triangle_triangle_adjacency.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 Daniele Panozzo <daniele.panozzo@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 "triangle_triangle_adjacency.h"
  9. #include "parallel_for.h"
  10. #include "unique_edge_map.h"
  11. #include <algorithm>
  12. #include <iostream>
  13. // Extract the face adjacencies
  14. template <typename DerivedF, typename TTT_type, typename DerivedTT>
  15. IGL_INLINE void igl::triangle_triangle_adjacency_extractTT(
  16. const Eigen::PlainObjectBase<DerivedF>& F,
  17. std::vector<std::vector<TTT_type> >& TTT,
  18. Eigen::PlainObjectBase<DerivedTT>& TT)
  19. {
  20. TT.setConstant((int)(F.rows()),F.cols(),-1);
  21. for(int i=1;i<(int)TTT.size();++i)
  22. {
  23. std::vector<int>& r1 = TTT[i-1];
  24. std::vector<int>& r2 = TTT[i];
  25. if ((r1[0] == r2[0]) && (r1[1] == r2[1]))
  26. {
  27. TT(r1[2],r1[3]) = r2[2];
  28. TT(r2[2],r2[3]) = r1[2];
  29. }
  30. }
  31. }
  32. template <typename DerivedF, typename DerivedTT>
  33. IGL_INLINE void igl::triangle_triangle_adjacency(
  34. const Eigen::PlainObjectBase<DerivedF>& F,
  35. Eigen::PlainObjectBase<DerivedTT>& TT)
  36. {
  37. DerivedTT TTi;
  38. return triangle_triangle_adjacency(F,TT,TTi);
  39. }
  40. template <typename DerivedF, typename TTT_type>
  41. IGL_INLINE void igl::triangle_triangle_adjacency_preprocess(
  42. const Eigen::PlainObjectBase<DerivedF>& F,
  43. std::vector<std::vector<TTT_type> >& TTT)
  44. {
  45. for(int f=0;f<F.rows();++f)
  46. for (int i=0;i<F.cols();++i)
  47. {
  48. // v1 v2 f ei
  49. int v1 = F(f,i);
  50. int v2 = F(f,(i+1)%F.cols());
  51. if (v1 > v2) std::swap(v1,v2);
  52. std::vector<int> r(4);
  53. r[0] = v1; r[1] = v2;
  54. r[2] = f; r[3] = i;
  55. TTT.push_back(r);
  56. }
  57. std::sort(TTT.begin(),TTT.end());
  58. }
  59. // Extract the face adjacencies indices (needed for fast traversal)
  60. template <typename DerivedF, typename TTT_type, typename DerivedTTi>
  61. IGL_INLINE void igl::triangle_triangle_adjacency_extractTTi(
  62. const Eigen::PlainObjectBase<DerivedF>& F,
  63. std::vector<std::vector<TTT_type> >& TTT,
  64. Eigen::PlainObjectBase<DerivedTTi>& TTi)
  65. {
  66. TTi.setConstant((int)(F.rows()),F.cols(),-1);
  67. for(int i=1;i<(int)TTT.size();++i)
  68. {
  69. std::vector<int>& r1 = TTT[i-1];
  70. std::vector<int>& r2 = TTT[i];
  71. if ((r1[0] == r2[0]) && (r1[1] == r2[1]))
  72. {
  73. TTi(r1[2],r1[3]) = r2[3];
  74. TTi(r2[2],r2[3]) = r1[3];
  75. }
  76. }
  77. }
  78. // Compute triangle-triangle adjacency with indices
  79. template <typename DerivedF, typename DerivedTT, typename DerivedTTi>
  80. IGL_INLINE void igl::triangle_triangle_adjacency(
  81. const Eigen::PlainObjectBase<DerivedF>& F,
  82. Eigen::PlainObjectBase<DerivedTT>& TT,
  83. Eigen::PlainObjectBase<DerivedTTi>& TTi)
  84. {
  85. std::vector<std::vector<int> > TTT;
  86. triangle_triangle_adjacency_preprocess(F,TTT);
  87. triangle_triangle_adjacency_extractTT(F,TTT,TT);
  88. triangle_triangle_adjacency_extractTTi(F,TTT,TTi);
  89. }
  90. template <
  91. typename DerivedF,
  92. typename TTIndex,
  93. typename TTiIndex>
  94. IGL_INLINE void igl::triangle_triangle_adjacency(
  95. const Eigen::PlainObjectBase<DerivedF> & F,
  96. std::vector<std::vector<std::vector<TTIndex> > > & TT,
  97. std::vector<std::vector<std::vector<TTiIndex> > > & TTi)
  98. {
  99. return triangle_triangle_adjacency(F,true,TT,TTi);
  100. }
  101. template <
  102. typename DerivedF,
  103. typename TTIndex>
  104. IGL_INLINE void igl::triangle_triangle_adjacency(
  105. const Eigen::PlainObjectBase<DerivedF> & F,
  106. std::vector<std::vector<std::vector<TTIndex> > > & TT)
  107. {
  108. std::vector<std::vector<std::vector<TTIndex> > > not_used;
  109. return triangle_triangle_adjacency(F,false,TT,not_used);
  110. }
  111. template <
  112. typename DerivedF,
  113. typename TTIndex,
  114. typename TTiIndex>
  115. IGL_INLINE void igl::triangle_triangle_adjacency(
  116. const Eigen::PlainObjectBase<DerivedF> & F,
  117. const bool construct_TTi,
  118. std::vector<std::vector<std::vector<TTIndex> > > & TT,
  119. std::vector<std::vector<std::vector<TTiIndex> > > & TTi)
  120. {
  121. using namespace Eigen;
  122. using namespace std;
  123. assert(F.cols() == 3 && "Faces must be triangles");
  124. // number of faces
  125. typedef typename DerivedF::Index Index;
  126. typedef Matrix<typename DerivedF::Scalar,Dynamic,2> MatrixX2I;
  127. typedef Matrix<typename DerivedF::Index,Dynamic,1> VectorXI;
  128. MatrixX2I E,uE;
  129. VectorXI EMAP;
  130. vector<vector<Index> > uE2E;
  131. unique_edge_map(F,E,uE,EMAP,uE2E);
  132. return triangle_triangle_adjacency(E,EMAP,uE2E,construct_TTi,TT,TTi);
  133. }
  134. template <
  135. typename DerivedE,
  136. typename DerivedEMAP,
  137. typename uE2EType,
  138. typename TTIndex,
  139. typename TTiIndex>
  140. IGL_INLINE void igl::triangle_triangle_adjacency(
  141. const Eigen::PlainObjectBase<DerivedE> & E,
  142. const Eigen::PlainObjectBase<DerivedEMAP> & EMAP,
  143. const std::vector<std::vector<uE2EType> > & uE2E,
  144. const bool construct_TTi,
  145. std::vector<std::vector<std::vector<TTIndex> > > & TT,
  146. std::vector<std::vector<std::vector<TTiIndex> > > & TTi)
  147. {
  148. using namespace std;
  149. using namespace Eigen;
  150. typedef typename DerivedE::Index Index;
  151. const size_t m = E.rows()/3;
  152. assert((size_t)E.rows() == m*3 && "E should come from list of triangles.");
  153. // E2E[i] --> {j,k,...} means face edge i corresponds to other faces edges j
  154. // and k
  155. TT.resize (m,vector<vector<TTIndex> >(3));
  156. if(construct_TTi)
  157. {
  158. TTi.resize(m,vector<vector<TTiIndex> >(3));
  159. }
  160. // No race conditions because TT*[f][c]'s are in bijection with e's
  161. // Minimum number of items per thread
  162. //const size_t num_e = E.rows();
  163. // Slightly better memory access than loop over E
  164. igl::parallel_for(
  165. m,
  166. [&](const Index & f)
  167. {
  168. for(Index c = 0;c<3;c++)
  169. {
  170. const Index e = f + m*c;
  171. //const Index c = e/m;
  172. const vector<uE2EType> & N = uE2E[EMAP(e)];
  173. for(const auto & ne : N)
  174. {
  175. const Index nf = ne%m;
  176. // don't add self
  177. if(nf != f)
  178. {
  179. TT[f][c].push_back(nf);
  180. if(construct_TTi)
  181. {
  182. const Index nc = ne/m;
  183. TTi[f][c].push_back(nc);
  184. }
  185. }
  186. }
  187. }
  188. },
  189. 1000ul);
  190. }
  191. #ifdef IGL_STATIC_LIBRARY
  192. // Explicit template instantiation
  193. // generated by autoexplicit.sh
  194. template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  195. // generated by autoexplicit.sh
  196. template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, 3, 0, -1, 3>, int>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >, std::allocator<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > > >&);
  197. // generated by autoexplicit.sh
  198. template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  199. // generated by autoexplicit.sh
  200. template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
  201. template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  202. template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, long, long, long>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > const&, bool, std::vector<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >, std::allocator<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > > >&, std::vector<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >, std::allocator<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > > >&);
  203. template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, unsigned long, int, int>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, bool, std::vector<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >, std::allocator<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > > >&, std::vector<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >, std::allocator<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > > >&);
  204. template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
  205. template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, -1, 0, -1, -1>, long, long>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >, std::allocator<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > > >&, std::vector<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >, std::allocator<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > > >&);
  206. template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, -1, 0, -1, -1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >, std::allocator<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > > >&);
  207. #endif