adjacency_list.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #ifndef IGL_ADJACENCY_MATRIX_H
  2. #define IGL_ADJACENCY_MATRIX_H
  3. #define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
  4. #include <Eigen/Dense>
  5. #include <Eigen/Sparse>
  6. //#include <plot_vector.h>
  7. namespace igl
  8. {
  9. // Constructs the graph adjacency list of a given mesh (V,F)
  10. // Templates:
  11. // T should be a eigen sparse matrix primitive type like int or double
  12. // Inputs:
  13. // F #F by dim list of mesh faces (must be triangles)
  14. // sorted flag that indicates if the list should be sorted counter-clockwise
  15. // Outputs:
  16. // A vector<vector<T> > containing at row i the adjacent vertices of vertex i
  17. //
  18. // Example:
  19. // // Mesh in (V,F)
  20. // vector<vector<double> > A;
  21. // adjacency_list(F,A);
  22. //
  23. // See also: edges, cotmatrix, diag
  24. template <typename T, typename M>
  25. inline void adjacency_list(
  26. const M & F,
  27. std::vector<std::vector<T> >& A,
  28. bool sorted = false
  29. );
  30. }
  31. // Implementation
  32. #include "verbose.h"
  33. template <typename T, typename M>
  34. inline void igl::adjacency_list(
  35. const M & F,
  36. std::vector<std::vector<T> >& A,
  37. bool sorted
  38. )
  39. {
  40. A.clear();
  41. A.resize(F.maxCoeff()+1);
  42. // Loop over faces
  43. for(int i = 0;i<F.rows();i++)
  44. {
  45. // Loop over this face
  46. for(int j = 0;j<F.cols();j++)
  47. {
  48. // Get indices of edge: s --> d
  49. int s = F(i,j);
  50. int d = F(i,(j+1)%F.cols());
  51. A.at(s).push_back(d);
  52. A.at(d).push_back(s);
  53. }
  54. }
  55. // Remove duplicates
  56. for(int i=0; i<A.size();++i)
  57. {
  58. std::sort(A[i].begin(), A[i].end());
  59. A[i].erase(std::unique(A[i].begin(), A[i].end()), A[i].end());
  60. }
  61. // If needed, sort every VV
  62. if (sorted)
  63. {
  64. // Loop over faces
  65. // for every vertex v store a set of ordered edges not incident to v that belongs to triangle incident on v.
  66. std::vector<std::vector<std::vector<int> > > SR;
  67. SR.resize(A.size());
  68. for(int i = 0;i<F.rows();i++)
  69. {
  70. // Loop over this face
  71. for(int j = 0;j<F.cols();j++)
  72. {
  73. // Get indices of edge: s --> d
  74. int s = F(i,j);
  75. int d = F(i,(j+1)%F.cols());
  76. // Get index of opposing vertex v
  77. int v = F(i,(j+2)%F.cols());
  78. std::vector<int> e(2);
  79. e[0] = d;
  80. e[1] = v;
  81. SR[s].push_back(e);
  82. }
  83. }
  84. for(int v=0; v<SR.size();++v)
  85. {
  86. std::vector<int>& vv = A.at(v);
  87. std::vector<std::vector<int> >& sr = SR[v];
  88. std::vector<std::vector<int> > pn = sr;
  89. // Compute previous/next for every element in sr
  90. for(int i=0;i<sr.size();++i)
  91. {
  92. int a = sr[i][0];
  93. int b = sr[i][1];
  94. // search for previous
  95. int p = -1;
  96. for(int j=0;j<sr.size();++j)
  97. if(sr[j][1] == a)
  98. p = j;
  99. pn[i][0] = p;
  100. // search for next
  101. int n = -1;
  102. for(int j=0;j<sr.size();++j)
  103. if(sr[j][0] == b)
  104. n = j;
  105. pn[i][1] = n;
  106. }
  107. // assume manifoldness (look for beginning of a single chain)
  108. int c = 0;
  109. for(int j=0; j<=sr.size();++j)
  110. if (pn[c][0] != -1)
  111. c = pn[c][0];
  112. if (pn[c][0] == -1) // border case
  113. {
  114. // finally produce the new vv relation
  115. for(int j=0; j<sr.size();++j)
  116. {
  117. vv[j] = sr[c][0];
  118. if (pn[c][1] != -1)
  119. c = pn[c][1];
  120. }
  121. vv.back() = sr[c][1];
  122. }
  123. else
  124. {
  125. // finally produce the new vv relation
  126. for(int j=0; j<sr.size();++j)
  127. {
  128. vv[j] = sr[c][0];
  129. c = pn[c][1];
  130. }
  131. }
  132. }
  133. }
  134. }
  135. #endif