cut_mesh_from_singularities.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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 <igl/edge_topology.h>
  11. #include <vector>
  12. #include <deque>
  13. namespace igl {
  14. template <
  15. typename DerivedV,
  16. typename DerivedF,
  17. typename DerivedM,
  18. typename DerivedO
  19. >
  20. class MeshCutter
  21. {
  22. protected:
  23. const Eigen::PlainObjectBase<DerivedV> &V;
  24. const Eigen::PlainObjectBase<DerivedF> &F;
  25. const Eigen::PlainObjectBase<DerivedM> &Handle_MMatch;
  26. Eigen::VectorXi F_visited;
  27. DerivedF TT;
  28. DerivedF TTi;
  29. Eigen::MatrixXi E, F2E, E2F;
  30. protected:
  31. inline bool IsRotSeam(const int f0,const int edge)
  32. {
  33. unsigned char MM = Handle_MMatch(f0,edge);
  34. return (MM!=0);
  35. }
  36. inline void FloodFill(const int start, Eigen::PlainObjectBase<DerivedO> &Handle_Seams)
  37. {
  38. std::deque<int> d;
  39. ///clean the visited flag
  40. F_visited(start) = true;
  41. d.push_back(start);
  42. while (!d.empty())
  43. {
  44. int f = d.at(0); d.pop_front();
  45. for (int s = 0; s<3; s++)
  46. {
  47. int g = TT(f,s); // f->FFp(s);
  48. int j = TTi(f,s); // f->FFi(s);
  49. if (j == -1)
  50. {
  51. g = f;
  52. j = s;
  53. }
  54. if ((!(IsRotSeam(f,s))) && (!(IsRotSeam(g,j))) && (!F_visited(g)) )
  55. {
  56. Handle_Seams(f,s)=false;
  57. Handle_Seams(g,j)=false;
  58. F_visited(g) = true;
  59. d.push_back(g);
  60. }
  61. }
  62. }
  63. }
  64. inline void Retract(Eigen::PlainObjectBase<DerivedO> &Handle_Seams)
  65. {
  66. std::vector<int> e(V.rows(),0); // number of edges per vert
  67. // for (unsigned f=0; f<F.rows(); f++)
  68. // {
  69. // for (int s = 0; s<3; s++)
  70. // {
  71. // if (Handle_Seams(f,s))
  72. // if (TT(f,s)<=f)
  73. // {
  74. // e[ F(f,s) ] ++;
  75. // e[ F(f,(s+1)%3) ] ++;
  76. // }
  77. // }
  78. // }
  79. for (int ei=0; ei<E.rows(); ++ei)
  80. {
  81. //only need one face
  82. int f0 = E2F(ei,0);
  83. if (f0==-1)
  84. f0 = E2F(ei,1);
  85. int k=0;
  86. for (k=0; k<3; ++k)
  87. if (F2E(f0,k)==ei)
  88. break;
  89. if (Handle_Seams(f0,k))
  90. {
  91. e[ F(f0,k) ] ++;
  92. e[ F(f0,(k+1)%3) ] ++;
  93. }
  94. }
  95. bool over=true;
  96. int guard = 0;
  97. do
  98. {
  99. over = true;
  100. for (int f = 0; f<F.rows(); f++) //if (!f->IsD())
  101. {
  102. for (int s = 0; s<3; s++)
  103. {
  104. if (Handle_Seams(f,s))
  105. if (!(IsRotSeam(f,s))) // never retract rot seams
  106. {
  107. if (e[ F(f,s) ] == 1) {
  108. // dissolve seam
  109. Handle_Seams(f,s)=false;
  110. if (TT(f,s) != -1)
  111. Handle_Seams(TT(f,s),TTi(f,s))=false;
  112. e[ F(f,s)] --;
  113. e[ F(f,(s+1)%3) ] --;
  114. over = false;
  115. }
  116. }
  117. }
  118. }
  119. if (guard++>10000)
  120. over = true;
  121. } while (!over);
  122. }
  123. public:
  124. inline MeshCutter(const Eigen::PlainObjectBase<DerivedV> &V_,
  125. const Eigen::PlainObjectBase<DerivedF> &F_,
  126. const Eigen::PlainObjectBase<DerivedM> &Handle_MMatch_):
  127. V(V_),
  128. F(F_),
  129. Handle_MMatch(Handle_MMatch_)
  130. {
  131. triangle_triangle_adjacency(F,TT,TTi);
  132. edge_topology(V,F,E,F2E,E2F);
  133. };
  134. inline void cut(Eigen::PlainObjectBase<DerivedO> &Handle_Seams)
  135. {
  136. F_visited.setConstant(F.rows(),0);
  137. Handle_Seams.setConstant(F.rows(),3,1);
  138. int index=0;
  139. for (unsigned f = 0; f<F.rows(); f++)
  140. {
  141. if (!F_visited(f))
  142. {
  143. index++;
  144. FloodFill(f, Handle_Seams);
  145. }
  146. }
  147. Retract(Handle_Seams);
  148. for (unsigned int f=0;f<F.rows();f++)
  149. for (int j=0;j<3;j++)
  150. if (IsRotSeam(f,j))
  151. Handle_Seams(f,j)=true;
  152. }
  153. };
  154. }
  155. template <typename DerivedV,
  156. typename DerivedF,
  157. typename DerivedM,
  158. typename DerivedO>
  159. IGL_INLINE void igl::cut_mesh_from_singularities(const Eigen::PlainObjectBase<DerivedV> &V,
  160. const Eigen::PlainObjectBase<DerivedF> &F,
  161. const Eigen::PlainObjectBase<DerivedM> &Handle_MMatch,
  162. Eigen::PlainObjectBase<DerivedO> &Handle_Seams)
  163. {
  164. igl::MeshCutter< DerivedV, DerivedF, DerivedM, DerivedO> mc(V, F, Handle_MMatch);
  165. mc.cut(Handle_Seams);
  166. }
  167. #ifdef IGL_STATIC_LIBRARY
  168. // Explicit template instantiation
  169. 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> >&);
  170. 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<double, -1, 3, 0, -1, 3>, 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<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  171. 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, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(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, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
  172. template void igl::cut_mesh_from_singularities<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::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> >&);
  173. template void igl::cut_mesh_from_singularities<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> >&);
  174. template void igl::cut_mesh_from_singularities<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, 3, 0, -1, 3> >(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, 3, 0, -1, 3> >&);
  175. template void igl::cut_mesh_from_singularities<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(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, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
  176. #endif