Browse Source

decimate with finite cost

Former-commit-id: ce1f76831746772fb8402b027ff0439c0439ee69
Alec Jacobson 9 years ago
parent
commit
6fad412558

+ 1 - 1
include/igl/circulation.cpp

@@ -44,8 +44,8 @@ IGL_INLINE std::vector<int> igl::circulation(
   int ei = e;
   while(true)
   {
-    N.push_back(fi);
     step(ei,fi,ei,fi);
+    N.push_back(fi);
     // back to start?
     if(fi == f0)
     {

+ 2 - 2
include/igl/collapse_edge.cpp

@@ -111,8 +111,8 @@ IGL_INLINE bool igl::collapse_edge(
   // finally, reindex faces and edges incident on d. Do this last so asserts
   // make sense.
   //
-  // Could actually skip first two, since those are always the two collpased
-  // faces.
+  // Could actually skip first and last, since those are always the two
+  // collpased faces.
   for(auto f : nV2Fd)
   {
     for(int v = 0;v<3;v++)

+ 4 - 2
include/igl/copyleft/progressive_hulls.cpp

@@ -14,7 +14,8 @@ IGL_INLINE bool igl::copyleft::progressive_hulls(
   const Eigen::MatrixXi & F,
   const size_t max_m,
   Eigen::MatrixXd & U,
-  Eigen::MatrixXi & G)
+  Eigen::MatrixXi & G,
+  Eigen::VectorXi & J)
 {
   int m = F.rows();
   return decimate(
@@ -23,5 +24,6 @@ IGL_INLINE bool igl::copyleft::progressive_hulls(
     progressive_hulls_cost_and_placement,
     max_faces_stopping_condition(m,max_m),
     U,
-    G);
+    G,
+    J);
 }

+ 3 - 1
include/igl/copyleft/progressive_hulls.h

@@ -26,13 +26,15 @@ namespace igl
     // Outputs:
     //   U  #U by dim list of output vertex posistions (can be same ref as V)
     //   G  #G by 3 list of output face indices into U (can be same ref as G)
+    //   J  #G list of indices into F of birth faces
     // Returns true if m was reached (otherwise #G > m)
     IGL_INLINE bool progressive_hulls(
       const Eigen::MatrixXd & V,
       const Eigen::MatrixXi & F,
       const size_t max_m,
       Eigen::MatrixXd & U,
-      Eigen::MatrixXi & G);
+      Eigen::MatrixXi & G,
+      Eigen::VectorXi & J);
   }
 }
 #ifndef IGL_STATIC_LIBRARY

+ 11 - 4
include/igl/decimate.cpp

@@ -17,7 +17,8 @@ IGL_INLINE bool igl::decimate(
   const Eigen::MatrixXi & F,
   const size_t max_m,
   Eigen::MatrixXd & U,
-  Eigen::MatrixXi & G)
+  Eigen::MatrixXi & G,
+  Eigen::VectorXi & J)
 {
   int m = F.rows();
   const auto & shortest_edge_and_midpoint = [](
@@ -40,7 +41,8 @@ IGL_INLINE bool igl::decimate(
     shortest_edge_and_midpoint,
     max_faces_stopping_condition(m,max_m),
     U,
-    G);
+    G,
+    J);
 }
 
 IGL_INLINE bool igl::decimate(
@@ -72,7 +74,8 @@ IGL_INLINE bool igl::decimate(
       const int,
       const int)> & stopping_condition,
   Eigen::MatrixXd & U,
-  Eigen::MatrixXi & G)
+  Eigen::MatrixXi & G,
+  Eigen::VectorXi & J)
 {
   using namespace Eigen;
   using namespace std;
@@ -132,6 +135,7 @@ IGL_INLINE bool igl::decimate(
   }
   // remove all IGL_COLLAPSE_EDGE_NULL faces
   MatrixXi F2(F.rows(),3);
+  J.resize(F.rows());
   int m = 0;
   for(int f = 0;f<F.rows();f++)
   {
@@ -140,10 +144,13 @@ IGL_INLINE bool igl::decimate(
       F(f,1) != IGL_COLLAPSE_EDGE_NULL || 
       F(f,2) != IGL_COLLAPSE_EDGE_NULL)
     {
-      F2.row(m++) = F.row(f);
+      F2.row(m) = F.row(f);
+      J(m) = f;
+      m++;
     }
   }
   F2.conservativeResize(m,F2.cols());
+  J.conservativeResize(m);
   VectorXi _1;
   remove_unreferenced(V,F2,U,G,_1);
   return clean_finish;

+ 5 - 2
include/igl/decimate.h

@@ -25,13 +25,15 @@ namespace igl
   // Outputs:
   //   U  #U by dim list of output vertex posistions (can be same ref as V)
   //   G  #G by 3 list of output face indices into U (can be same ref as G)
+  //   J  #G list of indices into F of birth face
   // Returns true if m was reached (otherwise #G > m)
   IGL_INLINE bool decimate(
     const Eigen::MatrixXd & V,
     const Eigen::MatrixXi & F,
     const size_t max_m,
     Eigen::MatrixXd & U,
-    Eigen::MatrixXi & G);
+    Eigen::MatrixXi & G,
+    Eigen::VectorXi & J);
   // Inputs:
   //   cost_and_placement  function computing cost of collapsing an edge and 3d
   //     position where it should be placed:
@@ -70,7 +72,8 @@ namespace igl
       const int,
       const int)> & stopping_condition,
     Eigen::MatrixXd & U,
-    Eigen::MatrixXi & G);
+    Eigen::MatrixXi & G,
+    Eigen::VectorXi & J);
 
 }
 

+ 108 - 0
include/igl/infinite_cost_stopping_condition.cpp

@@ -0,0 +1,108 @@
+// 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/.
+#include "infinite_cost_stopping_condition.h"
+
+IGL_INLINE void igl::infinite_cost_stopping_condition(
+  const std::function<void(
+    const int,
+    const Eigen::MatrixXd &,
+    const Eigen::MatrixXi &,
+    const Eigen::MatrixXi &,
+    const Eigen::VectorXi &,
+    const Eigen::MatrixXi &,
+    const Eigen::MatrixXi &,
+    double &,
+    Eigen::RowVectorXd &)> & cost_and_placement,
+  std::function<bool(
+    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,
+    const int)> & stopping_condition)
+{
+  stopping_condition = 
+    [&cost_and_placement]
+    (
+    const Eigen::MatrixXd & V,
+    const Eigen::MatrixXi & F,
+    const Eigen::MatrixXi & E,
+    const Eigen::VectorXi & EMAP,
+    const Eigen::MatrixXi & EF,
+    const Eigen::MatrixXi & EI,
+    const std::set<std::pair<double,int> > & Q,
+    const std::vector<std::set<std::pair<double,int> >::iterator > & Qit,
+    const Eigen::MatrixXd & C,
+    const int e,
+    const int /*e1*/,
+    const int /*e2*/,
+    const int /*f1*/,
+    const int /*f2*/)->bool
+    {
+      Eigen::RowVectorXd p;
+      double cost;
+      cost_and_placement(e,V,F,E,EMAP,EF,EI,cost,p);
+      return isinf(cost);
+    };
+}
+
+IGL_INLINE 
+  std::function<bool(
+    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,
+    const int)> 
+  igl::infinite_cost_stopping_condition(
+    const std::function<void(
+      const int,
+      const Eigen::MatrixXd &,
+      const Eigen::MatrixXi &,
+      const Eigen::MatrixXi &,
+      const Eigen::VectorXi &,
+      const Eigen::MatrixXi &,
+      const Eigen::MatrixXi &,
+      double &,
+      Eigen::RowVectorXd &)> & cost_and_placement)
+{
+  std::function<bool(
+    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,
+    const int)> stopping_condition;
+  infinite_cost_stopping_condition(cost_and_placement,stopping_condition);
+  return stopping_condition;
+}
+

+ 85 - 0
include/igl/infinite_cost_stopping_condition.h

@@ -0,0 +1,85 @@
+// 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_INFINITE_COST_STOPPING_CONDITION_H
+#define IGL_INFINITE_COST_STOPPING_CONDITION_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+#include <vector>
+#include <set>
+#include <functional>
+namespace igl
+{
+  // Stopping condition function compatible with igl::decimate. The output
+  // function handle will return true if cost of next edge is infinite.
+  //
+  // Inputs:
+  //   cost_and_placement  handle being used by igl::collapse_edge
+  // Outputs:
+  //   stopping_condition
+  //
+  IGL_INLINE void infinite_cost_stopping_condition(
+    const std::function<void(
+      const int,
+      const Eigen::MatrixXd &,
+      const Eigen::MatrixXi &,
+      const Eigen::MatrixXi &,
+      const Eigen::VectorXi &,
+      const Eigen::MatrixXi &,
+      const Eigen::MatrixXi &,
+      double &,
+      Eigen::RowVectorXd &)> & cost_and_placement,
+    std::function<bool(
+      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,
+      const int)> & stopping_condition);
+  IGL_INLINE 
+    std::function<bool(
+      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,
+      const int)> 
+    infinite_cost_stopping_condition(
+      const std::function<void(
+        const int,
+        const Eigen::MatrixXd &,
+        const Eigen::MatrixXi &,
+        const Eigen::MatrixXi &,
+        const Eigen::VectorXi &,
+        const Eigen::MatrixXi &,
+        const Eigen::MatrixXi &,
+        double &,
+        Eigen::RowVectorXd &)> & cost_and_placement);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "infinite_cost_stopping_condition.cpp"
+#endif
+#endif
+
+