#include "mesh_boolean.h" #include #include #include #include #include template < typename DerivedVA, typename DerivedFA, typename DerivedVB, typename DerivedFB, typename DerivedVC, typename DerivedFC, typename DerivedJ> IGL_INLINE void igl::mesh_boolean( const Eigen::PlainObjectBase & VA, const Eigen::PlainObjectBase & FA, const Eigen::PlainObjectBase & VB, const Eigen::PlainObjectBase & FB, const MeshBooleanType & type, Eigen::PlainObjectBase & VC, Eigen::PlainObjectBase & FC, Eigen::PlainObjectBase & J) { const std::function &, const Eigen::Matrix&, Eigen::Matrix &, Eigen::Matrix&, Eigen::Matrix&)> empty_fun; return mesh_boolean(VA,FA,VB,FB,type,empty_fun,VC,FC,J); } template < typename DerivedVA, typename DerivedFA, typename DerivedVB, typename DerivedFB, typename DerivedVC, typename DerivedFC> IGL_INLINE void igl::mesh_boolean( const Eigen::PlainObjectBase & VA, const Eigen::PlainObjectBase & FA, const Eigen::PlainObjectBase & VB, const Eigen::PlainObjectBase & FB, const MeshBooleanType & type, Eigen::PlainObjectBase & VC, Eigen::PlainObjectBase & FC) { Eigen::Matrix J; const std::function &, const Eigen::Matrix&, Eigen::Matrix &, Eigen::Matrix&, Eigen::Matrix&)> empty_fun; return mesh_boolean(VA,FA,VB,FB,type,empty_fun,VC,FC,J); } template < typename DerivedVA, typename DerivedFA, typename DerivedVB, typename DerivedFB, typename DerivedVC, typename DerivedFC, typename DerivedJ> IGL_INLINE void igl::mesh_boolean( const Eigen::PlainObjectBase & VA, const Eigen::PlainObjectBase & FA, const Eigen::PlainObjectBase & VB, const Eigen::PlainObjectBase & FB, const MeshBooleanType & type, const std::function&, const Eigen::Matrix&, Eigen::Matrix&, Eigen::Matrix&, Eigen::Matrix&)> & resolve_fun, Eigen::PlainObjectBase & VC, Eigen::PlainObjectBase & FC, Eigen::PlainObjectBase & J) { using namespace Eigen; using namespace std; using namespace igl; MeshBooleanType eff_type = type; // Concatenate A and B into a single mesh typedef typename DerivedVC::Scalar Scalar; typedef typename DerivedFC::Scalar Index; typedef Matrix MatrixX3S; typedef Matrix MatrixX3I; typedef Matrix MatrixX2I; typedef Matrix VectorXI; typedef Matrix VectorXJ; MatrixX3S V(VA.rows()+VB.rows(),3); MatrixX3I F(FA.rows()+FB.rows(),3); V.block(0,0,VA.rows(),VA.cols()) = VA; V.block(VA.rows(),0,VB.rows(),VB.cols()) = VB; switch(type) { // Minus is implemented by flipping B and computing union case MESH_BOOLEAN_TYPE_MINUS: F.block(0,0,FA.rows(),FA.cols()) = FA.rowwise().reverse(); F.block(FA.rows(),0,FB.rows(),FB.cols()) = FB.array()+VA.rows(); //F.block(0,0,FA.rows(),3) = FA; //F.block(FA.rows(),0,FB.rows(),3) = // FB.rowwise().reverse().array()+VA.rows(); eff_type = MESH_BOOLEAN_TYPE_INTERSECT; break; default: F.block(0,0,FA.rows(),FA.cols()) = FA; F.block(FA.rows(),0,FB.rows(),FB.cols()) = FB.array()+VA.rows(); break; } // Resolve intersections (assumes A and B are solid) const auto & libigl_resolve = []( const MatrixX3S & V, const MatrixX3I & F, MatrixX3S & CV, MatrixX3I & CF, VectorXJ & J) { MatrixX3S SV; MatrixX3I SF; MatrixX2I SIF; VectorXI SIM,UIM; RemeshSelfIntersectionsParam params; remesh_self_intersections(V,F,params,SV,SF,SIF,J,SIM); for_each(SF.data(),SF.data()+SF.size(),[&SIM](int & a){a=SIM(a);}); { remove_unreferenced(SV,SF,CV,CF,UIM); } }; MatrixX3S CV; MatrixX3I CF; VectorXJ CJ; if(resolve_fun) { resolve_fun(V,F,CV,CF,CJ); }else { libigl_resolve(V,F,CV,CF,CJ); } if(type == MESH_BOOLEAN_TYPE_RESOLVE) { FC = CF; VC = CV; J = CJ; return; } Matrix from_A(CF.rows()); // Peal layers keeping track of odd and even flips Matrix odd; Matrix flip; peal_outer_hull_layers(CV,CF,odd,flip); const Index m = CF.rows(); // Faces of output vG[i] = j means ith face of output should be jth face in F std::vector vG; // Whether faces of output should be flipped, Gflip[i] = true means ith face // of output should be F.row(vG[i]).reverse() rather than F.row(vG[i]) std::vector Gflip; for(Index f = 0;f, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::mesh_boolean, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); #endif