Browse Source

Merge branch 'master' into unittests

Former-commit-id: 27272f755f705e8ce915c52f8727cb75e29cc9ad
Qingnan Zhou 10 years ago
parent
commit
4abe0cb8a1

+ 44 - 8
include/igl/boolean/mesh_boolean.cpp

@@ -7,6 +7,8 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "mesh_boolean.h"
 #include <igl/per_face_normals.h>
+#include <igl/boundary_facets.h>
+#include <igl/exterior_edges.h>
 #include <igl/cgal/peel_outer_hull_layers.h>
 #include <igl/cgal/remesh_self_intersections.h>
 #include <igl/remove_unreferenced.h>
@@ -244,6 +246,14 @@ IGL_INLINE void igl::boolean::mesh_boolean(
     G.row(g) = Gflip[g] ? CF.row(vG[g]).reverse().eval() : CF.row(vG[g]);
     GJ(g) = CJ(vG[g]);
   }
+#ifdef IGL_MESH_BOOLEAN_DEBUG
+  {
+    MatrixXd O;
+    boundary_facets(FC,O);
+    cout<<"# boundary: "<<O.rows()<<endl;
+  }
+  cout<<"# exterior: "<<exterior_edges(FC).rows()<<endl;
+#endif
 #ifdef IGL_MESH_BOOLEAN_DEBUG
   cout<<"clean..."<<endl;
 #endif
@@ -257,6 +267,7 @@ IGL_INLINE void igl::boolean::mesh_boolean(
     vector<vector<Index> > 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<gm;g++)
     {
@@ -269,6 +280,7 @@ IGL_INLINE void igl::boolean::mesh_boolean(
         (G(g,0) == uG(ug,1) && G(g,1) == uG(ug,2) && G(g,2) == uG(ug,0)) ||
         (G(g,0) == uG(ug,2) && G(g,1) == uG(ug,0) && G(g,2) == uG(ug,1));
       counts(ug) += consistent ? 1 : -1;
+      ucounts(ug)++;
     }
     MatrixX3I oldG = G;
     // Faces of output vG[i] = j means ith face of output should be jth face in
@@ -278,17 +290,33 @@ IGL_INLINE void igl::boolean::mesh_boolean(
     {
       // if signed occurrences is zero or ±two then keep none
       // else if signed occurrences is ±one then keep just one facet
-      if(abs(counts(ug)) == 1)
+      switch(abs(counts(ug)))
       {
-        assert(uG2G.size() > 0);
-        vG.push_back(uG2G[ug][0]);
-      }
+        case 1:
+          assert(uG2G[ug].size() > 0);
+          vG.push_back(uG2G[ug][0]);
 #ifdef IGL_MESH_BOOLEAN_DEBUG
-      else
-      {
-        cout<<"Skipping "<<uG2G.size()<<" facets..."<<endl;
-      }
+          if(abs(ucounts(ug)) != 1)
+          {
+            cout<<"count,ucount of "<<counts(ug)<<","<<ucounts(ug)<<endl;
+          }
+#endif
+          break;
+        case 0:
+#ifdef IGL_MESH_BOOLEAN_DEBUG
+          cout<<"Skipping "<<uG2G[ug].size()<<" facets..."<<endl;
+          if(abs(ucounts(ug)) != 0)
+          {
+            cout<<"count,ucount of "<<counts(ug)<<","<<ucounts(ug)<<endl;
+          }
+#endif
+          break;
+        default:
+#ifdef IGL_MESH_BOOLEAN_DEBUG
+          cout<<"Didn't expect to be here."<<endl;
 #endif
+          assert(false && "Shouldn't count be -1/0/1 ?");
+      }
     }
     G.resize(vG.size(),3);
     J.resize(vG.size());
@@ -304,6 +332,14 @@ IGL_INLINE void igl::boolean::mesh_boolean(
   //cerr<<"warning not removing unref"<<endl;
   //VC = CV;
   //FC = G;
+#ifdef IGL_MESH_BOOLEAN_DEBUG
+  {
+    MatrixXd O;
+    boundary_facets(FC,O);
+    cout<<"# boundary: "<<O.rows()<<endl;
+  }
+  cout<<"# exterior: "<<exterior_edges(FC).rows()<<endl;
+#endif
 }
 
 #ifdef IGL_STATIC_LIBRARY

+ 18 - 18
include/igl/cgal/order_facets_around_edge.cpp

@@ -55,11 +55,11 @@ void igl::cgal::order_facets_around_edge(
 
     // Handle base cases
     if (adj_faces.size() == 0) {
-        order.resize(0);
+        order.resize(0, 1);
         return;
     } else if (adj_faces.size() == 1) {
-        order.resize(1);
-        order[0] = 0;
+        order.resize(1, 1);
+        order(0, 0) = 0;
         return;
     } else if (adj_faces.size() == 2) {
         const size_t o1 =
@@ -70,19 +70,19 @@ void igl::cgal::order_facets_around_edge(
         const Point_3 pd(V(d, 0), V(d, 1), V(d, 2));
         const Point_3 p1(V(o1, 0), V(o1, 1), V(o1, 2));
         const Point_3 p2(V(o2, 0), V(o2, 1), V(o2, 2));
-        order.resize(2);
+        order.resize(2, 1);
         switch (CGAL::orientation(ps, pd, p1, p2)) {
             case CGAL::POSITIVE:
-                order[0] = 1;
-                order[1] = 0;
+                order(0, 0) = 1;
+                order(1, 0) = 0;
                 break;
             case CGAL::NEGATIVE:
-                order[0] = 0;
-                order[1] = 1;
+                order(0, 0) = 0;
+                order(1, 0) = 1;
                 break;
             case CGAL::COPLANAR:
-                order[0] = adj_faces[0] < adj_faces[1] ? 0:1;
-                order[1] = adj_faces[0] < adj_faces[1] ? 1:0;
+                order(0, 0) = adj_faces[0] < adj_faces[1] ? 0:1;
+                order(1, 0) = adj_faces[0] < adj_faces[1] ? 1:0;
                 break;
             default:
                 assert(false);
@@ -167,28 +167,28 @@ void igl::cgal::order_facets_around_edge(
     const size_t negative_size = negative_order.size();
 
     order.resize(tie_positive_size + positive_size +
-            tie_negative_size + negative_size);
+            tie_negative_size + negative_size, 1);
 
     size_t count=0;
     for (size_t i=0; i<tie_positive_size; i++) {
-        order[count+i] =
+        order(count+i, 0) =
             tie_positive_oriented_index[tie_positive_order[i]];
     }
     count += tie_positive_size;
 
     for (size_t i=0; i<negative_size; i++) {
-        order[count+i] = negative_side_index[negative_order[i]];
+        order(count+i, 0) = negative_side_index[negative_order(i, 0)];
     }
     count += negative_size;
 
     for (size_t i=0; i<tie_negative_size; i++) {
-        order[count+i] =
+        order(count+i, 0) =
             tie_negative_oriented_index[tie_negative_order[i]];
     }
     count += tie_negative_size;
 
     for (size_t i=0; i<positive_size; i++) {
-        order[count+i] = positive_side_index[positive_order[i]];
+        order(count+i, 0) = positive_side_index[positive_order(i, 0)];
     }
     count += positive_size;
     assert(count == num_adj_faces);
@@ -196,9 +196,9 @@ void igl::cgal::order_facets_around_edge(
     // Find the correct start point.
     size_t start_idx = 0;
     for (size_t i=0; i<num_adj_faces; i++) {
-        const Point_3& p_a = opposite_vertices[order[i]];
+        const Point_3& p_a = opposite_vertices[order(i, 0)];
         const Point_3& p_b =
-            opposite_vertices[order[(i+1)%num_adj_faces]];
+            opposite_vertices[order((i+1)%num_adj_faces, 0)];
         if (CGAL::orientation(p_s, p_d, p_a, p_b) == CGAL::POSITIVE) {
             start_idx = (i+1)%num_adj_faces;
             break;
@@ -206,6 +206,6 @@ void igl::cgal::order_facets_around_edge(
     }
     DerivedI circular_order = order;
     for (size_t i=0; i<num_adj_faces; i++) {
-        order[i] = circular_order[(start_idx + i)%num_adj_faces];
+        order(i, 0) = circular_order((start_idx + i)%num_adj_faces, 0);
     }
 }

+ 15 - 9
include/igl/cgal/outer_facet.cpp

@@ -25,15 +25,21 @@ IGL_INLINE void igl::cgal::outer_facet(
         bool & flipped) {
 
     // Algorithm:
-    //    Find an outer edge.
-    //    Order adjacent facets around the edge.
-    //    For consecutive facets, check if the tetrahedron formed by them is
-    //    positively oriented.
-    //    If yes, check the next pair.
-    //    If not, return either face.
-    typedef typename DerivedV::Scalar Scalar;
-    typedef typename DerivedV::Index Index;
-    const size_t INVALID = std::numeric_limits<size_t>::max();
+    //
+    //    1. Find an outer edge (s, d).
+    //
+    //    2. Order adjacent facets around this edge. Because the edge is an
+    //    outer edge, there exists a plane passing through it such that all its
+    //    adjacent facets lie on the same side. The implementation of
+    //    order_facets_around_edge() will find a natural start facet such that
+    //    The first and last facets according to this order are on the outside.
+    //
+    //    3. Because the vertex s is an outer vertex by construction (see
+    //    implemnetation of outer_edge()). The first adjacent facet is facing
+    //    outside (i.e. flipped=false) if it contains directed edge (s, d).  
+    //
+    typedef typename DerivedV::Scalar Scalar; typedef typename DerivedV::Index
+        Index; const size_t INVALID = std::numeric_limits<size_t>::max();
 
     Index s,d;
     Eigen::Matrix<Index,Eigen::Dynamic,1> incident_faces;

+ 0 - 1
include/igl/cgal/outer_hull.cpp

@@ -17,7 +17,6 @@
 #include "../per_face_normals.h"
 #include "../writePLY.h"
 #include "../sort_angles.h"
-#include "../writeDMAT.h"
 
 #include <Eigen/Geometry>
 #include <vector>

+ 2 - 2
include/igl/normal_derivative.cpp

@@ -64,7 +64,7 @@ IGL_INLINE void igl::normal_derivative(
           2);
       DDV *= S;
 
-      IJV.resize(DDV.size());
+      IJV.reserve(DDV.size());
       for(size_t f = 0;f<6*4;f++)
       {
         for(size_t e = 0;e<m;e++)
@@ -95,7 +95,7 @@ IGL_INLINE void igl::normal_derivative(
         slice(C,(VectorXi(12)<<1,1,2,2,2,2,0,0,0,0,1,1).finished(),2);
       DDV *= S;
 
-      IJV.resize(DDV.size());
+      IJV.reserve(DDV.size());
       for(size_t f = 0;f<12;f++)
       {
         for(size_t e = 0;e<m;e++)

+ 1 - 1
tutorial/cmake/FindGLFWH.cmake

@@ -37,7 +37,7 @@ if(GLFW_FOUND)
   message(STATUS "Found GLFW: ${GLFW_INCLUDE_DIR} -- HEADERS ONLY")
 else(GLFW_FOUND)
   if (NOT GLFW_FIND_QUIETLY)
-    message("could NOT find GLFW")
+    message(WARNING "could NOT find GLFW")
   endif (NOT GLFW_FIND_QUIETLY)
 endif(GLFW_FOUND)