adjacency_list.cpp 3.5 KB

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