adjacency_list.cpp 4.4 KB

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