From 2ae4e28de77c468ebde3a804ab8f0003d6dfdfe2 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Wed, 1 Jul 2020 06:32:27 +0100 Subject: [PATCH] do not collapse when the cells set for collapse does not represent a manifold surface trying to make the cells set manifold is not easy, and quite costly, so let's just check whether the cells set surface is manifold and cancel the collapse if not --- .../internal/collapse_short_edges.h | 126 +++++++++--------- 1 file changed, 65 insertions(+), 61 deletions(-) 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)