triangulate.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include "triangulate.h"
  2. #include "assign_scalar.h"
  3. #include "../../list_to_matrix.h"
  4. #include <CGAL/Point_2.h>
  5. #include <CGAL/Constrained_Delaunay_triangulation_2.h>
  6. #include <CGAL/Constrained_triangulation_plus_2.h>
  7. #include <CGAL/Triangulation_face_base_with_info_2.h>
  8. #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
  9. #include <queue>
  10. template <
  11. typename Kernel,
  12. typename DerivedV,
  13. typename DerivedE,
  14. typename DerivedH,
  15. typename DerivedV2,
  16. typename DerivedF2>
  17. IGL_INLINE void igl::copyleft::cgal::triangulate(
  18. const Eigen::MatrixBase<DerivedV> & V,
  19. const Eigen::MatrixBase<DerivedE> & E,
  20. const Eigen::MatrixBase<DerivedH> & H,
  21. const bool retain_convex_hull,
  22. Eigen::PlainObjectBase<DerivedV2> & TV,
  23. Eigen::PlainObjectBase<DerivedF2> & TF)
  24. {
  25. struct FaceInfo2
  26. {
  27. FaceInfo2(){}
  28. bool visited = false;
  29. bool in_domain = true;
  30. };
  31. typedef Eigen::Index Index;
  32. //typedef CGAL::Epeck Kernel;
  33. typedef CGAL::Point_2<Kernel> Point_2;
  34. typedef CGAL::Triangulation_vertex_base_2<Kernel> TVB_2;
  35. typedef CGAL::Triangulation_face_base_with_info_2<FaceInfo2,Kernel> TFB_2;
  36. typedef CGAL::Constrained_triangulation_face_base_2<Kernel,TFB_2> CTFB_2;
  37. typedef CGAL::Triangulation_data_structure_2<TVB_2,CTFB_2> TDS_2;
  38. typedef CGAL::Exact_intersections_tag Itag;
  39. typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel,TDS_2,Itag> CDT_2;
  40. typedef CGAL::Constrained_triangulation_plus_2<CDT_2> CDT_plus_2;
  41. typedef typename CDT_plus_2::Face_handle Face_handle;
  42. CDT_plus_2 cdt;
  43. // Insert all points
  44. std::vector<Point_2> points;points.reserve(V.rows());
  45. for(Eigen::Index i = 0;i<V.rows();i++)
  46. {
  47. Point_2 p(V(i,0),V(i,1));
  48. cdt.insert(p);
  49. points.emplace_back(p);
  50. }
  51. // Insert all edges
  52. for(Eigen::Index e = 0;e<E.rows();e++)
  53. {
  54. cdt.insert_constraint(points[E(e,0)],points[E(e,1)]);
  55. }
  56. // https://doc.cgal.org/latest/Triangulation_2/index.html#title30
  57. //
  58. // "remove" connected component of face start by marking faces as
  59. // in_domain = false. start should not yet be visited.
  60. const auto remove_cc = [&](Face_handle start)
  61. {
  62. std::queue<Face_handle> queue;
  63. queue.push(start);
  64. while(!queue.empty())
  65. {
  66. Face_handle fh = queue.front();
  67. queue.pop();
  68. if(!fh->info().visited)
  69. {
  70. fh->info().visited = true;
  71. fh->info().in_domain = false;
  72. for(int i = 0; i < 3; i++)
  73. {
  74. typename CDT_plus_2::Edge e(fh,i);
  75. Face_handle n = fh->neighbor(i);
  76. if(!n->info().visited && !cdt.is_constrained(e))
  77. {
  78. queue.push(n);
  79. }
  80. }
  81. }
  82. }
  83. };
  84. // If _not_ meshsing convex hull, remove anything connected to infinite face
  85. if(!retain_convex_hull)
  86. {
  87. remove_cc(cdt.infinite_face());
  88. }
  89. // remove holes
  90. for(Eigen::Index h = 0;h<H.rows();h++)
  91. {
  92. remove_cc(cdt.locate({H(h,0),H(h,1)}));
  93. }
  94. std::vector<CGAL::Point_2<Kernel> > vertices;
  95. std::vector<std::vector<Index> > faces;
  96. // Read off vertices of the cdt, remembering index
  97. std::map<typename CDT_plus_2::Vertex_handle,Index> v2i;
  98. size_t count=0;
  99. for (
  100. auto itr = cdt.finite_vertices_begin();
  101. itr != cdt.finite_vertices_end();
  102. itr++)
  103. {
  104. vertices.push_back(itr->point());
  105. v2i[itr] = count;
  106. count++;
  107. }
  108. // Read off faces and store index triples
  109. for (
  110. auto itr = cdt.finite_faces_begin();
  111. itr != cdt.finite_faces_end();
  112. itr++)
  113. {
  114. if(itr->info().in_domain)
  115. {
  116. faces.push_back(
  117. { v2i[itr->vertex(0)], v2i[itr->vertex(1)], v2i[itr->vertex(2)] });
  118. }
  119. }
  120. TV.resize(vertices.size(),2);
  121. for(int v = 0;v<vertices.size();v++)
  122. {
  123. for(int d = 0;d<2;d++)
  124. {
  125. assign_scalar(vertices[v][d], TV(v,d));
  126. }
  127. }
  128. list_to_matrix(faces,TF);
  129. }
  130. #ifdef IGL_STATIC_LIBRARY
  131. // Explicit template instantiation
  132. // generated by autoexplicit.sh
  133. template void igl::copyleft::cgal::triangulate<CGAL::Epeck, 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<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  134. template void igl::copyleft::cgal::triangulate<CGAL::Epick, 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<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  135. #endif