polyvector_field_comb_from_matchings_and_cuts.cpp 5.5 KB

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