diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/collapse_short_edges.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/collapse_short_edges.h index b77b2bcafa7..0c4c4d4a41c 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/collapse_short_edges.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/collapse_short_edges.h @@ -54,12 +54,14 @@ class CollapseTriangulation typedef typename C3t3::Cell_handle Cell_handle; typedef typename C3t3::Vertex_handle Vertex_handle; typedef typename C3t3::Subdomain_index Subdomain_index; + typedef typename C3t3::Surface_patch_index Surface_patch_index; typedef typename C3t3::Triangulation::Point Point_3; typedef typename C3t3::Triangulation::Geom_traits::Vector_3 Vector_3; public: CollapseTriangulation(C3t3& c3t3, const Edge& e, + const std::unordered_set& cells_to_insert, Collapse_type _collapse_type) : collapse_type(_collapse_type) , v0_init(e.first->vertex(e.second)) @@ -68,14 +70,6 @@ public: typedef std::array Facet; // 3 = id typedef std::array Tet_with_ref; // first 4 = id, fifth = reference - std::unordered_set cells_to_insert; - c3t3.triangulation().finite_incident_cells(v0_init, - std::inserter(cells_to_insert, cells_to_insert.end())); - c3t3.triangulation().finite_incident_cells(v1_init, - std::inserter(cells_to_insert, cells_to_insert.end())); - - make_cells_set_manifold(c3t3, cells_to_insert); - std::unordered_set vertices_to_insert; for (Cell_handle ch : cells_to_insert) { @@ -144,58 +138,6 @@ public: #endif } - void make_cells_set_manifold(const C3t3& c3t3, - std::unordered_set& cells) - { - typedef Vertex_handle Vh; - typedef std::array FV; - typedef std::pair EV; - - boost::unordered_map facets; - for (Cell_handle c : cells) - { - for (int i = 0; i < 4; ++i) - { - const FV fvi = make_vertex_array(c->vertex((i + 1) % 4), - c->vertex((i + 2) % 4), - c->vertex((i + 3) % 4)); - typename boost::unordered_map::iterator fit = facets.find(fvi); - if(fit == facets.end()) - facets.insert(std::make_pair(fvi, 1)); - else - fit->second++; - } - } - - boost::unordered_map edges; - for (const std::pair& fvv : facets) - { - if(fvv.second != 1) - continue; - - for (int i = 0; i < 3; ++i) - { - const EV evi = make_vertex_pair(fvv.first[i], fvv.first[(i + 1) % 3]); - typename boost::unordered_map::iterator eit = edges.find(evi); - if (eit == edges.end()) - edges.insert(std::make_pair(evi, 1)); - else - eit->second++; - } - } - - for (const std::pair& evv : edges) - { - if (evv.second != 2) - { - c3t3.triangulation().finite_incident_cells(evv.first.first, - std::inserter(cells, cells.begin())); - c3t3.triangulation().finite_incident_cells(evv.first.second, - std::inserter(cells, cells.begin())); - } - } - } - Result_type collapse() { if (not_an_edge) @@ -1036,6 +978,55 @@ typename C3t3::Vertex_handle collapse(typename C3t3::Edge& edge, return vh; } +template +bool is_cells_set_manifold(const C3t3& c3t3, + std::unordered_set& cells) +{ + typedef typename C3t3::Cell_handle Cell_handle; + typedef typename C3t3::Vertex_handle Vh; + typedef std::array FV; + typedef std::pair EV; + + boost::unordered_map facets; + for (Cell_handle c : cells) + { + for (int i = 0; i < 4; ++i) + { + const FV fvi = make_vertex_array(c->vertex((i + 1) % 4), + c->vertex((i + 2) % 4), + c->vertex((i + 3) % 4)); + typename boost::unordered_map::iterator fit = facets.find(fvi); + if (fit == facets.end()) + facets.insert(std::make_pair(fvi, 1)); + else + fit->second++; + } + } + + boost::unordered_map edges; + for (const std::pair& fvv : facets) + { + if (fvv.second != 1) + continue; + + for (int i = 0; i < 3; ++i) + { + const EV evi = make_vertex_pair(fvv.first[i], fvv.first[(i + 1) % 3]); + typename boost::unordered_map::iterator eit = edges.find(evi); + if (eit == edges.end()) + edges.insert(std::make_pair(evi, 1)); + else + eit->second++; + } + } + + for (const std::pair& evv : edges) + if (evv.second != 2) + return false; + + return true; +} + template typename C3t3::Vertex_handle collapse_edge(typename C3t3::Edge& edge, C3t3& c3t3, @@ -1047,6 +1038,7 @@ typename C3t3::Vertex_handle collapse_edge(typename C3t3::Edge& edge, typedef typename C3t3::Triangulation Tr; typedef typename Tr::Point Point; typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Cell_handle Cell_handle; const Vertex_handle v0 = edge.first->vertex(edge.second); const Vertex_handle v1 = edge.first->vertex(edge.third); @@ -1119,7 +1111,19 @@ typename C3t3::Vertex_handle collapse_edge(typename C3t3::Edge& edge, CGAL_assertion(c3t3.triangulation().is_edge(edge.first->vertex(edge.second), edge.first->vertex(edge.third), dc, di, dj)); - CollapseTriangulation local_tri(c3t3, edge, collapse_type); + Vertex_handle v0_init = edge.first->vertex(edge.second); + Vertex_handle v1_init = edge.first->vertex(edge.third); + + std::unordered_set cells_to_insert; + c3t3.triangulation().finite_incident_cells(v0_init, + std::inserter(cells_to_insert, cells_to_insert.end())); + c3t3.triangulation().finite_incident_cells(v1_init, + std::inserter(cells_to_insert, cells_to_insert.end())); + + if(!is_cells_set_manifold(c3t3, cells_to_insert)) + return Vertex_handle(); + + CollapseTriangulation local_tri(c3t3, edge, cells_to_insert, collapse_type); Result_type res = local_tri.collapse(); if (res == VALID)