cut_mesh_from_singularities.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include "cut_mesh_from_singularities.h"
  2. #include <vector>
  3. #include <deque>
  4. namespace igl {
  5. template <
  6. typename DerivedV,
  7. typename DerivedF,
  8. typename DerivedM,
  9. typename DerivedS,
  10. typename DerivedO
  11. >
  12. class MeshCutter
  13. {
  14. protected:
  15. const Eigen::PlainObjectBase<DerivedV> &V;
  16. const Eigen::PlainObjectBase<DerivedF> &F;
  17. const Eigen::PlainObjectBase<DerivedS> &Handle_Singular;
  18. const Eigen::PlainObjectBase<DerivedS> &Handle_SingularDegree;
  19. const Eigen::PlainObjectBase<DerivedM> &Handle_MMatch;
  20. Eigen::VectorXi F_visited;
  21. Eigen::PlainObjectBase<DerivedF> TT;
  22. Eigen::PlainObjectBase<DerivedF> TTi;
  23. protected:
  24. bool IsRotSeam(const int f0,const int edge)
  25. {
  26. unsigned char MM = Handle_MMatch(f0,edge);
  27. return (MM!=0);
  28. }
  29. void FloodFill(const int start, Eigen::PlainObjectBase<DerivedO> &Handle_Seams)
  30. {
  31. std::deque<int> d;
  32. ///clean the visited flag
  33. F_visited(start) = true;
  34. d.push_back(start);
  35. while (!d.empty())
  36. {
  37. int f = d.at(0); d.pop_front();
  38. for (int s = 0; s<3; s++)
  39. {
  40. int g = TT(f,s); // f->FFp(s);
  41. int j = TTi(f,s); // f->FFi(s);
  42. if (j == -1)
  43. {
  44. g = f;
  45. j = s;
  46. }
  47. if ((!(IsRotSeam(f,s))) && (!(IsRotSeam(g,j))) && (!F_visited(g)) )
  48. {
  49. Handle_Seams(f,s)=false;
  50. Handle_Seams(g,j)=false;
  51. F_visited(g) = true;
  52. d.push_back(g);
  53. }
  54. }
  55. }
  56. }
  57. void Retract(Eigen::PlainObjectBase<DerivedO> &Handle_Seams)
  58. {
  59. std::vector<int> e(V.rows(),0); // number of edges per vert
  60. for (unsigned f=0; f<F.rows(); f++)
  61. {
  62. for (int s = 0; s<3; s++)
  63. {
  64. if (Handle_Seams(f,s))
  65. if (TT(f,s)<=f)
  66. {
  67. e[ F(f,s) ] ++;
  68. e[ F(f,(s+1)%3) ] ++;
  69. }
  70. }
  71. }
  72. bool over=true;
  73. int guard = 0;
  74. do
  75. {
  76. over = true;
  77. for (int f = 0; f<F.rows(); f++) //if (!f->IsD())
  78. {
  79. for (int s = 0; s<3; s++)
  80. {
  81. if (Handle_Seams(f,s))
  82. if (!(IsRotSeam(f,s))) // never retract rot seams
  83. {
  84. if (e[ F(f,s) ] == 1) {
  85. // dissolve seam
  86. Handle_Seams(f,s)=false;
  87. if (TT(f,s) != -1)
  88. Handle_Seams(TT(f,s),TTi(f,s))=false;
  89. e[ F(f,s)] --;
  90. e[ F(f,(s+1)%3) ] --;
  91. over = false;
  92. }
  93. }
  94. }
  95. }
  96. if (guard++>10000)
  97. over = true;
  98. } while (!over);
  99. }
  100. public:
  101. MeshCutter(const Eigen::PlainObjectBase<DerivedV> &V_,
  102. const Eigen::PlainObjectBase<DerivedF> &F_,
  103. const Eigen::PlainObjectBase<DerivedM> &Handle_MMatch_,
  104. const Eigen::PlainObjectBase<DerivedS> &Handle_Singular_,
  105. const Eigen::PlainObjectBase<DerivedS> &Handle_SingularDegree_):
  106. V(V_),
  107. F(F_),
  108. Handle_MMatch(Handle_MMatch_),
  109. Handle_Singular(Handle_Singular_),
  110. Handle_SingularDegree(Handle_SingularDegree_)
  111. {
  112. tt(V,F,TT,TTi);
  113. };
  114. void cut(Eigen::PlainObjectBase<DerivedO> &Handle_Seams)
  115. {
  116. F_visited.setConstant(F.rows(),0);
  117. Handle_Seams.setConstant(F.rows(),3,1);
  118. int index=0;
  119. for (unsigned f = 0; f<F.rows(); f++)
  120. {
  121. if (!F_visited(f))
  122. {
  123. index++;
  124. FloodFill(f, Handle_Seams);
  125. }
  126. }
  127. Retract(Handle_Seams);
  128. for (unsigned int f=0;f<F.rows();f++)
  129. for (int j=0;j<3;j++)
  130. if (IsRotSeam(f,j))
  131. Handle_Seams(f,j)=true;
  132. }
  133. };
  134. }
  135. template <typename DerivedV,
  136. typename DerivedF,
  137. typename DerivedM,
  138. typename DerivedS,
  139. typename DerivedO>
  140. IGL_INLINE void igl::cut_mesh_from_singularities(const Eigen::PlainObjectBase<DerivedV> &V,
  141. const Eigen::PlainObjectBase<DerivedF> &F,
  142. const Eigen::PlainObjectBase<DerivedM> &Handle_MMatch,
  143. const Eigen::PlainObjectBase<DerivedS> &isSingularity,
  144. const Eigen::PlainObjectBase<DerivedS> &singularityIndex,
  145. Eigen::PlainObjectBase<DerivedO> &Handle_Seams)
  146. {
  147. igl::MeshCutter< DerivedV, DerivedF, DerivedM, DerivedS, DerivedO> mc(V, F, Handle_MMatch, isSingularity, singularityIndex);
  148. mc.cut(Handle_Seams);
  149. }