polyvector_field_singularities_from_matchings.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #include <igl/polyvector_field_singularities_from_matchings.h>
  2. #include <igl/is_border_vertex.h>
  3. #include <igl/vertex_triangle_adjacency.h>
  4. #include <igl/list_to_matrix.h>
  5. #include <igl/triangle_triangle_adjacency.h>
  6. #include <igl/edge_topology.h>
  7. template <typename DerivedV, typename DerivedF, typename DerivedM, typename VFType, typename DerivedTT>
  8. void igl::polyvector_field_one_ring_matchings(const Eigen::PlainObjectBase<DerivedV> &V,
  9. const Eigen::PlainObjectBase<DerivedF> &F,
  10. const std::vector<std::vector<VFType> >& VF,
  11. const Eigen::MatrixXi& E2F,
  12. const Eigen::MatrixXi& F2E,
  13. const Eigen::PlainObjectBase<DerivedTT>& TT,
  14. const Eigen::PlainObjectBase<DerivedM> &match_ab,
  15. const Eigen::PlainObjectBase<DerivedM> &match_ba,
  16. const int vi,
  17. Eigen::MatrixXi &mvi,
  18. Eigen::VectorXi &fi)
  19. {
  20. int half_degree = match_ab.cols();
  21. mvi.resize(VF[vi].size()+1,half_degree);
  22. fi.resize(VF[vi].size()+1,1);
  23. //start from one face
  24. const int fstart = VF[vi][0];
  25. int current_face = fstart;
  26. int i =0;
  27. fi[i] = current_face;
  28. for (int j=0; j<half_degree; ++j)
  29. mvi(i,j) = j;
  30. int next_face = -1;
  31. while (next_face != fstart)
  32. {
  33. // look for the vertex
  34. int j=-1;
  35. for (unsigned z=0; z<3; ++z)
  36. if (F(current_face,z) == vi)
  37. j=z;
  38. assert(j!=-1);
  39. next_face = TT(current_face, j);
  40. ++i;
  41. // look at the edge between the two faces
  42. const int &current_edge = F2E(current_face,j);
  43. for (int k=0; k<half_degree; ++k)
  44. {
  45. // check its orientation to determine whether match_ab or match_ba should be used
  46. if ((E2F(current_edge,0) == current_face) &&
  47. (E2F(current_edge,1) == next_face) )
  48. {
  49. //look at match_ab
  50. mvi(i,k) = match_ab(current_edge,(mvi(i-1,k))%half_degree);
  51. }
  52. else
  53. {
  54. assert((E2F(current_edge,1) == current_face) &&
  55. (E2F(current_edge,0) == next_face));
  56. //look at match_ba
  57. mvi(i,k) = match_ba(current_edge,(mvi(i-1,k))%half_degree);
  58. }
  59. if (mvi(i-1,k)>=half_degree)
  60. mvi(i,k) = (mvi(i,k)+half_degree)%(2*half_degree);
  61. }
  62. current_face = next_face;
  63. fi[i] = current_face;
  64. }
  65. }
  66. template <typename DerivedV, typename DerivedF, typename DerivedM, typename DerivedS>
  67. IGL_INLINE void igl::polyvector_field_singularities_from_matchings(
  68. const Eigen::PlainObjectBase<DerivedV> &V,
  69. const Eigen::PlainObjectBase<DerivedF> &F,
  70. const Eigen::PlainObjectBase<DerivedM> &match_ab,
  71. const Eigen::PlainObjectBase<DerivedM> &match_ba,
  72. Eigen::PlainObjectBase<DerivedS> &singularities)
  73. {
  74. std::vector<bool> V_border = igl::is_border_vertex(V,F);
  75. std::vector<std::vector<int> > VF, VFi;
  76. igl::vertex_triangle_adjacency(V,F,VF,VFi);
  77. Eigen::MatrixXi TT, TTi;
  78. igl::triangle_triangle_adjacency(F,TT,TTi);
  79. Eigen::MatrixXi E, E2F, F2E;
  80. igl::edge_topology(V,F,E,F2E,E2F);
  81. igl::polyvector_field_singularities_from_matchings(V, F, V_border, VF, TT, E2F, F2E, match_ab, match_ba, singularities);
  82. }
  83. template <typename DerivedV, typename DerivedF, typename DerivedM, typename VFType, typename DerivedS>
  84. IGL_INLINE void igl::polyvector_field_singularities_from_matchings(
  85. const Eigen::PlainObjectBase<DerivedV> &V,
  86. const Eigen::PlainObjectBase<DerivedF> &F,
  87. const std::vector<bool> &V_border,
  88. const std::vector<std::vector<VFType> > &VF,
  89. const Eigen::MatrixXi &TT,
  90. const Eigen::MatrixXi &E2F,
  91. const Eigen::MatrixXi &F2E,
  92. const Eigen::PlainObjectBase<DerivedM> &match_ab,
  93. const Eigen::PlainObjectBase<DerivedM> &match_ba,
  94. Eigen::PlainObjectBase<DerivedS> &singularities)
  95. {
  96. int numV = V.rows();
  97. std::vector<int> singularities_v;
  98. int half_degree = match_ab.cols();
  99. for (int vi =0; vi<numV; ++vi)
  100. {
  101. ///check that is on border..
  102. if (V_border[vi])
  103. continue;
  104. Eigen::VectorXi fi;
  105. Eigen::MatrixXi mvi;
  106. igl::polyvector_field_one_ring_matchings(V, F, VF, E2F, F2E, TT, match_ab, match_ba, vi, mvi, fi);
  107. int num = fi.size();
  108. //pick one of the vectors to check for singularities
  109. for (int vector_to_match = 0; vector_to_match < half_degree; ++vector_to_match)
  110. {
  111. if(mvi(num-1,vector_to_match) != mvi(0,vector_to_match))
  112. {
  113. singularities_v.push_back(vi);
  114. break;
  115. }
  116. }
  117. }
  118. std::sort(singularities_v.begin(), singularities_v.end());
  119. auto last = std::unique(singularities_v.begin(), singularities_v.end());
  120. singularities_v.erase(last, singularities_v.end());
  121. igl::list_to_matrix(singularities_v, singularities);
  122. }
  123. template <typename DerivedV, typename DerivedF, typename DerivedM, typename DerivedS>
  124. IGL_INLINE void igl::polyvector_field_singularities_from_matchings(
  125. const Eigen::PlainObjectBase<DerivedV> &V,
  126. const Eigen::PlainObjectBase<DerivedF> &F,
  127. const Eigen::PlainObjectBase<DerivedM> &match_ab,
  128. const Eigen::PlainObjectBase<DerivedM> &match_ba,
  129. Eigen::PlainObjectBase<DerivedS> &singularities,
  130. Eigen::PlainObjectBase<DerivedS> &singularity_indices)
  131. {
  132. std::vector<bool> V_border = igl::is_border_vertex(V,F);
  133. std::vector<std::vector<int> > VF, VFi;
  134. igl::vertex_triangle_adjacency(V,F,VF,VFi);
  135. Eigen::MatrixXi TT, TTi;
  136. igl::triangle_triangle_adjacency(V,F,TT,TTi);
  137. Eigen::MatrixXi E, E2F, F2E;
  138. igl::edge_topology(V,F,E,F2E,E2F);
  139. igl::polyvector_field_singularities_from_matchings(V, F, V_border, VF, TT, E2F, F2E, match_ab, match_ba, singularities, singularity_indices);
  140. }
  141. template <typename DerivedV, typename DerivedF, typename DerivedM, typename VFType, typename DerivedS>
  142. IGL_INLINE void igl::polyvector_field_singularities_from_matchings(
  143. const Eigen::PlainObjectBase<DerivedV> &V,
  144. const Eigen::PlainObjectBase<DerivedF> &F,
  145. const std::vector<bool> &V_border,
  146. const std::vector<std::vector<VFType> > &VF,
  147. const Eigen::MatrixXi &TT,
  148. const Eigen::MatrixXi &E2F,
  149. const Eigen::MatrixXi &F2E,
  150. const Eigen::PlainObjectBase<DerivedM> &match_ab,
  151. const Eigen::PlainObjectBase<DerivedM> &match_ba,
  152. Eigen::PlainObjectBase<DerivedS> &singularities,
  153. Eigen::PlainObjectBase<DerivedS> &singularity_indices)
  154. {
  155. igl::polyvector_field_singularities_from_matchings(V, F, V_border, VF, TT, E2F, F2E, match_ab, match_ba, singularities);
  156. singularity_indices.setZero(singularities.size(), 1);
  157. //get index from first vector only
  158. int vector_to_match = 0;
  159. for (int i =0; i<singularities.size(); ++i)
  160. {
  161. int vi = singularities[i];
  162. Eigen::VectorXi mvi,fi;
  163. igl::polyvector_field_one_ring_matchings(V, F, VF, E2F, F2E, TT, match_ab, match_ba, vi, vector_to_match, mvi, fi);
  164. singularity_indices[i] = (mvi.tail(1)[0] - vector_to_match);
  165. }
  166. }
  167. #ifdef IGL_STATIC_LIBRARY
  168. // Explicit template specialization
  169. template void igl::polyvector_field_one_ring_matchings<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, int, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, Eigen::Matrix<int, -1, -1, 0, -1, -1>&, Eigen::Matrix<int, -1, 1, 0, -1, 1>&);
  170. template void igl::polyvector_field_singularities_from_matchings<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, int, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::__1::vector<bool, std::__1::allocator<bool> > const&, std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  171. //template void igl::polyvector_field_singularities_from_matchings<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, int, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<bool, std::allocator<bool> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  172. //template void igl::polyvector_field_singularities_from_matchings<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  173. //template void igl::polyvector_field_singularities_from_matchings<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, 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> >&);
  174. #endif