polyvector_field_comb_from_matchings_and_cuts.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include <igl/colon.h>
  2. #include <algorithm>
  3. #include <deque>
  4. #include <igl/polyvector_field_comb_from_matchings_and_cuts.h>
  5. #include <igl/edge_topology.h>
  6. #include <igl/triangle_triangle_adjacency.h>
  7. template <typename DerivedV, typename DerivedF, typename DerivedTT, typename DerivedS, typename DerivedM, typename DerivedC>
  8. IGL_INLINE void igl::polyvector_field_comb_from_matchings_and_cuts(
  9. const Eigen::PlainObjectBase<DerivedV> &V,
  10. const Eigen::PlainObjectBase<DerivedF> &F,
  11. const Eigen::PlainObjectBase<DerivedTT> &TT,
  12. const Eigen::MatrixXi &E2F,
  13. const Eigen::MatrixXi &F2E,
  14. const Eigen::PlainObjectBase<DerivedS> &sol3D,
  15. const Eigen::PlainObjectBase<DerivedM> &match_ab,
  16. const Eigen::PlainObjectBase<DerivedM> &match_ba,
  17. const Eigen::PlainObjectBase<DerivedC> &cuts,
  18. Eigen::PlainObjectBase<DerivedS> &sol3D_combed)
  19. {
  20. int half_degree = sol3D.cols()/3;
  21. int full_degree = 2*half_degree;
  22. Eigen::MatrixXi used; used.setConstant(F.rows(),half_degree,-1);
  23. // Eigen::VectorXi mark;
  24. std::deque<int> d;
  25. sol3D_combed.setZero(sol3D.rows(), sol3D.cols());
  26. int start = 0;
  27. d.push_back(start);
  28. used.row(start) = igl::colon<int>(0, half_degree-1);
  29. sol3D_combed.row(start) = sol3D.row(start);
  30. while (!d.empty())
  31. {
  32. int f0 = d.at(0);
  33. d.pop_front();
  34. for (int k=0; k<3; k++)
  35. {
  36. int f1 = TT(f0,k);
  37. if (f1==-1) continue;
  38. //do not comb across cuts
  39. if ((used.row(f1).array()!=-1).any()||cuts(f0,k))
  40. continue;
  41. // look at the edge between the two faces
  42. const int &current_edge = F2E(f0,k);
  43. // check its orientation to determine whether match_ab or match_ba should be used
  44. if ((E2F(current_edge,0) == f0) &&
  45. (E2F(current_edge,1) == f1) )
  46. {
  47. //look at match_ab
  48. for(int i=0; i<half_degree; ++i)
  49. {
  50. int ii = used(f0,i);
  51. used(f1,i) = (match_ab(current_edge,ii%half_degree) + (ii>=half_degree)*half_degree)%full_degree;
  52. }
  53. }
  54. else
  55. {
  56. assert((E2F(current_edge,1) == f0) &&
  57. (E2F(current_edge,0) == f1));
  58. //look at match_ba
  59. for(int i=0; i<half_degree; ++i)
  60. {
  61. int ii = used(f0,i);
  62. used(f1,i) = (match_ba(current_edge,ii%half_degree)+ (ii>=half_degree)*half_degree)%full_degree;
  63. }
  64. }
  65. for (int i = 0; i<half_degree; ++i)
  66. {
  67. int sign = (used(f1,i)<half_degree)?1:-1;
  68. sol3D_combed.block(f1,i*3,1,3) = sign*sol3D.block(f1,(used(f1,i)%half_degree)*3,1,3);
  69. }
  70. d.push_back(f1);
  71. }
  72. }
  73. // everything should be marked
  74. assert((used.rowwise().minCoeff().array()>=0).all());
  75. }
  76. template <typename DerivedV, typename DerivedF, typename DerivedS, typename DerivedM, typename DerivedC>
  77. IGL_INLINE void igl::polyvector_field_comb_from_matchings_and_cuts(
  78. const Eigen::PlainObjectBase<DerivedV> &V,
  79. const Eigen::PlainObjectBase<DerivedF> &F,
  80. const Eigen::PlainObjectBase<DerivedS> &sol3D,
  81. const Eigen::PlainObjectBase<DerivedM> &match_ab,
  82. const Eigen::PlainObjectBase<DerivedM> &match_ba,
  83. const Eigen::PlainObjectBase<DerivedC> &cuts,
  84. Eigen::PlainObjectBase<DerivedS> &sol3D_combed)
  85. {
  86. Eigen::MatrixXi TT, TTi;
  87. igl::triangle_triangle_adjacency(F,TT,TTi);
  88. Eigen::MatrixXi E, E2F, F2E;
  89. igl::edge_topology(V,F,E,F2E,E2F);
  90. igl::polyvector_field_comb_from_matchings_and_cuts(V, F, TT, E2F, F2E, sol3D, match_ab, match_ba, cuts, sol3D_combed);
  91. }
  92. #ifdef IGL_STATIC_LIBRARY
  93. // Explicit template specialization
  94. template void igl::polyvector_field_comb_from_matchings_and_cuts<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<double, -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::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, 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<double, -1, -1, 0, -1, -1> >&);
  95. template void igl::polyvector_field_comb_from_matchings_and_cuts<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, 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::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<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<double, -1, -1, 0, -1, -1> >&);
  96. #endif