Browse Source

Added basic mesh navigation primitives (not fully tested)

Former-commit-id: 46c21e4fe4c1f0db8dbb3978cd28acd10cacbd61
dpanozzo 13 năm trước cách đây
mục cha
commit
fe734a87bf
5 tập tin đã thay đổi với 323 bổ sung29 xóa
  1. 60 0
      adjacency_list.h
  2. 15 0
      plot_vector.h
  3. 125 0
      pos.h
  4. 72 29
      tt.h
  5. 51 0
      vf.h

+ 60 - 0
adjacency_list.h

@@ -0,0 +1,60 @@
+#ifndef IGL_ADJACENCY_MATRIX_H
+#define IGL_ADJACENCY_MATRIX_H
+
+#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
+#include <Eigen/Dense>
+#include <Eigen/Sparse>
+
+namespace igl 
+{
+  // Constructs the graph adjacency list  of a given mesh (V,F)
+  // Templates:
+  //   T  should be a eigen sparse matrix primitive type like int or double
+  // Inputs:
+  //   F  #F by dim list of mesh faces (must be triangles)
+  // Outputs: 
+  //   A  vector<vector<T> > containing at row i the adjacent vertices of vertex i
+  //
+  // Example:
+  //   // Mesh in (V,F)
+  //   vector<vector<double> > A;
+  //   adjacency_list(F,A);
+  //
+  // See also: edges, cotmatrix, diag
+  template <typename T>
+  inline void adjacency_list(
+                             const Eigen::MatrixXi & F, 
+                             vector<vector<T> >& A
+                             );
+}
+
+// Implementation
+#include "verbose.h"
+
+template <typename T>
+inline void igl::adjacency_list(
+  const Eigen::MatrixXi & F, 
+  vector<vector<T> >& A)
+{
+  A.clear(); 
+  A.resize(F.maxCoeff()+1);
+
+  // Loop over faces
+  for(int i = 0;i<F.rows();i++)
+  {
+    // Loop over this face
+    for(int j = 0;j<F.cols();j++)
+    {
+      // Get indices of edge: s --> d
+      int s = F(i,j);
+      int d = F(i,(j+1)%F.cols());
+      if (s>d)
+      {
+        A[s].push_back(d);
+        A[d].push_back(s);
+      }
+    }
+  }
+}
+
+#endif

+ 15 - 0
plot_vector.h

@@ -0,0 +1,15 @@
+#ifndef IGL_PLOT_VECTOR_H
+#define IGL_PLOT_VECTOR_H
+
+namespace igl 
+{
+  template <typename T>
+  inline void plot_vector( vector<T>& v)
+  {
+    for (int i=0; i<v.size(); ++i)
+      cerr << v[i] << " ";
+    cerr << endl;
+  }
+}
+
+#endif

+ 125 - 0
pos.h

@@ -0,0 +1,125 @@
+//
+//  IGL Lib - Simple C++ mesh library 
+//
+//  Copyright 2011, Daniele Panozzo. All rights reserved.
+
+#ifndef POS_H
+#define POS_H
+
+#include <Eigen/Core>
+#include <string>
+#include <ismanifold.h>
+
+#include <vector>
+
+namespace igl 
+{
+  // Pos - Fake halfedge for fast and easy navigation on triangle meshes with VT and TT adj
+  class Pos
+  {
+  public:
+    // Init the pos by specifying Face,Edge Index and Orientation
+    Pos(Eigen::MatrixXi* F, 
+        Eigen::MatrixXi* FF, 
+        Eigen::MatrixXi* FFi, 
+        int fi,
+        int ei,
+        bool reverse = false
+        )
+    : F(F), FF(FF), FFi(FFi), fi(fi), ei(ei), reverse(reverse)
+    {}
+
+//    // Init the pos by specifying Face,Vertex Index and Orientation
+//    Pos(Eigen::MatrixXi& F, 
+//        Eigen::MatrixXi& FF, 
+//        Eigen::MatrixXi& FFi, 
+//        int fi,
+//        int vi,
+//        bool reverse = false
+//        )
+//    : F(F), FF(FF), FFi(FFi), fi(fi), reverse(reverse)
+//    {
+//      ei = -1;
+//      for (int i=0;i<3;++i)
+//        if (F(fi,i) == vi)
+//          ei = i;
+//      assert(ei != -1);
+//      
+//      if (reverse)
+//        ei = (ei-1)%3;
+//    }
+    
+    // Change Face
+    void flipF()
+    {
+      int fin = (*FF)(fi,ei);
+      int ein = (*FFi)(fi,ei);
+      int reversen = !reverse;
+      
+      fi = fin;
+      ei = ein;
+      reverse = reversen;
+    }
+    
+    // Change Edge
+    void flipE()
+    {
+      if (!reverse)
+        ei = (ei+2)%3; // ei-1
+      else
+        ei = (ei+1)%3;
+
+      reverse = !reverse;
+    }
+    
+    // Change Vertex
+    void flipV()
+    {
+      reverse = !reverse;
+    }
+    
+    // Get vertex index
+    int Vi()
+    {
+      assert(fi >= 0);
+      assert(fi < F->rows());
+      assert(ei >= 0);
+      assert(ei <= 2);
+      
+      if (!reverse)
+        return (*F)(fi,ei);
+      else
+        return (*F)(fi,(ei+1)%3);
+    }
+    
+    // Get face index
+    int Fi()
+    {
+      return fi;
+    }
+    
+    bool operator==(Pos& p2)
+    {
+      return 
+      (
+       (fi == p2.fi) &&
+       (ei == p2.ei) &&
+       (reverse == p2.reverse) &&
+       (F   == p2.F) &&
+       (FF  == p2.FF) &&
+       (FFi == p2.FFi)
+       );
+    }
+    
+    int fi;
+    int ei;
+    bool reverse;
+    
+    Eigen::MatrixXi*     F;
+    Eigen::MatrixXi*     FF;
+    Eigen::MatrixXi*     FFi;
+  };
+  
+}
+
+#endif

+ 72 - 29
tt.h

@@ -14,37 +14,80 @@
 
 namespace igl 
 {
-    // Compute triangle-triangle adjacency
-    inline void tt(Eigen::MatrixXd& V, Eigen::MatrixXi& F, Eigen::MatrixXi& TT)
+
+  // Preprocessing
+  void tt_preprocess(Eigen::MatrixXd& V, Eigen::MatrixXi& F, std::vector<std::vector<int> >& TTT)
+  {
+    for(int f=0;f<F.rows();++f)
+      for (int i=0;i<3;++i)
+      {
+        // v1 v2 f ei 
+        int v1 = F(f,i);
+        int v2 = F(f,(i+1)%3);
+        if (v1 > v2) std::swap(v1,v2);
+        std::vector<int> r(4);
+        r[0] = v1; r[1] = v2;
+        r[2] = f;  r[3] = i;
+        TTT.push_back(r);
+      }
+    std::sort(TTT.begin(),TTT.end());
+  }
+  
+  // Extract the face adjacencies
+  void tt_extractTT(Eigen::MatrixXi& F, std::vector<std::vector<int> >& TTT, Eigen::MatrixXi& TT)
+  {
+    TT = Eigen::MatrixXi::Constant((int)(F.rows()),3,-1);
+    
+    for(int i=1;i<TTT.size();++i)
+    {
+      std::vector<int>& r1 = TTT[i-1];
+      std::vector<int>& r2 = TTT[i];
+      if ((r1[0] == r2[0]) && (r1[1] == r2[1]))
+      {
+        TT(r1[2],r1[3]) = r2[2];
+        TT(r2[2],r2[3]) = r1[2];
+      }
+    }
+  }
+  
+  // Extract the face adjacencies indices (needed for fast traversal)
+  void tt_extractTTi(Eigen::MatrixXi& F, std::vector<std::vector<int> >& TTT, Eigen::MatrixXi& TTi)
+  {
+    TTi = Eigen::MatrixXi::Constant((int)(F.rows()),3,-1);
+    
+    for(int i=1;i<TTT.size();++i)
     {
-        assert(igl::isManifold(V,F));
-        std::vector<std::vector<int> > TTT;
-        for(int f=0;f<F.rows();++f)
-            for (int i=0;i<3;++i)
-            {
-                // v1 v2 f ei 
-                int v1 = F(f,i);
-                int v2 = F(f,(i+1)%3);
-                if (v1 > v2) std::swap(v1,v2);
-                std::vector<int> r(4);
-                r[0] = v1; r[1] = v2;
-                r[2] = f;  r[3] = i;
-                TTT.push_back(r);
-            }
-        std::sort(TTT.begin(),TTT.end());
-        TT = Eigen::MatrixXi::Constant((int)(F.rows()),3,-1);
-        
-        for(int i=1;i<TTT.size();++i)
-        {
-            std::vector<int>& r1 = TTT[i-1];
-            std::vector<int>& r2 = TTT[i];
-            if ((r1[0] == r2[0]) && (r1[1] == r2[1]))
-            {
-                TT(r1[2],r1[3]) = r2[2];
-                TT(r2[2],r2[3]) = r1[2];
-            }
-        }
+      std::vector<int>& r1 = TTT[i-1];
+      std::vector<int>& r2 = TTT[i];
+      if ((r1[0] == r2[0]) && (r1[1] == r2[1]))
+      {
+        TTi(r1[2],r1[3]) = r2[3];
+        TTi(r2[2],r2[3]) = r1[3];
+      }
     }
+  }
+
+  // Compute triangle-triangle adjacency
+  inline void tt(Eigen::MatrixXd& V, Eigen::MatrixXi& F, Eigen::MatrixXi& TT)
+  {
+    assert(igl::isManifold(V,F));
+    std::vector<std::vector<int> > TTT;
+    
+    tt_preprocess(V,F,TTT);
+    tt_extractTT(F,TTT,TT);
+  }
+
+  // Compute triangle-triangle adjacency with indices
+  inline void tt(Eigen::MatrixXd& V, Eigen::MatrixXi& F, Eigen::MatrixXi& TT, Eigen::MatrixXi& TTi)
+  {
+    assert(igl::isManifold(V,F));
+    std::vector<std::vector<int> > TTT;
+    
+    tt_preprocess(V,F,TTT);
+    tt_extractTT(F,TTT,TT);
+    tt_extractTTi(F,TTT,TTi);
+  }
+
 }
 
 #endif

+ 51 - 0
vf.h

@@ -0,0 +1,51 @@
+#ifndef IGL_VF_H
+#define IGL_VF_H
+
+#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
+#include <Eigen/Dense>
+#include <Eigen/Sparse>
+
+namespace igl 
+{
+  // Constructs the vertex-face topology of a given mesh (V,F)
+  // Inputs:
+  //   V  #V by 3 list of vertex coordinates
+  //   F  #F by dim list of mesh faces (must be triangles)
+  // Outputs: 
+  //   A  vector<vector<int>> of face indices, each row i corresponding to V(i,:)
+  //
+  // See also: edges, cotmatrix, diag, vv
+    
+  template <typename T>
+  inline void vf( 
+    const Eigen::MatrixXd & V, 
+    const Eigen::MatrixXi & F, 
+    vector<vector<T> >& Al);
+}
+
+// Implementation
+#include "verbose.h"
+
+template <typename T>
+inline void igl::vf(
+  const Eigen::MatrixXd & V, 
+  const Eigen::MatrixXi & F, 
+  vector<vector<T> >& Al)
+{
+    Al.clear;
+    Al.resize(V.rows());
+    
+  // Loop over faces
+  for(int i = 0;i<F.rows();i++)
+  {
+    // Loop over this face
+    for(int j = 0;j<F.cols();j++)
+    {
+      Al[F(i,j)].push_back();
+    }
+  }
+
+  A = Eigen::SparseMatrix<T>(dyn_A);
+}
+
+#endif