// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2019 Hanxiao Shen // // This Source Code Form is subject to the terms of the Mozilla Public License // v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #include "cut_mesh.h" #include "triangle_triangle_adjacency.h" #include "HalfEdgeIterator.h" #include "is_border_vertex.h" // wrapper for input/output style template IGL_INLINE void igl::cut_mesh( const Eigen::MatrixBase& V, const Eigen::MatrixBase& F, const Eigen::MatrixBase& C, Eigen::PlainObjectBase& Vn, Eigen::PlainObjectBase& Fn ){ Vn = V; Fn = F; typedef typename DerivedF::Scalar Index; Eigen::Matrix _I; cut_mesh(Vn,Fn,C,_I); } template IGL_INLINE void igl::cut_mesh( const Eigen::MatrixBase& V, const Eigen::MatrixBase& F, const Eigen::MatrixBase& C, Eigen::PlainObjectBase& Vn, Eigen::PlainObjectBase& Fn, Eigen::PlainObjectBase& I ){ Vn = V; Fn = F; cut_mesh(Vn,Fn,C,I); } template IGL_INLINE void igl::cut_mesh( Eigen::PlainObjectBase& V, Eigen::PlainObjectBase& F, const Eigen::MatrixBase& C, Eigen::PlainObjectBase& I ){ DerivedF FF, FFi; igl::triangle_triangle_adjacency(F,FF,FFi); igl::cut_mesh(V,F,FF,FFi,C,I); } template IGL_INLINE void igl::cut_mesh( Eigen::PlainObjectBase& V, Eigen::PlainObjectBase& F, Eigen::MatrixBase& FF, Eigen::MatrixBase& FFi, const Eigen::MatrixBase& C, Eigen::PlainObjectBase& I ){ typedef typename DerivedF::Scalar Index; // store current number of occurance of each vertex as the alg proceed Eigen::Matrix occurence(V.rows()); occurence.setConstant(1); // set eventual number of occurance of each vertex expected Eigen::Matrix eventual(V.rows()); eventual.setZero(); for(Index i=0;i 0) ? eventual(i)-1 : 0); V.conservativeResize(n_v+n_new,Eigen::NoChange); I = DerivedI::LinSpaced(V.rows(),0,V.rows()); // pointing to the current bottom of V Index pos = n_v; for(Index f=0;f= n_v) continue; // ignore new vertices if(C(f,k) == 1 && occurence(v0) != eventual(v0)){ igl::HalfEdgeIterator he(F,FF,FFi,f,k); // rotate clock-wise around v0 until hit another cut std::vector fan; Index fi = he.Fi(); Index ei = he.Ei(); do{ fan.push_back(fi); he.flipE(); he.flipF(); fi = he.Fi(); ei = he.Ei(); }while(C(fi,ei) == 0 && !he.isBorder()); // make a copy V.row(pos) << V.row(v0); I(pos) = v0; // add one occurance to v0 occurence(v0) += 1; // replace old v0 for(Index f0: fan) for(Index j=0;j<3;j++) if(F(f0,j) == v0) F(f0,j) = pos; // mark cuts as boundary FF(f,k) = -1; FF(fi,ei) = -1; pos++; } } } } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation template void igl::cut_mesh, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::cut_mesh, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::cut_mesh, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::cut_mesh, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&); #endif