فهرست منبع

Refactor.

Former-commit-id: 44e869d864369f2cade5c809eb13f3ae69b3b907
Qingnan Zhou 9 سال پیش
والد
کامیت
a1fa72fa91

+ 24 - 1
include/igl/copyleft/boolean/mesh_boolean.cpp

@@ -91,6 +91,28 @@ IGL_INLINE bool igl::copyleft::boolean::mesh_boolean(
   log_time("resolve_self_intersection");
 #endif
 
+  // Compute edges.
+  Eigen::MatrixXi E, uE;
+  Eigen::VectorXi EMAP;
+  std::vector<std::vector<size_t> > uE2E;
+  igl::unique_edge_map(F, E, uE, EMAP, uE2E);
+
+  // Compute patches
+  Eigen::VectorXi P;
+  const size_t num_patches = igl::extract_manifold_patches(F, EMAP, uE2E, P);
+#ifdef MESH_BOOLEAN_TIMING
+  log_time("patch_extraction");
+#endif
+
+  // Compute cells.
+  Eigen::MatrixXi per_patch_cells;
+  const size_t num_cells =
+    igl::copyleft::cgal::extract_cells(
+        V, F, P, E, uE, uE2E, EMAP, per_patch_cells);
+#ifdef MESH_BOOLEAN_TIMING
+  log_time("cell_extraction");
+#endif
+
   // Compute winding numbers on each side of each facet.
   const size_t num_faces = F.rows();
   Eigen::MatrixXi W;
@@ -101,7 +123,8 @@ IGL_INLINE bool igl::copyleft::boolean::mesh_boolean(
   if (num_faces > 0) 
   {
     valid = valid & 
-      igl::copyleft::cgal::propagate_winding_numbers(V, F, labels, W);
+      igl::copyleft::cgal::propagate_winding_numbers(
+          V, F, uE, uE2E, num_patches, P, num_cells, per_patch_cells, labels, W);
   } else 
   {
     W.resize(0, 4);

+ 27 - 0
include/igl/copyleft/cgal/cell_adjacency.cpp

@@ -0,0 +1,27 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2016 Qingnan Zhou <qnzhou@gmail.com>
+// 
+// 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 "cell_adjacency.h"
+
+template <typename DerivedC>
+IGL_INLINE void igl::copyleft::cgal::cell_adjacency(
+    const Eigen::PlainObjectBase<DerivedC>& per_patch_cells,
+    const size_t num_cells,
+    std::vector<std::set<std::tuple<typename DerivedC::Scalar, bool, size_t> > >&
+    adjacency_list) {
+
+  const size_t num_patches = per_patch_cells.rows();
+  adjacency_list.resize(num_cells);
+  for (size_t i=0; i<num_patches; i++) {
+    const int positive_cell = per_patch_cells(i,0);
+    const int negative_cell = per_patch_cells(i,1);
+    adjacency_list[positive_cell].emplace(negative_cell, false, i);
+    adjacency_list[negative_cell].emplace(positive_cell, true, i);
+  }
+}

+ 50 - 0
include/igl/copyleft/cgal/cell_adjacency.h

@@ -0,0 +1,50 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2016 Qingnan Zhou <qnzhou@gmail.com>
+// 
+// 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/.
+//
+#ifndef IGL_COPYLEFT_CGAL_CELL_ADJACENCY_H
+#define IGL_COPYLEFT_CGAL_CELL_ADJACENCY_H
+#include "../../igl_inline.h"
+#include <Eigen/Core>
+#include <set>
+#include <tuple>
+#include <vector>
+
+namespace igl
+{
+  namespace copyleft
+  {
+    namespace cgal
+    {
+      // Inputs:
+      //   per_patch_cells  #P by 2 list of cell labels on each side of each
+      //                    patch.  Cell labels are assumed to be continuous
+      //                    from 0 to #C.
+      //   num_cells        number of cells.
+      //
+      // Outputs:
+      //   adjacency_list  #C array of list of adjcent cell informations.  If
+      //                   cell i and cell j are adjacent via patch x, where i
+      //                   is on the positive side of x, and j is on the
+      //                   negative side.  Then,
+      //                   adjacency_list[i] will contain the entry {j, false, x}
+      //                   and
+      //                   adjacency_list[j] will contain the entry {i, true, x}
+      template < typename DerivedC >
+      IGL_INLINE void cell_adjacency(
+          const Eigen::PlainObjectBase<DerivedC>& per_patch_cells,
+          const size_t num_cells,
+          std::vector<std::set<std::tuple<typename DerivedC::Scalar, bool, size_t> > >&
+          adjacency_list);
+    }
+  }
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "cell_adjacency.cpp"
+#endif
+#endif

+ 61 - 21
include/igl/copyleft/cgal/propagate_winding_numbers.cpp

@@ -20,6 +20,7 @@
 #include "closest_facet.h"
 #include "assign_scalar.h"
 #include "extract_cells.h"
+#include "cell_adjacency.h"
 
 #include <stdexcept>
 #include <limits>
@@ -54,19 +55,11 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
   };
   tictoc();
 #endif
-  const size_t num_faces = F.rows();
-  //typedef typename DerivedF::Scalar Index;
 
   Eigen::MatrixXi E, uE;
   Eigen::VectorXi EMAP;
   std::vector<std::vector<size_t> > uE2E;
   igl::unique_edge_map(F, E, uE, EMAP, uE2E);
-  bool valid = true;
-  if (!piecewise_constant_winding_number(F, uE, uE2E)) 
-  {
-    std::cerr << "Input mesh is not orientable!" << std::endl;
-    valid = false;
-  }
 
   Eigen::VectorXi P;
   const size_t num_patches = igl::extract_manifold_patches(F, EMAP, uE2E, P);
@@ -79,14 +72,61 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
   log_time("cell_extraction");
 #endif
 
-  typedef std::tuple<size_t, bool, size_t> CellConnection;
-  std::vector<std::set<CellConnection> > cell_adjacency(num_cells);
-  for (size_t i=0; i<num_patches; i++) {
-    const int positive_cell = per_patch_cells(i,0);
-    const int negative_cell = per_patch_cells(i,1);
-    cell_adjacency[positive_cell].emplace(negative_cell, false, i);
-    cell_adjacency[negative_cell].emplace(positive_cell, true, i);
+  return propagate_winding_numbers(V, F,
+          uE, uE2E,
+          num_patches, P,
+          num_cells, per_patch_cells,
+          labels, W);
+}
+
+
+template<
+  typename DerivedV,
+  typename DerivedF,
+  typename DeriveduE,
+  typename uE2EType,
+  typename DerivedP,
+  typename DerivedC,
+  typename DerivedL,
+  typename DerivedW>
+IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
+    const Eigen::PlainObjectBase<DerivedV>& V,
+    const Eigen::PlainObjectBase<DerivedF>& F,
+    const Eigen::PlainObjectBase<DeriveduE>& uE,
+    const std::vector<std::vector<uE2EType> >& uE2E,
+    const size_t num_patches,
+    const Eigen::PlainObjectBase<DerivedP>& P,
+    const size_t num_cells,
+    const Eigen::PlainObjectBase<DerivedC>& C,
+    const Eigen::PlainObjectBase<DerivedL>& labels,
+    Eigen::PlainObjectBase<DerivedW>& W)
+{
+#ifdef PROPAGATE_WINDING_NUMBER_TIMING
+  const auto & tictoc = []() -> double
+  {
+    static double t_start = igl::get_seconds();
+    double diff = igl::get_seconds()-t_start;
+    t_start += diff;
+    return diff;
+  };
+  const auto log_time = [&](const std::string& label) -> void {
+    std::cout << "propagate_winding_num." << label << ": "
+      << tictoc() << std::endl;
+  };
+  tictoc();
+#endif
+
+  bool valid = true;
+  if (!piecewise_constant_winding_number(F, uE, uE2E)) 
+  {
+    std::cerr << "Input mesh is not orientable!" << std::endl;
+    valid = false;
   }
+
+  const size_t num_faces = F.rows();
+  typedef std::tuple<typename DerivedC::Scalar, bool, size_t> CellConnection;
+  std::vector<std::set<CellConnection> > cell_adj;
+  igl::copyleft::cgal::cell_adjacency(C, num_cells, cell_adj);
 #ifdef PROPAGATE_WINDING_NUMBER_TIMING
   log_time("cell_connectivity");
 #endif
@@ -94,7 +134,7 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
   auto save_cell = [&](const std::string& filename, size_t cell_id) -> void{
     std::vector<size_t> faces;
     for (size_t i=0; i<num_patches; i++) {
-      if ((per_patch_cells.row(i).array() == cell_id).any()) {
+      if ((C.row(i).array() == cell_id).any()) {
         for (size_t j=0; j<num_faces; j++) {
           if ((size_t)P[j] == i) {
             faces.push_back(j);
@@ -140,7 +180,7 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
           size_t curr_idx = Q.front();
           Q.pop();
           int curr_label = cell_labels[curr_idx];
-          for (const auto& neighbor : cell_adjacency[curr_idx]) {
+          for (const auto& neighbor : cell_adj[curr_idx]) {
             if (cell_labels[std::get<0>(neighbor)] == 0) 
             {
               cell_labels[std::get<0>(neighbor)] = curr_label * -1;
@@ -191,7 +231,7 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
 #endif
 
   const size_t outer_patch = P[outer_facet];
-  const size_t infinity_cell = per_patch_cells(outer_patch, flipped?1:0);
+  const size_t infinity_cell = C(outer_patch, flipped?1:0);
 
   Eigen::VectorXi patch_labels(num_patches);
   const int INVALID = std::numeric_limits<int>::max();
@@ -214,7 +254,7 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
   while (!Q.empty()) {
     size_t curr_cell = Q.front();
     Q.pop();
-    for (const auto& neighbor : cell_adjacency[curr_cell]) {
+    for (const auto& neighbor : cell_adj[curr_cell]) {
       size_t neighbor_cell, patch_idx;
       bool direction;
       std::tie(neighbor_cell, direction, patch_idx) = neighbor;
@@ -258,8 +298,8 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
   for (size_t i=0; i<num_faces; i++) 
   {
     const size_t patch = P[i];
-    const size_t positive_cell = per_patch_cells(patch, 0);
-    const size_t negative_cell = per_patch_cells(patch, 1);
+    const size_t positive_cell = C(patch, 0);
+    const size_t negative_cell = C(patch, 1);
     for (size_t j=0; j<num_labels; j++) {
       W(i,j*2  ) = per_cell_W(positive_cell, j);
       W(i,j*2+1) = per_cell_W(negative_cell, j);

+ 33 - 0
include/igl/copyleft/cgal/propagate_winding_numbers.h

@@ -56,6 +56,39 @@ namespace igl
         const Eigen::PlainObjectBase<DerivedF>& F,
         const Eigen::PlainObjectBase<DerivedL>& labels,
         Eigen::PlainObjectBase<DerivedW>& W);
+
+      // Inputs:
+      //   V  #V by 3 list of vertex positions.
+      //   F  #F by 3 list of triangle indices into V.
+      //   P  #F list of patch ids.
+      //   C  #P by 2 list of cell ids on each side of each patch.
+      //   labels  #F list of facet labels ranging from 0 to k-1.
+      // Output:
+      //   W  #F by k*2 list of winding numbers.  ``W(i,j*2)`` is the winding
+      //      number on the positive side of facet ``i`` with respect to the
+      //      facets labeled ``j``.  Similarly, ``W(i,j*2+1)`` is the winding
+      //      number on the negative side of facet ``i`` with respect to the
+      //      facets labeled ``j``.
+      template<
+        typename DerivedV,
+        typename DerivedF,
+        typename DeriveduE,
+        typename uE2EType,
+        typename DerivedP,
+        typename DerivedC,
+        typename DerivedL,
+        typename DerivedW>
+      IGL_INLINE bool propagate_winding_numbers(
+        const Eigen::PlainObjectBase<DerivedV>& V,
+        const Eigen::PlainObjectBase<DerivedF>& F,
+        const Eigen::PlainObjectBase<DeriveduE>& uE,
+        const std::vector<std::vector<uE2EType> >& uE2E,
+        const size_t num_patches,
+        const Eigen::PlainObjectBase<DerivedP>& P,
+        const size_t num_cells,
+        const Eigen::PlainObjectBase<DerivedC>& C,
+        const Eigen::PlainObjectBase<DerivedL>& labels,
+        Eigen::PlainObjectBase<DerivedW>& W);
     }
   }
 }