Browse Source

pull out shortest_edge_... and max_faces... functions

Former-commit-id: 501a485477bd7e4208b4e9981607ad6fbc460192
Alec Jacobson 8 years ago
parent
commit
4deb79d564

+ 1 - 1
include/igl/copyleft/progressive_hulls.cpp

@@ -23,7 +23,7 @@ IGL_INLINE bool igl::copyleft::progressive_hulls(
     V,
     F,
     progressive_hulls_cost_and_placement,
-    max_faces_stopping_condition(m,max_m),
+    max_faces_stopping_condition(m,(const int)m,max_m),
     U,
     G,
     J,

+ 3 - 37
include/igl/decimate.cpp

@@ -12,6 +12,8 @@
 #include "slice_mask.h"
 #include "slice.h"
 #include "connect_boundary_to_infinity.h"
+#include "max_faces_stopping_condition.h"
+#include "shortest_edge_and_midpoint.h"
 #include <iostream>
 
 IGL_INLINE bool igl::decimate(
@@ -28,52 +30,16 @@ IGL_INLINE bool igl::decimate(
   const int orig_m = F.rows();
   // Tracking number of faces
   int m = F.rows();
-  const auto & shortest_edge_and_midpoint = [](
-    const int e,
-    const Eigen::MatrixXd & V,
-    const Eigen::MatrixXi & /*F*/,
-    const Eigen::MatrixXi & E,
-    const Eigen::VectorXi & /*EMAP*/,
-    const Eigen::MatrixXi & /*EF*/,
-    const Eigen::MatrixXi & /*EI*/,
-    double & cost,
-    Eigen::RowVectorXd & p)
-  {
-    cost = (V.row(E(e,0))-V.row(E(e,1))).norm();
-    p = 0.5*(V.row(E(e,0))+V.row(E(e,1)));
-  };
   typedef Eigen::MatrixXd DerivedV;
   typedef Eigen::MatrixXi DerivedF;
   DerivedV VO;
   DerivedF FO;
   igl::connect_boundary_to_infinity(V,F,VO,FO);
-  const auto & max_non_infinite_faces_stopping_condition = 
-    [max_m,orig_m,&m](
-      const Eigen::MatrixXd &,
-      const Eigen::MatrixXi &,
-      const Eigen::MatrixXi &,
-      const Eigen::VectorXi &,
-      const Eigen::MatrixXi &,
-      const Eigen::MatrixXi &,
-      const std::set<std::pair<double,int> > &,
-      const std::vector<std::set<std::pair<double,int> >::iterator > &,
-      const Eigen::MatrixXd &,
-      const int,
-      const int,
-      const int,
-      const int f1,
-      const int f2) -> bool
-    {
-      // Only subtract if we're collapsing a real face
-      if(f1 < orig_m) m-=1;
-      if(f2 < orig_m) m-=1;
-      return m<=(int)max_m;
-    };
   bool ret = decimate(
     VO,
     FO,
     shortest_edge_and_midpoint,
-    max_non_infinite_faces_stopping_condition,
+    max_faces_stopping_condition(m,orig_m,max_m),
     U,
     G,
     J,

+ 9 - 5
include/igl/max_faces_stopping_condition.cpp

@@ -2,6 +2,7 @@
 
 IGL_INLINE void igl::max_faces_stopping_condition(
   int & m,
+  const int orig_m,
   const int max_m,
   std::function<bool(
     const Eigen::MatrixXd &,
@@ -20,7 +21,7 @@ IGL_INLINE void igl::max_faces_stopping_condition(
     const int)> & stopping_condition)
 {
   stopping_condition = 
-    [max_m,&m](
+    [orig_m,max_m,&m](
     const Eigen::MatrixXd &,
     const Eigen::MatrixXi &,
     const Eigen::MatrixXi &,
@@ -33,10 +34,12 @@ IGL_INLINE void igl::max_faces_stopping_condition(
     const int,
     const int,
     const int,
-    const int,
-    const int)->bool
+    const int f1,
+    const int f2)->bool
     {
-      m-=2;
+      // Only subtract if we're collapsing a real face
+      if(f1 < orig_m) m-=1;
+      if(f2 < orig_m) m-=1;
       return m<=(int)max_m;
     };
 }
@@ -59,6 +62,7 @@ IGL_INLINE
     const int)> 
   igl::max_faces_stopping_condition(
     int & m,
+    const int orig_m,
     const int max_m)
 {
   std::function<bool(
@@ -77,6 +81,6 @@ IGL_INLINE
     const int,
     const int)> stopping_condition;
   max_faces_stopping_condition(
-      m,max_m,stopping_condition);
+      m,orig_m,max_m,stopping_condition);
   return stopping_condition;
 }

+ 5 - 0
include/igl/max_faces_stopping_condition.h

@@ -20,12 +20,16 @@ namespace igl
   // Inputs:
   //   m  reference to working variable initially should be set to current
   //    number of faces.
+  //   orig_m  number (size) of original face list _**not**_ including any
+  //     faces added to handle phony boundary faces connecting to point at
+  //     infinity. For closed meshes it's safe to set this to F.rows()
   //   max_m  maximum number of faces
   // Outputs:
   //   stopping_condition
   //
   IGL_INLINE void max_faces_stopping_condition(
     int & m,
+    const int orig_m,
     const int max_m,
     std::function<bool(
       const Eigen::MatrixXd &,
@@ -60,6 +64,7 @@ namespace igl
       const int)> 
     max_faces_stopping_condition(
       int & m,
+      const int orign_m,
       const int max_m);
 }
 

+ 16 - 0
include/igl/shortest_edge_and_midpoint.cpp

@@ -0,0 +1,16 @@
+#include "shortest_edge_and_midpoint.h"
+
+IGL_INLINE void igl::shortest_edge_and_midpoint(
+  const int e,
+  const Eigen::MatrixXd & V,
+  const Eigen::MatrixXi & /*F*/,
+  const Eigen::MatrixXi & E,
+  const Eigen::VectorXi & /*EMAP*/,
+  const Eigen::MatrixXi & /*EF*/,
+  const Eigen::MatrixXi & /*EI*/,
+  double & cost,
+  Eigen::RowVectorXd & p)
+{
+  cost = (V.row(E(e,0))-V.row(E(e,1))).norm();
+  p = 0.5*(V.row(E(e,0))+V.row(E(e,1)));
+}

+ 48 - 0
include/igl/shortest_edge_and_midpoint.h

@@ -0,0 +1,48 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2016 Alec Jacobson <alecjacobson@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_SHORTEST_EDGE_AND_MIDPOINT_H
+#define IGL_SHORTEST_EDGE_AND_MIDPOINT_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+#include <vector>
+namespace igl
+{
+  // Cost and placement function compatible with igl::decimate. The cost of
+  // collapsing an edge is its length (prefer to collapse short edges) and the
+  // placement strategy for the new vertex is the midpoint of the collapsed
+  // edge.
+  //
+  // Inputs:
+  //   e  index into E of edge to be considered for collapse
+  //   V  #V by dim list of vertex positions
+  //   F  #F by 3 list of faces (ignored)
+  //   E  #E by 2 list of edge indices into V
+  //   EMAP  #F*3 list of half-edges indices into E (ignored)
+  //   EF  #E by 2 list of edge-face flaps into F (ignored)
+  //   EI  #E by 2 list of edge-face opposite corners (ignored)
+  // Outputs:
+  //   cost  set to edge length
+  //   p  placed point set to edge midpoint
+  IGL_INLINE void shortest_edge_and_midpoint(
+    const int e,
+    const Eigen::MatrixXd & V,
+    const Eigen::MatrixXi & /*F*/,
+    const Eigen::MatrixXi & E,
+    const Eigen::VectorXi & /*EMAP*/,
+    const Eigen::MatrixXi & /*EF*/,
+    const Eigen::MatrixXi & /*EI*/,
+    double & cost,
+    Eigen::RowVectorXd & p);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "shortest_edge_and_midpoint.cpp"
+#endif
+#endif
+
+

+ 1 - 18
tutorial/703_Decimation/main.cpp

@@ -1,6 +1,7 @@
 #include <igl/circulation.h>
 #include <igl/collapse_edge.h>
 #include <igl/edge_flaps.h>
+#include <igl/shortest_edge_and_midpoint.h>
 #include <igl/read_triangle_mesh.h>
 #include <igl/viewer/Viewer.h>
 #include <Eigen/Core>
@@ -39,24 +40,6 @@ int main(int argc, char * argv[])
   MatrixXd C;
   int num_collapsed;
 
-  // Function for computing cost of collapsing edge (lenght) and placement
-  // (midpoint)
-  const auto & shortest_edge_and_midpoint = [](
-    const int e,
-    const Eigen::MatrixXd & V,
-    const Eigen::MatrixXi & /*F*/,
-    const Eigen::MatrixXi & E,
-    const Eigen::VectorXi & /*EMAP*/,
-    const Eigen::MatrixXi & /*EF*/,
-    const Eigen::MatrixXi & /*EI*/,
-    double & cost,
-    RowVectorXd & p)
-  {
-    cost = (V.row(E(e,0))-V.row(E(e,1))).norm();
-    p = 0.5*(V.row(E(e,0))+V.row(E(e,1)));
-  };
-
-
   // Function to reset original mesh and data structures
   const auto & reset = [&]()
   {