瀏覽代碼

Merge branch 'master' of https://github.com/libigl/libigl

Former-commit-id: 18b41b26435ac59e87fd29bc0d0d409efca972d7
Olga Diamanti 9 年之前
父節點
當前提交
9cef5ae6e4

+ 4 - 0
include/igl/copyleft/cgal/BinaryWindingNumberOperations.h

@@ -14,6 +14,10 @@
 #include "../../MeshBooleanType.h"
 #include "../../MeshBooleanType.h"
 #include <Eigen/Core>
 #include <Eigen/Core>
 
 
+// TODO: This is not written according to libigl style. These should be
+// function handles.
+//
+// Why is this templated on DerivedW
 namespace igl
 namespace igl
 {
 {
   namespace copyleft
   namespace copyleft

+ 8 - 0
include/igl/copyleft/cgal/extract_cells.cpp

@@ -83,6 +83,13 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
   const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
   const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
   Eigen::PlainObjectBase<DerivedC>& cells) 
   Eigen::PlainObjectBase<DerivedC>& cells) 
 {
 {
+  // Trivial base case
+  if(P.size() == 0)
+  {
+    assert(F.size() == 0);
+    cells.resize(0,2);
+    return 0;
+  }
 
 
   typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
   typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
   typedef Kernel::Point_3 Point_3;
   typedef Kernel::Point_3 Point_3;
@@ -113,6 +120,7 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
 #endif
 #endif
   const size_t num_faces = F.rows();
   const size_t num_faces = F.rows();
   typedef typename DerivedF::Scalar Index;
   typedef typename DerivedF::Scalar Index;
+  assert(P.size() > 0);
   const size_t num_patches = P.maxCoeff()+1;
   const size_t num_patches = P.maxCoeff()+1;
 
 
   // Extract all cells...
   // Extract all cells...

+ 1 - 0
include/igl/copyleft/cgal/extract_cells.h

@@ -29,6 +29,7 @@ namespace igl {
       //          cell index on the positive side of face i, and cells(i,1)
       //          cell index on the positive side of face i, and cells(i,1)
       //          represents cell index of the negqtive side.
       //          represents cell index of the negqtive side.
       //          By convension cell with index 0 is the infinite cell.
       //          By convension cell with index 0 is the infinite cell.
+      // Returns the number of cells
       template<
       template<
         typename DerivedV,
         typename DerivedV,
         typename DerivedF,
         typename DerivedF,

+ 214 - 147
include/igl/copyleft/cgal/mesh_boolean.cpp

@@ -10,17 +10,19 @@
 #include "mesh_boolean.h"
 #include "mesh_boolean.h"
 #include "BinaryWindingNumberOperations.h"
 #include "BinaryWindingNumberOperations.h"
 #include "assign_scalar.h"
 #include "assign_scalar.h"
+#include "string_to_mesh_boolean_type.h"
 #include "propagate_winding_numbers.h"
 #include "propagate_winding_numbers.h"
 #include "remesh_self_intersections.h"
 #include "remesh_self_intersections.h"
 #include "relabel_small_immersed_cells.h"
 #include "relabel_small_immersed_cells.h"
 #include "extract_cells.h"
 #include "extract_cells.h"
+#include "../../cumsum.h"
 #include "../../extract_manifold_patches.h"
 #include "../../extract_manifold_patches.h"
+#include "../../get_seconds.h"
 #include "../../remove_unreferenced.h"
 #include "../../remove_unreferenced.h"
-#include "../../unique_simplices.h"
-#include "../../unique_edge_map.h"
-#include "../../slice.h"
 #include "../../resolve_duplicated_faces.h"
 #include "../../resolve_duplicated_faces.h"
-#include "../../get_seconds.h"
+#include "../../slice.h"
+#include "../../unique_edge_map.h"
+#include "../../unique_simplices.h"
 
 
 #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
 #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
 #include <algorithm>
 #include <algorithm>
@@ -34,9 +36,74 @@ template <
   typename DerivedFA,
   typename DerivedFA,
   typename DerivedVB,
   typename DerivedVB,
   typename DerivedFB,
   typename DerivedFB,
-  typename WindingNumberOp,
-  typename KeepFunc,
-  typename ResolveFunc,
+  typename DerivedVC,
+  typename DerivedFC,
+  typename DerivedJ>
+IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
+    const Eigen::PlainObjectBase<DerivedVA > & VA,
+    const Eigen::PlainObjectBase<DerivedFA > & FA,
+    const Eigen::PlainObjectBase<DerivedVB > & VB,
+    const Eigen::PlainObjectBase<DerivedFB > & FB,
+    const MeshBooleanType & type,
+    Eigen::PlainObjectBase<DerivedVC > & VC,
+    Eigen::PlainObjectBase<DerivedFC > & FC,
+    Eigen::PlainObjectBase<DerivedJ > & J)
+{
+  switch (type) 
+  {
+    case MESH_BOOLEAN_TYPE_UNION:
+      return igl::copyleft::cgal::mesh_boolean(
+          VA, FA, VB, FB, igl::copyleft::cgal::BinaryUnion(),
+          igl::copyleft::cgal::KeepInside(), VC, FC, J);
+    case MESH_BOOLEAN_TYPE_INTERSECT:
+      return igl::copyleft::cgal::mesh_boolean(
+          VA, FA, VB, FB, igl::copyleft::cgal::BinaryIntersect(),
+          igl::copyleft::cgal::KeepInside(), VC, FC, J);
+    case MESH_BOOLEAN_TYPE_MINUS:
+      return igl::copyleft::cgal::mesh_boolean(
+          VA, FA, VB, FB, igl::copyleft::cgal::BinaryMinus(),
+          igl::copyleft::cgal::KeepInside(), VC, FC, J);
+    case MESH_BOOLEAN_TYPE_XOR:
+      return igl::copyleft::cgal::mesh_boolean(
+          VA, FA, VB, FB, igl::copyleft::cgal::BinaryXor(),
+          igl::copyleft::cgal::KeepInside(), VC, FC, J);
+    case MESH_BOOLEAN_TYPE_RESOLVE:
+      //op = binary_resolve();
+      return igl::copyleft::cgal::mesh_boolean(
+          VA, FA, VB, FB, igl::copyleft::cgal::BinaryResolve(),
+          igl::copyleft::cgal::KeepAll(), VC, FC, J);
+    default:
+      assert(false && "Unsupported boolean type.");
+      return false;
+  }
+}
+template <
+  typename DerivedVA,
+  typename DerivedFA,
+  typename DerivedVB,
+  typename DerivedFB,
+  typename DerivedVC,
+  typename DerivedFC,
+  typename DerivedJ>
+IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
+  const Eigen::PlainObjectBase<DerivedVA > & VA,
+  const Eigen::PlainObjectBase<DerivedFA > & FA,
+  const Eigen::PlainObjectBase<DerivedVB > & VB,
+  const Eigen::PlainObjectBase<DerivedFB > & FB,
+  const std::string & type_str,
+  Eigen::PlainObjectBase<DerivedVC > & VC,
+  Eigen::PlainObjectBase<DerivedFC > & FC,
+  Eigen::PlainObjectBase<DerivedJ > & J)
+{
+  return mesh_boolean(
+    VA,FA,VB,FB,string_to_mesh_boolean_type(type_str),VC,FC,J);
+}
+
+template <
+  typename DerivedVA,
+  typename DerivedFA,
+  typename DerivedVB,
+  typename DerivedFB,
   typename DerivedVC,
   typename DerivedVC,
   typename DerivedFC,
   typename DerivedFC,
   typename DerivedJ>
   typename DerivedJ>
@@ -45,14 +112,90 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
     const Eigen::PlainObjectBase<DerivedFA> & FA,
     const Eigen::PlainObjectBase<DerivedFA> & FA,
     const Eigen::PlainObjectBase<DerivedVB> & VB,
     const Eigen::PlainObjectBase<DerivedVB> & VB,
     const Eigen::PlainObjectBase<DerivedFB> & FB,
     const Eigen::PlainObjectBase<DerivedFB> & FB,
-    const WindingNumberOp& wind_num_op,
-    const KeepFunc& keep,
-    const ResolveFunc& resolve_fun,
+    const std::function<int(const Eigen::Matrix<int,1,Eigen::Dynamic>) >& wind_num_op,
+    const std::function<int(const int, const int)> & keep,
     Eigen::PlainObjectBase<DerivedVC > & VC,
     Eigen::PlainObjectBase<DerivedVC > & VC,
     Eigen::PlainObjectBase<DerivedFC > & FC,
     Eigen::PlainObjectBase<DerivedFC > & FC,
     Eigen::PlainObjectBase<DerivedJ > & J) 
     Eigen::PlainObjectBase<DerivedJ > & J) 
 {
 {
+  // Generate combined mesh (VA,FA,VB,FB) -> (V,F)
+  Eigen::Matrix<size_t,2,1> sizes(FA.rows(),FB.rows());
+  DerivedVA VV(VA.rows() + VB.rows(), 3);
+  DerivedFC FF(FA.rows() + FB.rows(), 3);
+  // Can't use comma initializer
+  for(int a = 0;a<VA.rows();a++)
+  {
+    for(int d = 0;d<3;d++) VV(a,d) = VA(a,d);
+  }
+  for(int b = 0;b<VB.rows();b++)
+  {
+    for(int d = 0;d<3;d++) VV(VA.rows()+b,d) = VB(b,d);
+  }
+  FF << FA, FB.array() + VA.rows();
+  return mesh_boolean(VV,FF,sizes,wind_num_op,keep,VC,FC,J);
+}
+
+template <
+  typename DerivedV,
+  typename DerivedF,
+  typename DerivedVC,
+  typename DerivedFC,
+  typename DerivedJ>
+IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
+    const std::vector<DerivedV > & Vlist,
+    const std::vector<DerivedF > & Flist,
+    const std::function<int(const Eigen::Matrix<int,1,Eigen::Dynamic>) >& wind_num_op,
+    const std::function<int(const int, const int)> & keep,
+    Eigen::PlainObjectBase<DerivedVC > & VC,
+    Eigen::PlainObjectBase<DerivedFC > & FC,
+    Eigen::PlainObjectBase<DerivedJ > & J)
+{
+  assert(Flist.size() == Vlist.size() && "#Vlist and #Flist should match");
+  const size_t num_inputs = Vlist.size();
+  // Gather sizes
+  Eigen::Matrix<size_t,Eigen::Dynamic,1> sizes(num_inputs);
+  int numf = 0;
+  int numv = 0;
+  for(int i = 0;i<num_inputs;i++)
+  {
+    sizes(i) = Flist[i].rows();
+    numf += Flist[i].rows();
+    numv += Vlist[i].rows();
+  }
+  // Combined mesh
+  DerivedV VV(numv,3);
+  DerivedF FF(numf,3);
+  {
+    int fk = 0;
+    int vk = 0;
+    for(int i = 0;i<num_inputs;i++)
+    {
+      FF.block(fk,0,Flist[i].rows(),3) = Flist[i].array() + vk;
+      fk += Flist[i].rows();
+      VV.block(vk,0,Vlist[i].rows(),3) = Vlist[i];
+      vk += Vlist[i].rows();
+    }
+  }
+  return mesh_boolean(VV,FF,sizes,wind_num_op,keep,VC,FC,J);
+}
 
 
+template <
+  typename DerivedVV,
+  typename DerivedFF,
+  typename Derivedsizes,
+  typename DerivedVC,
+  typename DerivedFC,
+  typename DerivedJ>
+IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
+    const Eigen::PlainObjectBase<DerivedVV > & VV,
+    const Eigen::PlainObjectBase<DerivedFF > & FF,
+    const Eigen::PlainObjectBase<Derivedsizes> & sizes,
+    const std::function<int(const Eigen::Matrix<int,1,Eigen::Dynamic>) >& wind_num_op,
+    const std::function<int(const int, const int)> & keep,
+    Eigen::PlainObjectBase<DerivedVC > & VC,
+    Eigen::PlainObjectBase<DerivedFC > & FC,
+    Eigen::PlainObjectBase<DerivedJ > & J)
+{
 #ifdef MESH_BOOLEAN_TIMING
 #ifdef MESH_BOOLEAN_TIMING
   const auto & tictoc = []() -> double
   const auto & tictoc = []() -> double
   {
   {
@@ -67,16 +210,11 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
   };
   };
   tictoc();
   tictoc();
 #endif
 #endif
-
   typedef typename DerivedVC::Scalar Scalar;
   typedef typename DerivedVC::Scalar Scalar;
-  //typedef typename DerivedFC::Scalar Index;
   typedef CGAL::Epeck Kernel;
   typedef CGAL::Epeck Kernel;
   typedef Kernel::FT ExactScalar;
   typedef Kernel::FT ExactScalar;
   typedef Eigen::Matrix<Scalar,Eigen::Dynamic,3> MatrixX3S;
   typedef Eigen::Matrix<Scalar,Eigen::Dynamic,3> MatrixX3S;
-  //typedef Eigen::Matrix<Index,Eigen::Dynamic,Eigen::Dynamic> MatrixXI;
   typedef Eigen::Matrix<typename DerivedJ::Scalar,Eigen::Dynamic,1> VectorXJ;
   typedef Eigen::Matrix<typename DerivedJ::Scalar,Eigen::Dynamic,1> VectorXJ;
-
-  // Generate combined mesh.
   typedef Eigen::Matrix<
   typedef Eigen::Matrix<
     ExactScalar,
     ExactScalar,
     Eigen::Dynamic,
     Eigen::Dynamic,
@@ -86,30 +224,40 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
   DerivedFC F;
   DerivedFC F;
   VectorXJ  CJ;
   VectorXJ  CJ;
   {
   {
-      DerivedVA VV(VA.rows() + VB.rows(), 3);
-      DerivedFC FF(FA.rows() + FB.rows(), 3);
-      VV << VA, VB;
-      FF << FA, FB.array() + VA.rows();
-      resolve_fun(VV, FF, V, F, CJ);
-  }
+    Eigen::VectorXi I;
+    igl::copyleft::cgal::RemeshSelfIntersectionsParam params;
+    params.stitch_all = true;
+    MatrixXES Vr;
+    DerivedFC Fr;
+    Eigen::MatrixXi IF;
+    igl::copyleft::cgal::remesh_self_intersections(
+        VV, FF, params, Vr, Fr, IF, CJ, I);
+    assert(I.size() == Vr.rows());
+    // Merge coinciding vertices into non-manifold vertices.
+    std::for_each(Fr.data(), Fr.data()+Fr.size(),
+          [&I](typename DerivedFC::Scalar& a) { a=I[a]; });
+      // Remove unreferenced vertices.
+      Eigen::VectorXi UIM;
+      igl::remove_unreferenced(Vr, Fr, V, F, UIM);
+   }
 #ifdef MESH_BOOLEAN_TIMING
 #ifdef MESH_BOOLEAN_TIMING
   log_time("resolve_self_intersection");
   log_time("resolve_self_intersection");
 #endif
 #endif
 
 
-  // Compute edges.
+  // Compute edges of (F) --> (E,uE,EMAP,uE2E)
   Eigen::MatrixXi E, uE;
   Eigen::MatrixXi E, uE;
   Eigen::VectorXi EMAP;
   Eigen::VectorXi EMAP;
   std::vector<std::vector<size_t> > uE2E;
   std::vector<std::vector<size_t> > uE2E;
   igl::unique_edge_map(F, E, uE, EMAP, uE2E);
   igl::unique_edge_map(F, E, uE, EMAP, uE2E);
 
 
-  // Compute patches
+  // Compute patches (F,EMAP,uE2E) --> (P)
   Eigen::VectorXi P;
   Eigen::VectorXi P;
   const size_t num_patches = igl::extract_manifold_patches(F, EMAP, uE2E, P);
   const size_t num_patches = igl::extract_manifold_patches(F, EMAP, uE2E, P);
 #ifdef MESH_BOOLEAN_TIMING
 #ifdef MESH_BOOLEAN_TIMING
   log_time("patch_extraction");
   log_time("patch_extraction");
 #endif
 #endif
 
 
-  // Compute cells.
+  // Compute cells (V,F,P,E,uE,EMAP) -> (per_patch_cells)
   Eigen::MatrixXi per_patch_cells;
   Eigen::MatrixXi per_patch_cells;
   const size_t num_cells =
   const size_t num_cells =
     igl::copyleft::cgal::extract_cells(
     igl::copyleft::cgal::extract_cells(
@@ -120,10 +268,31 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
 
 
   // Compute winding numbers on each side of each facet.
   // Compute winding numbers on each side of each facet.
   const size_t num_faces = F.rows();
   const size_t num_faces = F.rows();
+  // W(f,:) --> [w1out,w1in,w2out,w2in, ... wnout,wnint] winding numbers above
+  // and below each face w.r.t. each input mesh, so that W(f,2*i) is the
+  // winding number above face f w.r.t. input i, and W(f,2*i+1) is the winding
+  // number below face f w.r.t. input i.
   Eigen::MatrixXi W;
   Eigen::MatrixXi W;
+  // labels(f) = i means that face f comes from mesh i
   Eigen::VectorXi labels(num_faces);
   Eigen::VectorXi labels(num_faces);
-  std::transform(CJ.data(), CJ.data()+CJ.size(), labels.data(),
-      [&](int i) { return i<FA.rows() ? 0:1; });
+  // cumulative sizes
+  Derivedsizes cumsizes;
+  igl::cumsum(sizes,1,cumsizes);
+  const size_t num_inputs = sizes.size();
+  std::transform(
+    CJ.data(), 
+    CJ.data()+CJ.size(), 
+    labels.data(),
+    // Determine which input mesh birth face i comes from
+    [&num_inputs,&cumsizes](int i)->int
+    { 
+      for(int k = 0;k<num_inputs;k++)
+      {
+        if(i<cumsizes(k)) return k;
+      }
+      assert(false && "Birth parent index out of range");
+      return -1;
+    });
   bool valid = true;
   bool valid = true;
   if (num_faces > 0) 
   if (num_faces > 0) 
   {
   {
@@ -132,18 +301,17 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
           V, F, uE, uE2E, num_patches, P, num_cells, per_patch_cells, labels, W);
           V, F, uE, uE2E, num_patches, P, num_cells, per_patch_cells, labels, W);
   } else 
   } else 
   {
   {
-    W.resize(0, 4);
+    W.resize(0, 2*num_inputs);
   }
   }
   assert((size_t)W.rows() == num_faces);
   assert((size_t)W.rows() == num_faces);
-  if (W.cols() == 2) 
+  // If W doesn't have enough columns, pad with zeros
+  if (W.cols() <= 2*num_inputs) 
   {
   {
-    assert(FB.rows() == 0);
-    Eigen::MatrixXi W_tmp(num_faces, 4);
-    W_tmp << W, Eigen::MatrixXi::Zero(num_faces, 2);
-    W = W_tmp;
-  } else {
-    assert(W.cols() == 4);
+    const int old_ncols = W.cols();
+    W.conservativeResize(num_faces,2*num_inputs);
+    W.rightCols(2*num_inputs-old_ncols).setConstant(0);
   }
   }
+  assert((size_t)W.cols() == 2*num_inputs);
 #ifdef MESH_BOOLEAN_TIMING
 #ifdef MESH_BOOLEAN_TIMING
   log_time("propagate_input_winding_number");
   log_time("propagate_input_winding_number");
 #endif
 #endif
@@ -152,9 +320,13 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
   Eigen::MatrixXi Wr(num_faces, 2);
   Eigen::MatrixXi Wr(num_faces, 2);
   for (size_t i=0; i<num_faces; i++) 
   for (size_t i=0; i<num_faces; i++) 
   {
   {
-    Eigen::MatrixXi w_out(1,2), w_in(1,2);
-    w_out << W(i,0), W(i,2);
-    w_in  << W(i,1), W(i,3);
+    // Winding number vectors above and below
+    Eigen::RowVectorXi w_out(1,num_inputs), w_in(1,num_inputs);
+    for(size_t k =0;k<num_inputs;k++)
+    {
+      w_out(k) = W(i,2*k+0);
+      w_in(k) = W(i,2*k+1);
+    }
     Wr(i,0) = wind_num_op(w_out);
     Wr(i,0) = wind_num_op(w_out);
     Wr(i,1) = wind_num_op(w_in);
     Wr(i,1) = wind_num_op(w_in);
   }
   }
@@ -163,8 +335,8 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
 #endif
 #endif
 
 
 #ifdef SMALL_CELL_REMOVAL
 #ifdef SMALL_CELL_REMOVAL
-  igl::copyleft::cgal::relabel_small_immersed_cells(V, F,
-          num_patches, P, num_cells, per_patch_cells, 1e-3, Wr);
+  igl::copyleft::cgal::relabel_small_immersed_cells(
+    V, F, num_patches, P, num_cells, per_patch_cells, 1e-3, Wr);
 #endif
 #endif
 
 
   // Extract boundary separating inside from outside.
   // Extract boundary separating inside from outside.
@@ -256,114 +428,6 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
   return valid;
   return valid;
 }
 }
 
 
-template <
-  typename DerivedVA,
-  typename DerivedFA,
-  typename DerivedVB,
-  typename DerivedFB,
-  typename ResolveFunc,
-  typename DerivedVC,
-  typename DerivedFC,
-  typename DerivedJ>
-IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
-    const Eigen::PlainObjectBase<DerivedVA > & VA,
-    const Eigen::PlainObjectBase<DerivedFA > & FA,
-    const Eigen::PlainObjectBase<DerivedVB > & VB,
-    const Eigen::PlainObjectBase<DerivedFB > & FB,
-    const MeshBooleanType & type,
-    const ResolveFunc& resolve_func,
-    Eigen::PlainObjectBase<DerivedVC > & VC,
-    Eigen::PlainObjectBase<DerivedFC > & FC,
-    Eigen::PlainObjectBase<DerivedJ > & J)
-{
-  switch (type) 
-  {
-    case MESH_BOOLEAN_TYPE_UNION:
-      return igl::copyleft::cgal::mesh_boolean(
-          VA, FA, VB, FB, igl::copyleft::cgal::BinaryUnion(),
-          igl::copyleft::cgal::KeepInside(), resolve_func, VC, FC, J);
-    case MESH_BOOLEAN_TYPE_INTERSECT:
-      return igl::copyleft::cgal::mesh_boolean(
-          VA, FA, VB, FB, igl::copyleft::cgal::BinaryIntersect(),
-          igl::copyleft::cgal::KeepInside(), resolve_func, VC, FC, J);
-    case MESH_BOOLEAN_TYPE_MINUS:
-      return igl::copyleft::cgal::mesh_boolean(
-          VA, FA, VB, FB, igl::copyleft::cgal::BinaryMinus(),
-          igl::copyleft::cgal::KeepInside(), resolve_func, VC, FC, J);
-    case MESH_BOOLEAN_TYPE_XOR:
-      return igl::copyleft::cgal::mesh_boolean(
-          VA, FA, VB, FB, igl::copyleft::cgal::BinaryXor(),
-          igl::copyleft::cgal::KeepInside(), resolve_func, VC, FC, J);
-    case MESH_BOOLEAN_TYPE_RESOLVE:
-      //op = binary_resolve();
-      return igl::copyleft::cgal::mesh_boolean(
-          VA, FA, VB, FB, igl::copyleft::cgal::BinaryResolve(),
-          igl::copyleft::cgal::KeepAll(), resolve_func, VC, FC, J);
-    default:
-      assert(false && "Unsupported boolean type.");
-      return false;
-  }
-}
-
-template <
-  typename DerivedVA,
-  typename DerivedFA,
-  typename DerivedVB,
-  typename DerivedFB,
-  typename DerivedVC,
-  typename DerivedFC,
-  typename DerivedJ>
-IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
-  const Eigen::PlainObjectBase<DerivedVA > & VA,
-  const Eigen::PlainObjectBase<DerivedFA > & FA,
-  const Eigen::PlainObjectBase<DerivedVB > & VB,
-  const Eigen::PlainObjectBase<DerivedFB > & FB,
-  const MeshBooleanType & type,
-  Eigen::PlainObjectBase<DerivedVC > & VC,
-  Eigen::PlainObjectBase<DerivedFC > & FC,
-  Eigen::PlainObjectBase<DerivedJ > & J)
-{
-  typedef CGAL::Epeck Kernel;
-  typedef Kernel::FT ExactScalar;
-  typedef Eigen::Matrix<
-    ExactScalar,
-    Eigen::Dynamic,
-    Eigen::Dynamic,
-    DerivedVC::IsRowMajor> MatrixXES;
-
-  std::function<void(
-      const Eigen::PlainObjectBase<DerivedVA>&,
-      const Eigen::PlainObjectBase<DerivedFA>&,
-      Eigen::PlainObjectBase<MatrixXES>&,
-      Eigen::PlainObjectBase<DerivedFC>&,
-      Eigen::PlainObjectBase<DerivedJ>&)> resolve_func =
-    [](const Eigen::PlainObjectBase<DerivedVA>& V,
-        const Eigen::PlainObjectBase<DerivedFA>& F,
-        Eigen::PlainObjectBase<MatrixXES>& Vo,
-        Eigen::PlainObjectBase<DerivedFC>& Fo,
-        Eigen::PlainObjectBase<DerivedJ>& J) {
-      Eigen::VectorXi I;
-      igl::copyleft::cgal::RemeshSelfIntersectionsParam params;
-      params.stitch_all = true;
-      MatrixXES Vr;
-      DerivedFC Fr;
-      Eigen::MatrixXi IF;
-      igl::copyleft::cgal::remesh_self_intersections(
-          V, F, params, Vr, Fr, IF, J, I);
-      assert(I.size() == Vr.rows());
-
-      // Merge coinciding vertices into non-manifold vertices.
-      std::for_each(Fr.data(), Fr.data()+Fr.size(),
-          [&I](typename DerivedFC::Scalar& a) { a=I[a]; });
-
-      // Remove unreferenced vertices.
-      Eigen::VectorXi UIM;
-      igl::remove_unreferenced(Vr, Fr, Vo, Fo, UIM);
-    };
-
-  return mesh_boolean(VA,FA,VB,FB,type,resolve_func,VC,FC,J);
-}
-
 template <
 template <
   typename DerivedVA,
   typename DerivedVA,
   typename DerivedFA,
   typename DerivedFA,
@@ -389,6 +453,9 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(std::vector<Eigen::Matrix<double, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<double, -1, -1, 0, -1, -1> > > const&, std::vector<Eigen::Matrix<int, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<int, -1, -1, 0, -1, -1> > > const&, std::function<int (Eigen::Matrix<int, 1, -1, 1, 1, -1>)> const&, std::function<int (int, int)> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #undef IGL_STATIC_LIBRARY
 #undef IGL_STATIC_LIBRARY
 #include "../../remove_unreferenced.cpp"
 #include "../../remove_unreferenced.cpp"
 template void igl::remove_unreferenced<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::remove_unreferenced<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);

+ 98 - 56
include/igl/copyleft/cgal/mesh_boolean.h

@@ -14,6 +14,7 @@
 #include "../../MeshBooleanType.h"
 #include "../../MeshBooleanType.h"
 #include <Eigen/Core>
 #include <Eigen/Core>
 #include <functional>
 #include <functional>
+#include <vector>
 
 
 namespace igl
 namespace igl
 {
 {
@@ -29,18 +30,13 @@ namespace igl
       //    FA  #FA by 3 list of triangle indices into VA
       //    FA  #FA by 3 list of triangle indices into VA
       //    VB  #VB by 3 list of vertex positions of second mesh
       //    VB  #VB by 3 list of vertex positions of second mesh
       //    FB  #FB by 3 list of triangle indices into VB
       //    FB  #FB by 3 list of triangle indices into VB
-      //    wind_num_op  function handle for filtering winding numbers from
-      //      tuples of integer values to [0,1] outside/inside values
-      //    keep  function handle for determining if a patch should be "kept"
-      //      in the output based on the winding number on either side
-      //    resolve_fun  function handle for computing resolve of a
-      //      self-intersections of a mesh and outputting the new mesh.
+      //    type  type of boolean operation
       //  Outputs:
       //  Outputs:
       //    VC  #VC by 3 list of vertex positions of boolean result mesh
       //    VC  #VC by 3 list of vertex positions of boolean result mesh
       //    FC  #FC by 3 list of triangle indices into VC
       //    FC  #FC by 3 list of triangle indices into VC
       //    J  #FC list of indices into [FA;FB] revealing "birth" facet
       //    J  #FC list of indices into [FA;FB] revealing "birth" facet
-      //  Returns true iff inputs induce a piecewise constant winding number
-      //    field
+      //  Returns true if inputs induce a piecewise constant winding number
+      //  field and type is valid
       //
       //
       //  See also: mesh_boolean_cork, intersect_other,
       //  See also: mesh_boolean_cork, intersect_other,
       //  remesh_self_intersections
       //  remesh_self_intersections
@@ -49,38 +45,51 @@ namespace igl
         typename DerivedFA,
         typename DerivedFA,
         typename DerivedVB,
         typename DerivedVB,
         typename DerivedFB,
         typename DerivedFB,
-        typename WindingNumberOp,
-        typename KeepFunc,
-        typename ResolveFunc,
         typename DerivedVC,
         typename DerivedVC,
         typename DerivedFC,
         typename DerivedFC,
         typename DerivedJ>
         typename DerivedJ>
       IGL_INLINE bool mesh_boolean(
       IGL_INLINE bool mesh_boolean(
-          const Eigen::PlainObjectBase<DerivedVA> & VA,
-          const Eigen::PlainObjectBase<DerivedFA> & FA,
-          const Eigen::PlainObjectBase<DerivedVB> & VB,
-          const Eigen::PlainObjectBase<DerivedFB> & FB,
-          const WindingNumberOp& wind_num_op,
-          const KeepFunc& keep,
-          const ResolveFunc& resolve_fun,
-          Eigen::PlainObjectBase<DerivedVC > & VC,
-          Eigen::PlainObjectBase<DerivedFC > & FC,
-          Eigen::PlainObjectBase<DerivedJ > & J);
-
+        const Eigen::PlainObjectBase<DerivedVA > & VA,
+        const Eigen::PlainObjectBase<DerivedFA > & FA,
+        const Eigen::PlainObjectBase<DerivedVB > & VB,
+        const Eigen::PlainObjectBase<DerivedFB > & FB,
+        const MeshBooleanType & type,
+        Eigen::PlainObjectBase<DerivedVC > & VC,
+        Eigen::PlainObjectBase<DerivedFC > & FC,
+        Eigen::PlainObjectBase<DerivedJ > & J);
+      template <
+        typename DerivedVA,
+        typename DerivedFA,
+        typename DerivedVB,
+        typename DerivedFB,
+        typename DerivedVC,
+        typename DerivedFC,
+        typename DerivedJ>
+      IGL_INLINE bool mesh_boolean(
+        const Eigen::PlainObjectBase<DerivedVA > & VA,
+        const Eigen::PlainObjectBase<DerivedFA > & FA,
+        const Eigen::PlainObjectBase<DerivedVB > & VB,
+        const Eigen::PlainObjectBase<DerivedFB > & FB,
+        const std::string & type_str,
+        Eigen::PlainObjectBase<DerivedVC > & VC,
+        Eigen::PlainObjectBase<DerivedFC > & FC,
+        Eigen::PlainObjectBase<DerivedJ > & J);
+      //
       //  Inputs:
       //  Inputs:
       //    VA  #VA by 3 list of vertex positions of first mesh
       //    VA  #VA by 3 list of vertex positions of first mesh
       //    FA  #FA by 3 list of triangle indices into VA
       //    FA  #FA by 3 list of triangle indices into VA
       //    VB  #VB by 3 list of vertex positions of second mesh
       //    VB  #VB by 3 list of vertex positions of second mesh
       //    FB  #FB by 3 list of triangle indices into VB
       //    FB  #FB by 3 list of triangle indices into VB
-      //    type  type of boolean operation
-      //    resolve_fun  function handle for computing resolve of a
-      //      self-intersections of a mesh and outputting the new mesh.
+      //    wind_num_op  function handle for filtering winding numbers from
+      //      tuples of integer values to [0,1] outside/inside values
+      //    keep  function handle for determining if a patch should be "kept"
+      //      in the output based on the winding number on either side
       //  Outputs:
       //  Outputs:
       //    VC  #VC by 3 list of vertex positions of boolean result mesh
       //    VC  #VC by 3 list of vertex positions of boolean result mesh
       //    FC  #FC by 3 list of triangle indices into VC
       //    FC  #FC by 3 list of triangle indices into VC
       //    J  #FC list of indices into [FA;FB] revealing "birth" facet
       //    J  #FC list of indices into [FA;FB] revealing "birth" facet
-      //  Returns true if inputs induce a piecewise constant winding number
-      //    field and type is valid.
+      //  Returns true iff inputs induce a piecewise constant winding number
+      //    field
       //
       //
       //  See also: mesh_boolean_cork, intersect_other,
       //  See also: mesh_boolean_cork, intersect_other,
       //  remesh_self_intersections
       //  remesh_self_intersections
@@ -89,54 +98,87 @@ namespace igl
         typename DerivedFA,
         typename DerivedFA,
         typename DerivedVB,
         typename DerivedVB,
         typename DerivedFB,
         typename DerivedFB,
-        typename ResolveFunc,
         typename DerivedVC,
         typename DerivedVC,
         typename DerivedFC,
         typename DerivedFC,
         typename DerivedJ>
         typename DerivedJ>
       IGL_INLINE bool mesh_boolean(
       IGL_INLINE bool mesh_boolean(
-          const Eigen::PlainObjectBase<DerivedVA > & VA,
-          const Eigen::PlainObjectBase<DerivedFA > & FA,
-          const Eigen::PlainObjectBase<DerivedVB > & VB,
-          const Eigen::PlainObjectBase<DerivedFB > & FB,
-          const MeshBooleanType & type,
-        const ResolveFunc& resolve_func,
+          const Eigen::PlainObjectBase<DerivedVA> & VA,
+          const Eigen::PlainObjectBase<DerivedFA> & FA,
+          const Eigen::PlainObjectBase<DerivedVB> & VB,
+          const Eigen::PlainObjectBase<DerivedFB> & FB,
+          const std::function<int(const Eigen::Matrix<int,1,Eigen::Dynamic>) >& wind_num_op,
+          const std::function<int(const int, const int)> & keep,
           Eigen::PlainObjectBase<DerivedVC > & VC,
           Eigen::PlainObjectBase<DerivedVC > & VC,
           Eigen::PlainObjectBase<DerivedFC > & FC,
           Eigen::PlainObjectBase<DerivedFC > & FC,
           Eigen::PlainObjectBase<DerivedJ > & J);
           Eigen::PlainObjectBase<DerivedJ > & J);
-
+      //  MESH_BOOLEAN Variadic boolean operations
+      //
       //  Inputs:
       //  Inputs:
-      //    VA  #VA by 3 list of vertex positions of first mesh
-      //    FA  #FA by 3 list of triangle indices into VA
-      //    VB  #VB by 3 list of vertex positions of second mesh
-      //    FB  #FB by 3 list of triangle indices into VB
-      //    type  type of boolean operation
+      //    Vlist  k-long list of lists of mesh vertex positions
+      //    Flist  k-long list of lists of mesh face indices, so that Flist[i] indexes
+      //      vertices in Vlist[i]
+      //    wind_num_op  function handle for filtering winding numbers from
+      //      n-tuples of integer values to [0,1] outside/inside values
+      //    keep  function handle for determining if a patch should be "kept"
+      //      in the output based on the winding number on either side
       //  Outputs:
       //  Outputs:
       //    VC  #VC by 3 list of vertex positions of boolean result mesh
       //    VC  #VC by 3 list of vertex positions of boolean result mesh
       //    FC  #FC by 3 list of triangle indices into VC
       //    FC  #FC by 3 list of triangle indices into VC
-      //    J  #FC list of indices into [FA;FB] revealing "birth" facet
-      //  Returns true if inputs induce a piecewise constant winding number
-      //  field and type is valid
+      //    J  #FC list of indices into [Flist[0];Flist[1];...;Flist[k]]
+      //      revealing "birth" facet
+      //  Returns true iff inputs induce a piecewise constant winding number
+      //    field
       //
       //
       //  See also: mesh_boolean_cork, intersect_other,
       //  See also: mesh_boolean_cork, intersect_other,
       //  remesh_self_intersections
       //  remesh_self_intersections
       template <
       template <
-        typename DerivedVA,
-        typename DerivedFA,
-        typename DerivedVB,
-        typename DerivedFB,
+        typename DerivedV,
+        typename DerivedF,
         typename DerivedVC,
         typename DerivedVC,
         typename DerivedFC,
         typename DerivedFC,
         typename DerivedJ>
         typename DerivedJ>
       IGL_INLINE bool mesh_boolean(
       IGL_INLINE bool mesh_boolean(
-        const Eigen::PlainObjectBase<DerivedVA > & VA,
-        const Eigen::PlainObjectBase<DerivedFA > & FA,
-        const Eigen::PlainObjectBase<DerivedVB > & VB,
-        const Eigen::PlainObjectBase<DerivedFB > & FB,
-        const MeshBooleanType & type,
-        Eigen::PlainObjectBase<DerivedVC > & VC,
-        Eigen::PlainObjectBase<DerivedFC > & FC,
-        Eigen::PlainObjectBase<DerivedJ > & J);
-
+          const std::vector<DerivedV > & Vlist,
+          const std::vector<DerivedF > & Flist,
+          const std::function<int(const Eigen::Matrix<int,1,Eigen::Dynamic>) >& wind_num_op,
+          const std::function<int(const int, const int)> & keep,
+          Eigen::PlainObjectBase<DerivedVC > & VC,
+          Eigen::PlainObjectBase<DerivedFC > & FC,
+          Eigen::PlainObjectBase<DerivedJ > & J);
+      // Given a merged mesh (V,F) and list of sizes of inputs
+      //
+      // Inputs:
+      //   V  #V by 3 list of merged mesh vertex positions
+      //   F  #F by 3 list of merged mesh face indices so that first sizes(0)
+      //     faces come from the first input, and the next sizes(1) faces come
+      //     from the second input, and so on.
+      //   sizes  #inputs list of sizes so that sizes(i) is the #faces in the
+      //     ith input
+      //    wind_num_op  function handle for filtering winding numbers from
+      //      tuples of integer values to [0,1] outside/inside values
+      //    keep  function handle for determining if a patch should be "kept"
+      //      in the output based on the winding number on either side
+      //  Outputs:
+      //    VC  #VC by 3 list of vertex positions of boolean result mesh
+      //    FC  #FC by 3 list of triangle indices into VC
+      //    J  #FC list of birth parent indices
+      // 
+      template <
+        typename DerivedVV,
+        typename DerivedFF,
+        typename Derivedsizes,
+        typename DerivedVC,
+        typename DerivedFC,
+        typename DerivedJ>
+      IGL_INLINE bool mesh_boolean(
+          const Eigen::PlainObjectBase<DerivedVV > & VV,
+          const Eigen::PlainObjectBase<DerivedFF > & FF,
+          const Eigen::PlainObjectBase<Derivedsizes> & sizes,
+          const std::function<int(const Eigen::Matrix<int,1,Eigen::Dynamic>) >& wind_num_op,
+          const std::function<int(const int, const int)> & keep,
+          Eigen::PlainObjectBase<DerivedVC > & VC,
+          Eigen::PlainObjectBase<DerivedFC > & FC,
+          Eigen::PlainObjectBase<DerivedJ > & J);
       //  Inputs:
       //  Inputs:
       //    VA  #VA by 3 list of vertex positions of first mesh
       //    VA  #VA by 3 list of vertex positions of first mesh
       //    FA  #FA by 3 list of triangle indices into VA
       //    FA  #FA by 3 list of triangle indices into VA

文件差異過大導致無法顯示
+ 0 - 0
include/igl/copyleft/cgal/remesh_intersections.cpp


+ 1 - 0
include/igl/copyleft/cgal/remesh_self_intersections.cpp

@@ -92,4 +92,5 @@ template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<doubl
 template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif
 #endif

+ 2 - 0
include/igl/cumsum.cpp

@@ -62,4 +62,6 @@ IGL_INLINE void igl::cumsum(
 template void igl::cumsum<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::cumsum<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::cumsum<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 template void igl::cumsum<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 template void igl::cumsum<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
 template void igl::cumsum<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
+template void igl::cumsum<Eigen::Matrix<unsigned long, 2, 1, 0, 2, 1>, Eigen::Matrix<unsigned long, 2, 1, 0, 2, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<unsigned long, 2, 1, 0, 2, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<unsigned long, 2, 1, 0, 2, 1> >&);
+template void igl::cumsum<Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1>, Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1> >&);
 #endif
 #endif

+ 3 - 2
include/igl/nchoosek.cpp

@@ -30,7 +30,7 @@ IGL_INLINE double igl::nchoosek(const int n, const int k)
 
 
 template < typename DerivedV, typename DerivedU>
 template < typename DerivedV, typename DerivedU>
 IGL_INLINE void igl::nchoosek(
 IGL_INLINE void igl::nchoosek(
-  const Eigen::PlainObjectBase<DerivedV> & V,
+  const Eigen::MatrixBase<DerivedV> & V,
   const int k,
   const int k,
   Eigen::PlainObjectBase<DerivedU> & U)
   Eigen::PlainObjectBase<DerivedU> & U)
 {
 {
@@ -68,5 +68,6 @@ IGL_INLINE void igl::nchoosek(
 
 
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
 // Explicit template specialization
-template void igl::nchoosek<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template void igl::nchoosek<Eigen::CwiseNullaryOp<Eigen::internal::linspaced_op<int, true>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::CwiseNullaryOp<Eigen::internal::linspaced_op<int, true>, Eigen::Matrix<int, -1, 1, 0, -1, 1> > > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template void igl::nchoosek<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 #endif
 #endif

+ 1 - 1
include/igl/nchoosek.h

@@ -32,7 +32,7 @@ namespace igl
   //     combination
   //     combination
   template < typename DerivedV, typename DerivedU>
   template < typename DerivedV, typename DerivedU>
   IGL_INLINE void nchoosek(
   IGL_INLINE void nchoosek(
-    const Eigen::PlainObjectBase<DerivedV> & V,
+    const Eigen::MatrixBase<DerivedV> & V,
     const int k,
     const int k,
     Eigen::PlainObjectBase<DerivedU> & U);
     Eigen::PlainObjectBase<DerivedU> & U);
 }
 }

部分文件因文件數量過多而無法顯示