diff --git a/Triangulation_3/include/CGAL/Conforming_Delaunay_triangulation_3.h b/Triangulation_3/include/CGAL/Conforming_Delaunay_triangulation_3.h index dc7d7f5aeeb..50a88aaeab9 100644 --- a/Triangulation_3/include/CGAL/Conforming_Delaunay_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Conforming_Delaunay_triangulation_3.h @@ -42,12 +42,19 @@ namespace CGAL { enum class CDT_3_vertex_type { FREE, CORNER, STEINER_ON_EDGE, STEINER_IN_FACE }; +enum class CDT_3_vertex_marker { + CLEAR = 0, + REGION_BORDER, + REGION_INSIDE, + nb_of_markers +}; + using CDT_3_face_index = int; // must be signed template > class Conforming_Delaunay_triangulation_vertex_base_3 : public Base_with_time_stamp { CDT_3_vertex_type m_vertex_type = CDT_3_vertex_type::FREE; - unsigned int mark = 0; + std::bitset(CDT_3_vertex_marker::nb_of_markers)> mark; union U { struct On_edge { int nb_of_incident_constraints = 0; @@ -83,16 +90,20 @@ public: return u.on_edge.nb_of_incident_constraints; } - void mark_vertex() { - mark = 1; + void set_mark(CDT_3_vertex_marker marker) { + mark.set(static_cast(marker)); } - void unmark_vertex() { - mark = 0; + void clear_marks() { + mark.reset(); } - bool is_marked() const { - return mark == 1; + void clear_mark(CDT_3_vertex_marker marker) { + mark.reset(static_cast(marker)); + } + + bool is_marked(CDT_3_vertex_marker marker) const { + return mark.test(static_cast(marker)); } template diff --git a/Triangulation_3/include/CGAL/Constrained_Delaunay_triangulation_3.h b/Triangulation_3/include/CGAL/Constrained_Delaunay_triangulation_3.h index ded146abb5d..f541a5fc81a 100644 --- a/Triangulation_3/include/CGAL/Constrained_Delaunay_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Constrained_Delaunay_triangulation_3.h @@ -218,6 +218,8 @@ public: using Locate_type = typename T_3::Locate_type; using Geom_traits = typename T_3::Geom_traits; + using Vertex_marker = CDT_3_vertex_marker; + using Face_index = CDT_3_face_index; static std::string io_signature() { @@ -1026,8 +1028,8 @@ private: { const auto vc = cell->vertex(index_vd); const auto vd = cell->vertex(index_vc); - if(!vd->is_Steiner_vertex_in_face() && vd->is_marked()) return 0; // vertex marked of the border - if(!vc->is_Steiner_vertex_in_face() && vc->is_marked()) return 0; // vertex marked of the border + if(vc->is_marked(Vertex_marker::REGION_BORDER)) return 0; // vertex marked of the border + if(vd->is_marked(Vertex_marker::REGION_BORDER)) return 0; // vertex marked of the border const auto pc = this->point(vc); const auto pd = this->point(vd); const typename Geom_traits::Segment_3 seg{pc, pd}; @@ -1200,10 +1202,10 @@ private: #endif // CGAL_CDT_3_CAN_USE_CXX20_FORMAT auto [cached_value_it, not_visited] = new_edge(v0, v1, false); if(!not_visited) return value_returned(cached_value_it->second); - int v0v1_intersects_region = ((v0->is_Steiner_vertex_in_face() && v0->face_index() == face_index) || - (v1->is_Steiner_vertex_in_face() && v1->face_index() == face_index)) - ? expected - : does_edge_intersect_region(cell, index_v0, index_v1, cdt_2, fh_region); + int v0v1_intersects_region = + (v0->is_marked(Vertex_marker::REGION_INSIDE) || v1->is_marked(Vertex_marker::REGION_INSIDE)) + ? expected + : does_edge_intersect_region(cell, index_v0, index_v1, cdt_2, fh_region); if(v0v1_intersects_region != 0) { if(v0v1_intersects_region != expected) { throw PLC_error{"PLC error: v0v1_intersects_region != expected" , @@ -1306,11 +1308,11 @@ private: } #endif // CGAL_CDT_3_CAN_USE_CXX20_FORMAT for(auto v: region_border_vertices) { - v->mark_vertex(); + v->set_mark(Vertex_marker::REGION_BORDER); } const auto found_edge_opt = search_first_intersection(face_index, cdt_2, fh_region, border_edges); for(auto v: region_border_vertices) { - v->unmark_vertex(); + v->clear_mark(Vertex_marker::REGION_BORDER); } [[maybe_unused]] auto try_flip_region_size_4 = [&] { @@ -1448,6 +1450,25 @@ private: } CGAL_assertion(found_edge_opt != std::nullopt); + for(auto v : region_border_vertices) { + v->set_mark(Vertex_marker::REGION_BORDER); + } + for(auto v : region_vertices) { + if(v->is_marked(Vertex_marker::REGION_BORDER)) + continue; + v->set_mark(Vertex_marker::REGION_INSIDE); + } + struct Region_vertices_marker_scope_guard + { + std::function unmark; + ~Region_vertices_marker_scope_guard() { unmark(); } + } guard{[&] { + for(auto v : region_vertices) { + v->clear_mark(Vertex_marker::REGION_BORDER); + v->clear_mark(Vertex_marker::REGION_INSIDE); + } + }}; + const auto first_intersecting_edge = *found_edge_opt; const auto [intersecting_edges, original_intersecting_cells, original_vertices_of_upper_cavity, original_vertices_of_lower_cavity, original_facets_of_upper_cavity, original_facets_of_lower_cavity] =