adjacency_list.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #ifndef IGL_ADJACENCY_LIST_H
  2. #define IGL_ADJACENCY_LIST_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. // Implementation
  31. #include "verbose.h"
  32. template <typename T, typename M>
  33. inline void igl::adjacency_list(
  34. const M & F,
  35. std::vector<std::vector<T> >& A,
  36. bool sorted)
  37. {
  38. A.clear();
  39. A.resize(F.maxCoeff()+1);
  40. // Loop over faces
  41. for(int i = 0;i<F.rows();i++)
  42. {
  43. // Loop over this face
  44. for(int j = 0;j<F.cols();j++)
  45. {
  46. // Get indices of edge: s --> d
  47. int s = F(i,j);
  48. int d = F(i,(j+1)%F.cols());
  49. A.at(s).push_back(d);
  50. A.at(d).push_back(s);
  51. }
  52. }
  53. // Remove duplicates
  54. for(int i=0; i<(int)A.size();++i)
  55. {
  56. std::sort(A[i].begin(), A[i].end());
  57. A[i].erase(std::unique(A[i].begin(), A[i].end()), A[i].end());
  58. }
  59. // If needed, sort every VV
  60. if (sorted)
  61. {
  62. // Loop over faces
  63. // for every vertex v store a set of ordered edges not incident to v that belongs to triangle incident on v.
  64. std::vector<std::vector<std::vector<int> > > SR;
  65. SR.resize(A.size());
  66. for(int i = 0;i<F.rows();i++)
  67. {
  68. // Loop over this face
  69. for(int j = 0;j<F.cols();j++)
  70. {
  71. // Get indices of edge: s --> d
  72. int s = F(i,j);
  73. int d = F(i,(j+1)%F.cols());
  74. // Get index of opposing vertex v
  75. int v = F(i,(j+2)%F.cols());
  76. std::vector<int> e(2);
  77. e[0] = d;
  78. e[1] = v;
  79. SR[s].push_back(e);
  80. }
  81. }
  82. for(int v=0; v<(int)SR.size();++v)
  83. {
  84. std::vector<int>& vv = A.at(v);
  85. std::vector<std::vector<int> >& sr = SR[v];
  86. std::vector<std::vector<int> > pn = sr;
  87. // Compute previous/next for every element in sr
  88. for(int i=0;i<(int)sr.size();++i)
  89. {
  90. int a = sr[i][0];
  91. int b = sr[i][1];
  92. // search for previous
  93. int p = -1;
  94. for(int j=0;j<(int)sr.size();++j)
  95. if(sr[j][1] == a)
  96. p = j;
  97. pn[i][0] = p;
  98. // search for next
  99. int n = -1;
  100. for(int j=0;j<(int)sr.size();++j)
  101. if(sr[j][0] == b)
  102. n = j;
  103. pn[i][1] = n;
  104. }
  105. // assume manifoldness (look for beginning of a single chain)
  106. int c = 0;
  107. for(int j=0; j<=(int)sr.size();++j)
  108. if (pn[c][0] != -1)
  109. c = pn[c][0];
  110. if (pn[c][0] == -1) // border case
  111. {
  112. // finally produce the new vv relation
  113. for(int j=0; j<(int)sr.size();++j)
  114. {
  115. vv[j] = sr[c][0];
  116. if (pn[c][1] != -1)
  117. c = pn[c][1];
  118. }
  119. vv.back() = sr[c][1];
  120. }
  121. else
  122. {
  123. // finally produce the new vv relation
  124. for(int j=0; j<(int)sr.size();++j)
  125. {
  126. vv[j] = sr[c][0];
  127. c = pn[c][1];
  128. }
  129. }
  130. }
  131. }
  132. }
  133. #endif