polyvector_field_singularities_from_matchings.cpp 10 KB

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