cut_mesh_from_singularities.cpp 4.9 KB

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