소스 검색

adjacency list can now produce sorted result

Former-commit-id: 90a142cc9547ffc9dacd7cfd16a1bd49b6448560
dpanozzo 13 년 전
부모
커밋
fd64e40548
1개의 변경된 파일99개의 추가작업 그리고 9개의 파일을 삭제
  1. 99 9
      adjacency_list.h

+ 99 - 9
adjacency_list.h

@@ -4,14 +4,15 @@
 #define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
 #include <Eigen/Dense>
 #include <Eigen/Sparse>
-
+#include <plot_vector.h>
 namespace igl 
 {
-  // Constructs the graph adjacency list  of a given mesh (V,F)
+  // 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)
+  //   F       #F by dim list of mesh faces (must be triangles)
+  //   sorted  flag that indicates if the list should be sorted counter-clockwise
   // Outputs: 
   //   A  vector<vector<T> > containing at row i the adjacent vertices of vertex i
   //
@@ -24,7 +25,8 @@ namespace igl
   template <typename T>
   inline void adjacency_list(
                              const Eigen::MatrixXi & F, 
-                             std::vector<std::vector<T> >& A
+                             std::vector<std::vector<T> >& A,
+                             bool sorted = false
                              );
 }
 
@@ -33,12 +35,14 @@ namespace igl
 
 template <typename T>
 inline void igl::adjacency_list(
-  const Eigen::MatrixXi & F, 
-  std::vector<std::vector<T> >& A)
+                                const Eigen::MatrixXi & F, 
+                                std::vector<std::vector<T> >& A,
+                                bool sorted 
+                                )
 {
   A.clear(); 
   A.resize(F.maxCoeff()+1);
-
+  
   // Loop over faces
   for(int i = 0;i<F.rows();i++)
   {
@@ -48,8 +52,8 @@ inline void igl::adjacency_list(
       // Get indices of edge: s --> d
       int s = F(i,j);
       int d = F(i,(j+1)%F.cols());
-      A[s].push_back(d);
-      A[d].push_back(s);
+      A.at(s).push_back(d);
+      A.at(d).push_back(s);
     }
   }
   
@@ -59,6 +63,92 @@ inline void igl::adjacency_list(
     std::sort(A[i].begin(), A[i].end());
     A[i].erase(std::unique(A[i].begin(), A[i].end()), A[i].end());
   }
+  
+  // If needed, sort every VV
+  if (sorted)
+  {
+	  // Loop over faces
+	  
+	  // for every vertex v store a set of ordered edges not incident to v that belongs to triangle incident on v.
+    std::vector<std::vector<std::vector<int> > > SR; 
+	  SR.resize(A.size());
+	  
+	  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());
+        // Get index of opposing vertex v
+        int v = F(i,(j+2)%F.cols());
+        
+        std::vector<int> e(2);
+        e[0] = d;
+        e[1] = v;
+        SR[s].push_back(e);
+      }
+	  }
+	  
+    for(int v=0; v<SR.size();++v)
+    {
+      std::vector<int>& vv = A.at(v);
+      std::vector<std::vector<int> >& sr = SR[v];
+      
+      std::vector<std::vector<int> > pn = sr;
+      
+      // Compute previous/next for every element in sr
+      for(int i=0;i<sr.size();++i)
+      {
+        int a = sr[i][0];
+        int b = sr[i][1];
+        
+        // search for previous
+        int p = -1;
+        for(int j=0;j<sr.size();++j)
+          if(sr[j][1] == a)
+            p = j;
+        pn[i][0] = p;
+        
+        // search for next
+        int n = -1;
+        for(int j=0;j<sr.size();++j)
+          if(sr[j][0] == b)
+            n = j;
+        pn[i][1] = n;
+        
+      }
+      
+      // assume manifoldness (look for beginning of a single chain)
+      int c = 0;
+      for(int j=0; j<=sr.size();++j)
+        if (pn[c][0] != -1)
+          c = pn[c][0];
+      
+      if (pn[c][0] == -1) // border case
+      {
+        // finally produce the new vv relation
+        for(int j=0; j<sr.size();++j)
+        {
+          vv[j] = sr[c][0];
+          if (pn[c][1] != -1)
+            c = pn[c][1];
+        }
+        vv.back() = sr[c][1];
+      }
+      else
+      {
+        // finally produce the new vv relation
+        for(int j=0; j<sr.size();++j)
+        {
+          vv[j] = sr[c][0];
+          
+          c = pn[c][1];
+        }
+      }
+    }
+  }
 }
 
 #endif