diff --git a/include/igl/boolean/MeshBooleanType.h b/include/igl/boolean/MeshBooleanType.h index e12ce6542..035bbfa47 100644 --- a/include/igl/boolean/MeshBooleanType.h +++ b/include/igl/boolean/MeshBooleanType.h @@ -1,14 +1,17 @@ #ifndef MESH_BOOLEAN_TYPE_H #define MESH_BOOLEAN_TYPE_H -enum MeshBooleanType +namespace igl { - MESH_BOOLEAN_TYPE_UNION = 0, - MESH_BOOLEAN_TYPE_INTERSECT = 1, - MESH_BOOLEAN_TYPE_MINUS = 2, - MESH_BOOLEAN_TYPE_XOR = 3, - MESH_BOOLEAN_TYPE_RESOLVE = 4, - NUM_MESH_BOOLEAN_TYPES = 5 + enum MeshBooleanType + { + MESH_BOOLEAN_TYPE_UNION = 0, + MESH_BOOLEAN_TYPE_INTERSECT = 1, + MESH_BOOLEAN_TYPE_MINUS = 2, + MESH_BOOLEAN_TYPE_XOR = 3, + MESH_BOOLEAN_TYPE_RESOLVE = 4, + NUM_MESH_BOOLEAN_TYPES = 5 + }; }; #endif diff --git a/include/igl/boolean/from_cork_mesh.cpp b/include/igl/boolean/from_cork_mesh.cpp index 674173e70..7c15262cf 100644 --- a/include/igl/boolean/from_cork_mesh.cpp +++ b/include/igl/boolean/from_cork_mesh.cpp @@ -31,6 +31,7 @@ IGL_INLINE void igl::from_cork_mesh( #ifdef IGL_STATIC_LIBRARY // Explicit template specialization template void igl::from_cork_mesh, Eigen::Matrix >(CorkTriMesh const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); +template void igl::from_cork_mesh, Eigen::Matrix >(CorkTriMesh const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); #endif #endif diff --git a/include/igl/boolean/mesh_boolean.cpp b/include/igl/boolean/mesh_boolean.cpp index 9cb69ad5f..6ba4308b4 100644 --- a/include/igl/boolean/mesh_boolean.cpp +++ b/include/igl/boolean/mesh_boolean.cpp @@ -11,7 +11,8 @@ template < typename DerivedVB, typename DerivedFB, typename DerivedVC, - typename DerivedFC> + typename DerivedFC, + typename DerivedJ> IGL_INLINE void igl::mesh_boolean( const Eigen::PlainObjectBase & VA, const Eigen::PlainObjectBase & FA, @@ -19,15 +20,17 @@ IGL_INLINE void igl::mesh_boolean( const Eigen::PlainObjectBase & FB, const MeshBooleanType & type, Eigen::PlainObjectBase & VC, - Eigen::PlainObjectBase & FC) + Eigen::PlainObjectBase & FC, + Eigen::PlainObjectBase & J) { 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); + return mesh_boolean(VA,FA,VB,FB,type,empty_fun,VC,FC,J); } template < @@ -37,6 +40,34 @@ template < 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, @@ -47,10 +78,12 @@ IGL_INLINE void igl::mesh_boolean( const Eigen::Matrix&, const Eigen::Matrix&, Eigen::Matrix&, - Eigen::Matrix&)> + Eigen::Matrix&, + Eigen::Matrix&)> & resolve_fun, Eigen::PlainObjectBase & VC, - Eigen::PlainObjectBase & FC) + Eigen::PlainObjectBase & FC, + Eigen::PlainObjectBase & J) { using namespace Eigen; using namespace std; @@ -63,6 +96,7 @@ IGL_INLINE void igl::mesh_boolean( 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; @@ -89,14 +123,15 @@ IGL_INLINE void igl::mesh_boolean( const MatrixX3S & V, const MatrixX3I & F, MatrixX3S & CV, - MatrixX3I & CF) + MatrixX3I & CF, + VectorXJ & J) { MatrixX3S SV; MatrixX3I SF; MatrixX2I SIF; - VectorXI SJ,SIM,UIM; + VectorXI SIM,UIM; RemeshSelfIntersectionsParam params; - remesh_self_intersections(V,F,params,SV,SF,SIF,SJ,SIM); + 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); @@ -105,18 +140,20 @@ IGL_INLINE void igl::mesh_boolean( MatrixX3S CV; MatrixX3I CF; + VectorXJ CJ; if(resolve_fun) { - resolve_fun(V,F,CV,CF); + resolve_fun(V,F,CV,CF,CJ); }else { - libigl_resolve(V,F,CV,CF); + libigl_resolve(V,F,CV,CF,CJ); } if(type == MESH_BOOLEAN_TYPE_RESOLVE) { FC = CF; VC = CV; + J = CJ; return; } @@ -152,7 +189,7 @@ IGL_INLINE void igl::mesh_boolean( if((!odd(f) && !flip(f)) || (odd(f) && flip(f))) { vG.push_back(f); - Gflip.push_back(false); + Gflip.push_back(type == MESH_BOOLEAN_TYPE_MINUS); } break; default: @@ -162,14 +199,23 @@ IGL_INLINE void igl::mesh_boolean( } const Index gm = vG.size(); MatrixX3I G(gm,3); + VectorXi GJ(gm,1); for(Index g = 0;g, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, MeshBooleanType const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); +template void igl::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::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 diff --git a/include/igl/boolean/mesh_boolean.h b/include/igl/boolean/mesh_boolean.h index 096507bb3..464ab12b7 100644 --- a/include/igl/boolean/mesh_boolean.h +++ b/include/igl/boolean/mesh_boolean.h @@ -19,9 +19,27 @@ namespace igl // Outputs: // W #W by 3 list of vertex positions of boolean result mesh // H #H by 3 list of triangle indices into W + // J #H list of indices into [FA;FB] revealing "birth" facet // // See also: self_intersect // + template < + typename DerivedVA, + typename DerivedFA, + typename DerivedVB, + typename DerivedFB, + typename DerivedVC, + typename DerivedFC, + typename DerivedJ> + IGL_INLINE void 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); template < typename DerivedVA, typename DerivedFA, @@ -46,7 +64,8 @@ namespace igl typename DerivedVB, typename DerivedFB, typename DerivedVC, - typename DerivedFC> + typename DerivedFC, + typename DerivedJ> IGL_INLINE void mesh_boolean( const Eigen::PlainObjectBase & VA, const Eigen::PlainObjectBase & FA, @@ -55,12 +74,14 @@ namespace igl const MeshBooleanType & type, const std::function &, - const Eigen::Matrix &, + const Eigen::Matrix &, Eigen::Matrix &, - Eigen::Matrix &)> + Eigen::Matrix &, + Eigen::Matrix&)> & resolve_fun, Eigen::PlainObjectBase & VC, - Eigen::PlainObjectBase & FC); + Eigen::PlainObjectBase & FC, + Eigen::PlainObjectBase & J); } #ifndef IGL_STATIC_LIBRARY diff --git a/include/igl/boolean/mesh_boolean_cork.cpp b/include/igl/boolean/mesh_boolean_cork.cpp index b82a1d7a9..65f2f7844 100644 --- a/include/igl/boolean/mesh_boolean_cork.cpp +++ b/include/igl/boolean/mesh_boolean_cork.cpp @@ -88,6 +88,7 @@ IGL_INLINE void igl::mesh_boolean_cork( #ifdef IGL_STATIC_LIBRARY // Explicit template specialization template void igl::mesh_boolean_cork, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, MeshBooleanType const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); +template void igl::mesh_boolean_cork, 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 >&); #endif #endif diff --git a/include/igl/boolean/to_cork_mesh.cpp b/include/igl/boolean/to_cork_mesh.cpp index 7aba7f44c..c30997eb4 100644 --- a/include/igl/boolean/to_cork_mesh.cpp +++ b/include/igl/boolean/to_cork_mesh.cpp @@ -33,5 +33,6 @@ IGL_INLINE void igl::to_cork_mesh( #ifdef IGL_STATIC_LIBRARY // Explicit template specialization template void igl::to_cork_mesh, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, CorkTriMesh&); +template void igl::to_cork_mesh, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, CorkTriMesh&); #endif #endif diff --git a/include/igl/cgal/remesh_self_intersections.cpp b/include/igl/cgal/remesh_self_intersections.cpp index 80f6c5c37..57d9278f9 100644 --- a/include/igl/cgal/remesh_self_intersections.cpp +++ b/include/igl/cgal/remesh_self_intersections.cpp @@ -84,4 +84,5 @@ IGL_INLINE void igl::remesh_self_intersections( // Explicit template specialization template void igl::remesh_self_intersections, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, igl::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::remesh_self_intersections, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, igl::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); +template void igl::remesh_self_intersections, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, igl::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); #endif diff --git a/include/igl/matlab/mexStream.h b/include/igl/matlab/mexStream.h index 242184f36..079fb5f61 100644 --- a/include/igl/matlab/mexStream.h +++ b/include/igl/matlab/mexStream.h @@ -32,6 +32,7 @@ namespace igl } // Implementation +#include inline std::streamsize igl::MexStream::xsputn( const char *s, std::streamsize n) diff --git a/include/igl/matlab/prepare_lhs.cpp b/include/igl/matlab/prepare_lhs.cpp index 2d46e423a..cfa455909 100644 --- a/include/igl/matlab/prepare_lhs.cpp +++ b/include/igl/matlab/prepare_lhs.cpp @@ -37,4 +37,5 @@ IGL_INLINE void igl::prepare_lhs_index( template void igl::prepare_lhs_index >(Eigen::PlainObjectBase > const&, mxArray_tag**); template void igl::prepare_lhs_index >(Eigen::PlainObjectBase > const&, mxArray_tag**); template void igl::prepare_lhs_double >(Eigen::PlainObjectBase > const&, mxArray_tag**); +template void igl::prepare_lhs_index >(Eigen::PlainObjectBase > const&, mxArray_tag**); #endif diff --git a/include/igl/triangle_triangle_adjacency.cpp b/include/igl/triangle_triangle_adjacency.cpp index d4d6f4733..a0555ef35 100644 --- a/include/igl/triangle_triangle_adjacency.cpp +++ b/include/igl/triangle_triangle_adjacency.cpp @@ -137,7 +137,6 @@ template < using namespace std; assert(F.cols() == 3 && "Faces must be triangles"); // number of faces - const int m = F.rows(); typedef typename DerivedF::Index Index; typedef Matrix MatrixX2I; typedef Matrix VectorXI; @@ -166,7 +165,7 @@ template < using namespace Eigen; typedef typename DerivedE::Index Index; const size_t m = E.rows()/3; - assert(E.rows() == m*3 && "E should come from list of triangles."); + assert((size_t)E.rows() == m*3 && "E should come from list of triangles."); // E2E[i] --> {j,k,...} means face edge i corresponds to other faces edges j // and k TT.resize (m,vector >(3)); @@ -177,20 +176,17 @@ template < // No race conditions because TT*[f][c]'s are in bijection with e's // Minimum number of iterms per openmp thread - const size_t ne = E.rows(); + //const size_t num_e = E.rows(); # ifndef IGL_OMP_MIN_VALUE # define IGL_OMP_MIN_VALUE 1000 # endif -# pragma omp parallel for if (ne>IGL_OMP_MIN_VALUE) +# pragma omp parallel for if (m>IGL_OMP_MIN_VALUE) // Slightly better memory access than loop over E for(Index f = 0;f<(Index)m;f++) { for(Index c = 0;c<3;c++) { const Index e = f + m*c; - const Index i = E(e,0); - const Index j = E(e,1); - //const Index f = e%m; //const Index c = e/m; const vector & N = uE2E[EMAP(e)]; for(const auto & ne : N) diff --git a/include/igl/unique_edge_map.cpp b/include/igl/unique_edge_map.cpp index 8ddbd5766..bf1a70901 100644 --- a/include/igl/unique_edge_map.cpp +++ b/include/igl/unique_edge_map.cpp @@ -29,7 +29,7 @@ IGL_INLINE void igl::unique_edge_map( uE2E.resize(uE.rows()); // This does help a little for_each(uE2E.begin(),uE2E.end(),[](vector & v){v.reserve(2);}); - assert(EMAP.size() == ne); + assert((size_t)EMAP.size() == ne); for(uE2EType e = 0;e<(uE2EType)ne;e++) { uE2E[EMAP(e)].push_back(e); diff --git a/include/igl/viewer/Viewer.cpp b/include/igl/viewer/Viewer.cpp index 73810544b..4af70fdcd 100644 --- a/include/igl/viewer/Viewer.cpp +++ b/include/igl/viewer/Viewer.cpp @@ -911,7 +911,7 @@ namespace igl glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); #endif - window = glfwCreateWindow(1280, 800, "IGL Viewer", NULL, NULL); + window = glfwCreateWindow(1280, 800, "libigl viewer", NULL, NULL); if (!window) { glfwTerminate(); diff --git a/tutorial/609_Boolean/CMakeLists.txt b/tutorial/609_Boolean/CMakeLists.txt new file mode 100644 index 000000000..a200c45a4 --- /dev/null +++ b/tutorial/609_Boolean/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 2.6) +project(609_Boolean) + +find_package(CGAL REQUIRED) +include(${CGAL_USE_FILE}) + +# for some reason must come after cgal include +include("../CMakeLists.shared") + +set(SOURCES +${PROJECT_SOURCE_DIR}/main.cpp +) + +add_executable(${PROJECT_NAME}_bin ${SOURCES} ${SHARED_SOURCES}) +target_link_libraries(${PROJECT_NAME}_bin ${SHARED_LIBRARIES} ${CGAL_LIBRARIES}) diff --git a/tutorial/609_Boolean/main.cpp b/tutorial/609_Boolean/main.cpp new file mode 100755 index 000000000..170ba2eb6 --- /dev/null +++ b/tutorial/609_Boolean/main.cpp @@ -0,0 +1,94 @@ +#include +#define IGL_NO_CORK +#include +#include + +#include +#include + +Eigen::MatrixXd VA,VB,VC; +Eigen::VectorXi J; +Eigen::MatrixXi FA,FB,FC; +igl::MeshBooleanType boolean_type(igl::MESH_BOOLEAN_TYPE_UNION); + +const char * MESH_BOOLEAN_TYPE_NAMES[] = +{ + "Union", + "Intersect", + "Minus", + "XOR", + "Resolve", +}; + +void update(igl::Viewer &viewer) +{ + igl::mesh_boolean(VA,FA,VB,FB,boolean_type,VC,FC,J); + Eigen::MatrixXd C(FC.rows(),3); + for(size_t f = 0;f( + (boolean_type+1)% igl::NUM_MESH_BOOLEAN_TYPES); + break; + case ',': + boolean_type = + static_cast( + (boolean_type+igl::NUM_MESH_BOOLEAN_TYPES-1)% + igl::NUM_MESH_BOOLEAN_TYPES); + break; + case '[': + viewer.core.camera_dnear -= 0.1; + return true; + case ']': + viewer.core.camera_dnear += 0.1; + return true; + } + std::cout<<"A "<