Эх сурвалжийг харах

Reimplemented slice function -> huge speedup

Former-commit-id: 17ac6342dace6ce559be1686ef24d0a4ae7f0fb2
schuellc 10 жил өмнө
parent
commit
a838034aa2

+ 10 - 1
include/igl/boundary_loop.cpp

@@ -21,7 +21,10 @@ IGL_INLINE void igl::boundary_loop(
   using namespace Eigen;
   using namespace igl;
 
-  MatrixXd Vdummy(F.maxCoeff(),1);
+  if(F.rows() == 0)
+    return;
+
+  MatrixXd Vdummy(F.maxCoeff()+1,1);
   MatrixXi TT,TTi;
   vector<std::vector<int> > VF, VFi;
   triangle_triangle_adjacency(Vdummy,F,TT,TTi);
@@ -95,6 +98,9 @@ IGL_INLINE void igl::boundary_loop(
   using namespace Eigen;
   using namespace std;
 
+  if(F.rows() == 0)
+    return;
+
   vector<vector<int> > Lall;
   boundary_loop(F,Lall);
 
@@ -122,6 +128,9 @@ IGL_INLINE void igl::boundary_loop(
   using namespace Eigen;
   using namespace std;
 
+  if(F.rows() == 0)
+    return;
+
   vector<int> Lvec;
   boundary_loop(F,Lvec);
 

+ 11 - 7
include/igl/serialize.cpp

@@ -43,7 +43,7 @@ namespace igl
     }
     else
     {
-      std::cerr << "saving binary serialization failed!" << std::endl;
+      std::cerr << "serialization: file " << filename << " not found!" << std::endl;
     }
 
     return success;
@@ -115,7 +115,7 @@ namespace igl
     }
     else
     {
-      std::cerr << "Loading binary serialization failed!" << std::endl;
+      std::cerr << "serialization: file " << filename << " not found!" << std::endl;
     }
 
     return success;
@@ -646,16 +646,20 @@ namespace igl
       {
         if(obj)
         {
-          std::cout << "deserialization: possible memory leak for '" << typeid(obj).name() << "'" << std::endl;
+          std::cout << "serialization: possible memory leak in serialization for '" << typeid(obj).name() << "'" << std::endl;
           obj = nullptr;
         }
       }
       else
       {
         if(obj)
-          std::cout << "deserialization: possible memory leak for '" << typeid(obj).name() << "'" << std::endl;
-
-        obj = new typename std::remove_pointer<T>::type();
+        {
+          std::cout << "serialization: possible memory corruption in deserialization for '" << typeid(obj).name() << "'" << std::endl;
+        }
+        else
+        {
+          obj = new typename std::remove_pointer<T>::type();
+        }
         serialization::deserialize(*obj,iter);
       }
     }
@@ -721,7 +725,7 @@ namespace igl
     template <typename T>
     IGL_INLINE void deserialize(T& obj,const std::vector<char>& buffer)
     {
-      std::cerr << typeid(obj).name() << " is not drserializable: derive from igl::Serializable or overload the function igl::serialization::deserialize(T& obj, const std::vector<char>& buffer)" << std::endl;
+      std::cerr << typeid(obj).name() << " is not deserializable: derive from igl::Serializable or overload the function igl::serialization::deserialize(T& obj, const std::vector<char>& buffer)" << std::endl;
     }
 
     // helper functions

+ 25 - 30
include/igl/slice.cpp

@@ -38,42 +38,37 @@ IGL_INLINE void igl::slice(
   assert(C.minCoeff() >= 0);
   assert(C.maxCoeff() < xn);
 
-  // Build reindexing maps for columns and rows, -1 means not in map
-  std::vector<std::vector<int> > RI;
-  RI.resize(xm);
-  for(int i = 0;i<ym;i++)
-  {
-    RI[R(i)].push_back(i);
-  }
-  std::vector<std::vector<int> > CI;
-  CI.resize(xn);
-  // initialize to -1
-  for(int i = 0;i<yn;i++)
+  // initialize row and col permutation vectors
+  Eigen::VectorXi rowIndexVec = Eigen::VectorXi::LinSpaced(xm,0,xm);
+  Eigen::VectorXi rowPermVec  = Eigen::VectorXi::LinSpaced(xm,0,xm);
+  for(int i=0;i<ym;i++)
   {
-    CI[C(i)].push_back(i);
+    int pos = rowIndexVec.coeffRef(R(i));
+    if(pos != i)
+    {
+      int& val = rowPermVec.coeffRef(i);
+      std::swap(rowIndexVec.coeffRef(val),rowIndexVec.coeffRef(R(i)));
+      std::swap(rowPermVec.coeffRef(i),rowPermVec.coeffRef(pos));
+    }
   }
-  // Resize output
-  Eigen::SparseMatrix<T, Eigen::RowMajor> dyn_Y(ym,yn);
-  // Take a guess at the number of nonzeros (this assumes uniform distribution
-  // not banded or heavily diagonal)
-  dyn_Y.reserve((X.nonZeros()/(X.rows()*X.cols())) * (ym*yn));
-  // Iterate over outside
-  for(int k=0; k<X.outerSize(); ++k)
+  Eigen::PermutationMatrix<Eigen::Dynamic,Eigen::Dynamic,int> rowPerm(rowIndexVec);
+
+  Eigen::VectorXi colIndexVec = Eigen::VectorXi::LinSpaced(xn,0,xn);
+  Eigen::VectorXi colPermVec = Eigen::VectorXi::LinSpaced(xn,0,xn);
+  for(int i=0;i<yn;i++)
   {
-    // Iterate over inside
-    for(typename Eigen::SparseMatrix<T>::InnerIterator it (X,k); it; ++it)
+    int pos = colIndexVec.coeffRef(C(i));
+    if(pos != i)
     {
-      std::vector<int>::iterator rit, cit;
-      for(rit = RI[it.row()].begin();rit != RI[it.row()].end(); rit++)
-      {
-        for(cit = CI[it.col()].begin();cit != CI[it.col()].end(); cit++)
-        {
-          dyn_Y.coeffRef(*rit,*cit) = it.value();
-        }
-      }
+      int& val = colPermVec.coeffRef(i);
+      std::swap(colIndexVec.coeffRef(val),colIndexVec.coeffRef(C(i)));
+      std::swap(colPermVec.coeffRef(i),colPermVec.coeffRef(pos));
     }
   }
-  Y = Eigen::SparseMatrix<T>(dyn_Y);
+  Eigen::PermutationMatrix<Eigen::Dynamic,Eigen::Dynamic,int> colPerm(colPermVec);
+
+  Eigen::SparseMatrix<T> M = (rowPerm * X);
+  Y = (M * colPerm).block(0,0,ym,yn);
 }
 
 template <typename Mat>

+ 1 - 3
include/igl/slice.h

@@ -1,7 +1,7 @@
 // This file is part of libigl, a simple c++ geometry processing library.
 // 
 // Copyright (C) 2013 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/.
@@ -14,8 +14,6 @@
 
 namespace igl
 {
-  // THIS MAY HAVE BEEN SUPERSEDED BY EIGEN'S select FUNCTION
-  // 
   // Act like the matlab X(row_indices,col_indices) operator
   // 
   // Inputs:

+ 4 - 0
include/igl/viewer/Viewer.h

@@ -41,6 +41,10 @@ namespace igl
     IGL_INLINE int launch(std::string filename = "");
     IGL_INLINE void init();
 
+    // Stores command line arguments
+    int argc;
+    char **argv;
+
     // Stores all the viewing options
     igl::ViewerCore core;