Przeglądaj źródła

updated template types in removeUnreference and fixed a minor bug
add fit_plane


Former-commit-id: 31bb32a665be3fdeb6fa0dcd09b9baf38c3b261e

Daniele Panozzo 11 lat temu
rodzic
commit
5e6a231f3f

+ 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

+ 80 - 21
include/igl/removeUnreferenced.cpp

@@ -7,33 +7,33 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "removeUnreferenced.h"
 
-template <typename T, typename S>
+template <typename Scalar, typename Index>
 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
-  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 j=0; j<F.cols(); ++j)
     {
       if (F(i,j) != -1)
-        mark(F(i,j),0) = 1;
+        mark(F(i,j)) = 1;
     }
   }
   
   // Sum the occupied cells 
   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
   int count = 0;
@@ -50,21 +50,80 @@ IGL_INLINE void igl::removeUnreferenced(
       I(i) = -1;
     }
   }
-  
+
+  NF.resize(F.rows(),F.cols());
+
   // 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;
   }
 }
 
+// template <typename T, typename S>
+//  IGL_INLINE void removeUnreferenced(
+//    const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V,
+//    const vector<vector<S> > &F,
+//    Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &NV,
+//    const vector<vector<S> > &NF,
+//    Eigen::Matrix<S, Eigen::Dynamic, 1> &I)
+//{
+//  // Mark referenced vertices
+//  Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> mark = Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic>::Zero(V.rows(),1);
+//  
+//  for(int i=0; i<F.size(); ++i)
+//  {
+//    for(int j=0; j<F[i].size(); ++j)
+//    {
+//      if (F[i][j] != -1)
+//        mark(F[i][j],0) = 1;
+//    }
+//  }
+//  
+//  // Sum the occupied cells 
+//  int newsize = mark.sum();
+//  
+//  NV = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>(newsize,V.cols());
+//  NF.clear();
+//  I  = Eigen::Matrix<S, Eigen::Dynamic, 1>(V.rows(),1);
+//  
+//  // Do a pass on the marked vector and remove the unreferenced vertices
+//  int count = 0;
+//  for(int i=0;i<mark.rows();++i)
+//  {
+//    if (mark(i) == 1)
+//    {
+//      NV.row(count) = V.row(i);
+//      I(i) = count;
+//      count++;
+//    }
+//    else
+//    {
+//      I(i) = -1;
+//    }
+//  }
+//  
+//  // Apply I on F
+//  for (int i=0; i<F.size(); ++i)
+//  {
+//    vector<S> t;
+//    for (int j=0; j<F[i].size(); ++j)
+//      t.push_back(I[F[i][j]]);
+//
+//    vector<S> t_copy = t;
+//    typename std::vector<S>::iterator it;
+//    it = std::unique (t_copy.begin(), t_copy.end()); 
+//    t_copy.resize( std::distance(t_copy.begin(),it) );
+//
+//    if (t_copy.size() > 2)
+//      NF.push_back(t);
+//  }
+//}
+
 #ifndef IGL_HEADER_ONLY
 // Explicit template specialization
 #endif

+ 16 - 8
include/igl/removeUnreferenced.h

@@ -27,15 +27,23 @@ namespace igl
   // Output:
   // 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(
-    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
+
+                                     );
+ 
+// template <typename T, typename S>
+//  IGL_INLINE void removeUnreferenced(
+//    const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V,
+//    const vector<vector<S> > &F,
+//    Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &NV,
+//    const vector<vector<S> > &NF,
+//    Eigen::Matrix<S, Eigen::Dynamic, 1> &I);
   
 }