// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2015 Alec Jacobson // // 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 "mesh_boolean.h" #include #include #include #include #include #include #include #include #include #include #include //#define IGL_MESH_BOOLEAN_DEBUG template < typename DerivedVA, typename DerivedFA, typename DerivedVB, typename DerivedFB, typename DerivedVC, typename DerivedFC, typename DerivedJ, typename DerivedI> IGL_INLINE void igl::boolean::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&, Eigen::Matrix&)> & resolve_fun, Eigen::PlainObjectBase & VC, Eigen::PlainObjectBase & FC, Eigen::PlainObjectBase & J, Eigen::PlainObjectBase & I) { using namespace Eigen; using namespace std; using namespace igl; using namespace igl::cgal; MeshBooleanType eff_type = type; // Concatenate A and B into a single mesh typedef CGAL::Epeck Kernel; typedef Kernel::FT ExactScalar; typedef typename DerivedVC::Scalar Scalar; typedef typename DerivedFC::Scalar Index; typedef Matrix MatrixX3S; typedef Matrix MatrixX3ES; typedef Matrix MatrixX3I; typedef Matrix MatrixX2I; typedef Matrix VectorXI; typedef Matrix VectorXJ; #ifdef IGL_MESH_BOOLEAN_DEBUG cout<<"mesh boolean..."< UIM; remove_unreferenced(SV,SF,CV,CF,UIM); for_each(I.data(),I.data()+I.size(), [&UIM](typename VectorXI::Scalar & a){a=UIM(a);}); } #ifdef IGL_MESH_BOOLEAN_DEBUG cout<<"#F: "< CI; if(resolve_fun) { resolve_fun(V,F,CV,CF,CJ,CI); }else { libigl_resolve(V,F,EV,CF,CJ,CI); CV.resize(EV.rows(), EV.cols()); // Just use f'ing for loops. What if EV and CV don't use the same ordering? for(int i=0;i from_A(CF.rows()); // peel layers keeping track of odd and even flips VectorXi iter; Matrix flip; peel_outer_hull_layers(EV,CF,iter,flip); //Array even = igl::mod(I,2).array()==0; const auto even = [&](const Index & f)->bool { return (iter(f)%2)==0; }; #ifdef IGL_MESH_BOOLEAN_DEBUG cout<<"categorize..."< 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 > uG2G(uG.rows()); // signed counts VectorXi counts = VectorXi::Zero(uG.rows()); VectorXi ucounts = VectorXi::Zero(uG.rows()); // loop over all faces for(Index g = 0;g 0); vG.push_back(uG2G[ug][0]); #ifdef IGL_MESH_BOOLEAN_DEBUG if(abs(ucounts(ug)) != 1) { cout<<"count,ucount of "< IGL_INLINE void igl::boolean::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, Eigen::PlainObjectBase & I) { const std::function &, const Eigen::Matrix&, Eigen::Matrix &, Eigen::Matrix&, Eigen::Matrix&, Eigen::Matrix&) > empty_fun; return mesh_boolean(VA,FA,VB,FB,type,empty_fun,VC,FC,J,I); } template < typename DerivedVA, typename DerivedFA, typename DerivedVB, typename DerivedFB, typename DerivedVC, typename DerivedFC> IGL_INLINE void igl::boolean::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; typedef Eigen::Matrix VectorXI; VectorXI I; const std::function &, const Eigen::Matrix&, Eigen::Matrix &, Eigen::Matrix&, Eigen::Matrix&, Eigen::Matrix&)> empty_fun; return mesh_boolean(VA,FA,VB,FB,type,empty_fun,VC,FC,J,I); } #ifdef IGL_STATIC_LIBRARY // Explicit template specialization template void igl::boolean::mesh_boolean, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, igl::boolean::MeshBooleanType const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::boolean::mesh_boolean, Eigen::Matrix, 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::boolean::MeshBooleanType const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::boolean::mesh_boolean, -1, 3, 0, -1, 3>, Eigen::Matrix, Eigen::Matrix, -1, 3, 0, -1, 3>, Eigen::Matrix, Eigen::Matrix, -1, 3, 0, -1, 3>, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase > const&, igl::boolean::MeshBooleanType const&, Eigen::PlainObjectBase, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); // This is a hack to discuss. I'm not sure why this _doesn't_ create // duplicate symbols. #include template void igl::remove_unreferenced, -1, 3, 0, -1, 3>, Eigen::Matrix, Eigen::Matrix, -1, 3, 0, -1, 3>, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); #include template unsigned long igl::cgal::peel_outer_hull_layers, -1, 3, 0, -1, 3>, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); #include template void igl::cgal::outer_hull, -1, 3, 0, -1, 3>, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); #include #include template void igl::barycenter, -1, 3, 0, -1, 3>, Eigen::Matrix, Eigen::Matrix, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase, -1, 3, 0, -1, 3> >&); #include template Eigen::PlainObjectBase > igl::mod >(Eigen::PlainObjectBase > const&, int); #include template void igl::outer_edge, -1, 3, 0, -1, 3>, Eigen::Matrix, Eigen::Matrix, long, Eigen::Matrix >(Eigen::PlainObjectBase, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, long&, long&, Eigen::PlainObjectBase >&); #include template void igl::colon(int, long, Eigen::Matrix&); #endif