Browse Source

cleaned up removeUnreferenced (we should rename this remove_unreferenced to match style and the corresponding matlab func)

Former-commit-id: a74c8a6e22c9247f5fac50297a882b387c150b3b
Alec Jacobson (jalec 11 years ago
parent
commit
306c5b7a31

+ 55 - 0
include/igl/fit_plane.cpp

@@ -0,0 +1,55 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2013 Daniele Panozzo <daniele.panozzo@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 "fit_plane.h"
+#include <iostream>
+
+void igl::fit_plane(
+    const Eigen::MatrixXd & V,
+    Eigen::RowVector3d & N,
+    Eigen::RowVector3d & C)
+{
+    assert(V.rows()>0);
+
+    Eigen::Vector3d sum = V.colwise().sum();
+
+    Eigen::Vector3d center = sum.array()/(double(V.rows()));
+
+    C = center;
+
+    double sumXX=0.0f,sumXY=0.0f,sumXZ=0.0f;
+    double sumYY=0.0f,sumYZ=0.0f;
+    double sumZZ=0.0f;
+
+    for(int i=0;i<V.rows();i++){
+        double diffX=V(i,0)-center(0);
+        double diffY=V(i,1)-center(1);
+        double diffZ=V(i,2)-center(2);
+        sumXX+=diffX*diffX;
+        sumXY+=diffX*diffY;
+        sumXZ+=diffX*diffZ;
+        sumYY+=diffY*diffY;
+        sumYZ+=diffY*diffZ;
+        sumZZ+=diffZ*diffZ;
+    }
+
+    Eigen::MatrixXd m(3,3);
+    m << sumXX,sumXY,sumXZ,
+        sumXY,sumYY,sumYZ,
+        sumXZ,sumYZ,sumZZ;
+
+	Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(m);
+  
+  N = es.eigenvectors().col(0);
+}
+
+#ifndef IGL_HEADER_ONLY
+#endif
+
+
+

+ 35 - 0
include/igl/fit_plane.h

@@ -0,0 +1,35 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2013 Daniele Panozzo <daniele.panozzo@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_FIT_PLANE_H
+#define IGL_FIT_PLANE_H
+
+#include "igl_inline.h"
+#include <Eigen/Dense>
+
+namespace igl
+{
+  // This function fits a plane to a point cloud.
+  //
+  // Input:
+  //   V #Vx3 matrix. The 3D point cloud, one row for each vertex.
+  // Output: 
+  //   N 1x3 Vector. The normal of the fitted plane.
+  //   C 1x3 Vector. A point that lies in the fitted plane.
+  // From http://missingbytes.blogspot.com/2012/06/fitting-plane-to-point-cloud.html
+
+  IGL_INLINE void fit_plane(
+    const Eigen::MatrixXd & V,
+    Eigen::RowVector3d & N,
+    Eigen::RowVector3d & C);
+}
+
+#ifdef IGL_HEADER_ONLY
+#  include "fit_plane.cpp"
+#endif
+
+#endif

+ 19 - 21
include/igl/removeUnreferenced.cpp

@@ -7,33 +7,32 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "removeUnreferenced.h"
 #include "removeUnreferenced.h"
 
 
-template <typename T, typename S>
+template <typename Scalar, typename Index>
 IGL_INLINE void igl::removeUnreferenced(
 IGL_INLINE void igl::removeUnreferenced(
-  const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V,
-  const Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> &F,
-  Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &NV,
-  Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> &NF,
-  Eigen::Matrix<S, Eigen::Dynamic, 1> &I)
+  const Eigen::PlainObjectBase<Scalar> &V,
+  const Eigen::PlainObjectBase<Index> &F,
+  Eigen::PlainObjectBase<Scalar> &NV,
+  Eigen::PlainObjectBase<Index> &NF,
+  Eigen::PlainObjectBase<Index> &I)
 {
 {
 
 
   // Mark referenced vertices
   // Mark referenced vertices
-  Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> mark = Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic>::Zero(V.rows(),1);
+  Eigen::MatrixXi mark = Eigen::MatrixXi::Zero(V.rows(),1);
   
   
   for(int i=0; i<F.rows(); ++i)
   for(int i=0; i<F.rows(); ++i)
   {
   {
     for(int j=0; j<F.cols(); ++j)
     for(int j=0; j<F.cols(); ++j)
     {
     {
       if (F(i,j) != -1)
       if (F(i,j) != -1)
-        mark(F(i,j),0) = 1;
+        mark(F(i,j)) = 1;
     }
     }
   }
   }
   
   
   // Sum the occupied cells 
   // Sum the occupied cells 
   int newsize = mark.sum();
   int newsize = mark.sum();
   
   
-  NV = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>(newsize,V.cols());
-  NF = Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic>(F.rows(),F.cols());
-  I  = Eigen::Matrix<S, Eigen::Dynamic, 1>(V.rows(),1);
+  NV.resize(newsize,V.cols());
+  I.resize(V.rows(),1);
   
   
   // Do a pass on the marked vector and remove the unreferenced vertices
   // Do a pass on the marked vector and remove the unreferenced vertices
   int count = 0;
   int count = 0;
@@ -50,18 +49,17 @@ IGL_INLINE void igl::removeUnreferenced(
       I(i) = -1;
       I(i) = -1;
     }
     }
   }
   }
-  
+
+  NF.resize(F.rows(),F.cols());
+
   // Apply I on F
   // Apply I on F
-      
-  // Why is this also removing combinatorially degenerate faces?
-  count = 0;
-  for (int i =0; i<F.rows(); ++i)
+  for (int i=0; i<F.rows(); ++i)
   {
   {
-    int v0 = I[F(i,0)];
-    int v1 = I[F(i,1)];
-    int v2 = I[F(i,2)];
-    if ( (v0 != v1) && (v2 != v1) && (v0 != v2) )
-      NF.row(count++) << v0, v1, v2;
+    Eigen::RowVectorXi t(F.cols());
+    for (int j=0; j<F.cols(); ++j)
+      t(j) = I(F(i,j));
+
+    NF.row(i) = t;
   }
   }
 }
 }
 
 

+ 7 - 10
include/igl/removeUnreferenced.h

@@ -18,7 +18,7 @@
 #include <Eigen/Core>
 #include <Eigen/Core>
 namespace igl 
 namespace igl 
 {
 {
-  // [ NV, NF ] = removeUnreferenced( V,F,epsilon )
+  // [ NV, NF ] = removeUnreferenced( V,F)
   // Remove unreferenced vertices from V, updating F accordingly
   // Remove unreferenced vertices from V, updating F accordingly
   //
   //
   // Input:
   // Input:
@@ -27,16 +27,13 @@ namespace igl
   // Output:
   // Output:
   // NV, NF: new mesh without unreferenced vertices
   // NV, NF: new mesh without unreferenced vertices
   //
   //
-  // Known bugs:
-  //   Also removes combinatorially degenerate faces in NF
-  template <typename T, typename S>
+  template <typename Scalar, typename Index>
   IGL_INLINE void removeUnreferenced(
   IGL_INLINE void removeUnreferenced(
-    const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V,
-    const Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> &F,
-    Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &NV,
-    Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> &NF,
-    Eigen::Matrix<S, Eigen::Dynamic, 1> &I);
-  
+    const Eigen::PlainObjectBase<Scalar> &V,
+    const Eigen::PlainObjectBase<Index> &F,
+    Eigen::PlainObjectBase<Scalar> &NV,
+    Eigen::PlainObjectBase<Index> &NF,
+    Eigen::PlainObjectBase<Index> &I);
 }
 }
 
 
 #ifdef IGL_HEADER_ONLY
 #ifdef IGL_HEADER_ONLY