From 2b012c900d98fbba4f8da483fd64ac17c73ee506 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 10 Apr 2024 15:27:52 +0200 Subject: [PATCH] vector instead of a hash_set of pairs --- .../Conforming_Delaunay_triangulation_3.h | 47 ++++++++++++++----- .../Constrained_Delaunay_triangulation_3.h | 42 +++++++++++------ 2 files changed, 61 insertions(+), 28 deletions(-) diff --git a/Triangulation_3/include/CGAL/Conforming_Delaunay_triangulation_3.h b/Triangulation_3/include/CGAL/Conforming_Delaunay_triangulation_3.h index effcab37312..75f0fc9e27c 100644 --- a/Triangulation_3/include/CGAL/Conforming_Delaunay_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Conforming_Delaunay_triangulation_3.h @@ -206,10 +206,12 @@ protected: auto v2 = (*cell_it)->vertex(j); if(self.tr.is_infinite(v1) || self.tr.is_infinite(v2)) continue; if(self.use_finite_edges_map()) { - [[maybe_unused]] auto nb_erased = self.all_finite_edges.erase(make_sorted_pair(v1, v2)); + if(v1 > v2) std::swap(v1, v2); + auto v1_index = v1->time_stamp(); + [[maybe_unused]] auto nb_erased = self.all_finite_edges[v1_index].erase(v2); if constexpr (cdt_3_can_use_cxx20_format()) if(self.debug_finite_edges_map() && nb_erased > 0) { std::cerr << std::format("erasing edge {} {}\n", self.display_vert((std::min)(v1, v2)), - self.display_vert((std::max)(v1, v2))); + self.display_vert((std::max)(v1, v2))); } } auto [contexts_begin, contexts_end] = @@ -310,10 +312,11 @@ protected: void new_edge(Edge e) { - auto [v1, v2] = tr.vertices(e); + if(!update_all_finite_edges_) return; + auto [v1, v2] = make_sorted_pair(tr.vertices(e)); if(tr.is_infinite(v1) || tr.is_infinite(v2)) return; - [[maybe_unused]] auto [_, inserted] = all_finite_edges.insert(make_sorted_pair(v1, v2)); + [[maybe_unused]] auto [_, inserted] = all_finite_edges[v1->time_stamp()].insert(v2); if constexpr (cdt_3_can_use_cxx20_format()) if (debug_finite_edges_map() && inserted) { if(v2 < v1) std::swap(v1, v2); std::cerr << std::format("new_edge({}, {})\n", display_vert(v1), display_vert(v2)); @@ -344,14 +347,18 @@ protected: switch (tr.dimension()) { case 3: { typename T_3::Conflict_tester_3 tester(p, this); - return tr.insert_in_conflict(p, lt, c, li, lj, tester, - visitor); + auto v = tr.insert_in_conflict(p, lt, c, li, lj, tester, + visitor); + new_vertex(v); + return v; } // dim 3 case 2: { typename T_3::Conflict_tester_2 tester(p, this); - auto v = tr.insert_in_conflict(p, lt, c, li, lj, tester, - visitor); - tr.incident_edges(v, boost::make_function_output_iterator([&](Edge e) { this->new_edge(e); })); + auto v = tr.insert_in_conflict(p, lt, c, li, lj, tester, visitor); + if(use_finite_edges_map()) { + new_vertex(v); + tr.incident_edges(v, boost::make_function_output_iterator([&](Edge e) { this->new_edge(e); })); + } return v; } // dim 2 default: @@ -359,6 +366,7 @@ protected: // Do not use the generic insert. auto v = tr.insert(p, c); if(use_finite_edges_map()) { + new_vertex(v); all_finite_edges.clear(); if (debug_finite_edges_map()) std::cerr << "all_finite_edges.clear()\n"; for(auto e: tr.all_edges()) { @@ -500,8 +508,12 @@ public: bool is_edge(Vertex_handle va, Vertex_handle vb) const { const bool is_edge_v1 = ((debug_finite_edges_map() && use_finite_edges_map()) || !use_finite_edges_map()) && tr.tds().is_edge(va, vb); + + if(use_finite_edges_map() && va > vb) std::swap(va, vb); + const auto va_index = va->time_stamp(); const bool is_edge_v2 = - use_finite_edges_map() && all_finite_edges.find(make_sorted_pair(va, vb)) != all_finite_edges.end(); + use_finite_edges_map() && all_finite_edges[va_index].find(vb) != all_finite_edges[va_index].end(); + if(debug_finite_edges_map() && use_finite_edges_map() && is_edge_v1 != is_edge_v2) { std::cerr << "!! Inconsistent edge status\n"; std::cerr << " -> constraint " << display_vert(va) << " " << display_vert(vb) << '\n'; @@ -693,6 +705,9 @@ protected: visitor.insert_Steiner_point_on_constraint(constraint, va, vb, v); add_to_subconstraints_to_conform(va, v, constraint); add_to_subconstraints_to_conform(v, vb, constraint); + + new_vertex(v); + return v; } @@ -1020,8 +1035,7 @@ protected: std::stack > subconstraints_to_conform; - using Hash = boost::hash; - std::unordered_set all_finite_edges; + std::vector> all_finite_edges; bool update_all_finite_edges_ = false; void update_all_finite_edges() { @@ -1029,7 +1043,7 @@ protected: update_all_finite_edges_ = true; if(use_finite_edges_map()) { all_finite_edges.clear(); - all_finite_edges.reserve(tr.number_of_finite_edges()); + all_finite_edges.resize(tr.number_of_vertices()+1); for(auto e: tr.all_edges()) { new_edge(e); } @@ -1037,6 +1051,13 @@ protected: } } + void new_vertex(Vertex_handle v) { + if(use_finite_edges_map() && v->time_stamp() >= all_finite_edges.size()) { + all_finite_edges.emplace_back(); + CGAL_assertion(v->time_stamp() == all_finite_edges.size() - 1); + } + } + enum class Debug_flags { Steiner_points = 0, conforming, diff --git a/Triangulation_3/include/CGAL/Constrained_Delaunay_triangulation_3.h b/Triangulation_3/include/CGAL/Constrained_Delaunay_triangulation_3.h index 685cfadd735..ed068ca7b84 100644 --- a/Triangulation_3/include/CGAL/Constrained_Delaunay_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Constrained_Delaunay_triangulation_3.h @@ -576,15 +576,18 @@ template class Constrained_Delaunay_triangulation_3 : public Conforming_Delaunay_triangulation_3 { public: using Conforming_Dt = Conforming_Delaunay_triangulation_3; + using Vertex_handle = typename T_3::Vertex_handle; - using Cell_handle = typename T_3::Cell_handle; using Edge = typename T_3::Edge; using Facet = typename T_3::Facet; - using Point_3 = typename T_3::Point; - using Segment_3 = typename T_3::Geom_traits::Segment_3; - using Vector_3 = typename T_3::Geom_traits::Vector_3; - using Locate_type = typename T_3::Locate_type; + using Cell_handle = typename T_3::Cell_handle; + using Geom_traits = typename T_3::Geom_traits; + using Point_3 = typename T_3::Point; + using Segment_3 = typename Geom_traits::Segment_3; + using Vector_3 = typename Geom_traits::Vector_3; + using Locate_type = typename T_3::Locate_type; + using size_type = typename T_3::size_type; using Vertex_marker = CDT_3_vertex_marker; using Cell_marker = CDT_3_cell_marker; @@ -923,6 +926,9 @@ public: for(auto c: cells_of_cavity) { this->tds().delete_cell(c); } + + this->new_vertex(p_vh); + CGAL_assume(!this->debug_validity() || this->is_valid(true)); return p_vh; @@ -3143,23 +3149,29 @@ public: } } if(this->use_finite_edges_map()) { - bool test = this->all_finite_edges.size() == this->number_of_finite_edges(); + const auto number_of_elements_in_finite_edges_map = + std::accumulate(this->all_finite_edges.begin(), this->all_finite_edges.end(), size_type(0), + [&](size_type res, const auto& hash_map) { return res + hash_map.size(); }); + bool test = number_of_elements_in_finite_edges_map == this->number_of_finite_edges(); result = result && test; if(!test && verbose) { - std::cerr << "all_finite_edges.size() = " << this->all_finite_edges.size() + std::cerr << "all_finite_edges.size() = " << number_of_elements_in_finite_edges_map << " != number_of_finite_edges() = " << this->number_of_finite_edges() << std::endl; } - for(auto e: this->all_finite_edges) { - test = this->is_edge(e.first, e.second); - result = result && test; - if(!test && verbose) { - std::cerr << "edge (" << IO::oformat(e.first, with_point_and_info) << ", " - << IO::oformat(e.second, with_point_and_info) << ") is not an edge" << std::endl; + for(auto v1: this->finite_vertex_handles()) { + for(auto v2: this->all_finite_edges[v1->time_stamp()]) { + test = this->is_edge(v1, v2); + result = result && test; + if(!test && verbose) { + std::cerr << "edge (" << IO::oformat(v1, with_point_and_info) << ", " + << IO::oformat(v2, with_point_and_info) << ") is not an edge" << std::endl; + } } } for(auto e : this->finite_edges()) { - auto [v1, v2] = this->vertices(e); - test = this->all_finite_edges.find(make_sorted_pair(v1, v2)) != this->all_finite_edges.end(); + auto [v1, v2] = make_sorted_pair(this->vertices(e)); + auto v1_index = v1->time_stamp(); + test = this->all_finite_edges[v1_index].find(v2)!= this->all_finite_edges[v1_index].end(); result = result && test; if(!test && verbose) { std::cerr << "finite edge (" << IO::oformat(v1, with_point_and_info) << ", "