diff --git a/Circulator/include/CGAL/circulator.h b/Circulator/include/CGAL/circulator.h index c622fb615ad..aa069651668 100644 --- a/Circulator/include/CGAL/circulator.h +++ b/Circulator/include/CGAL/circulator.h @@ -22,10 +22,11 @@ #include #include #include +#include #include -#include #include +#include // These are name redefinitions for backwards compatibility // with the pre iterator-traits style adaptors. @@ -640,6 +641,34 @@ operator+( Dist n, const Iterator_from_circulator& circ) { return tmp += n; } +template +class Range_from_circulator { +private: + Circ anchor; +public: + using pointer = CGAL::cpp20::remove_cvref_t())>; + using const_pointer = CGAL::cpp20::remove_cvref_t())>; + using reference = decltype(*anchor); + using const_reference = decltype(*std::as_const(anchor)); + using iterator = Iterator_from_circulator; + using const_iterator = Iterator_from_circulator; + + iterator begin() { + return iterator(&anchor, 0); + } + const_iterator begin() const { + return const_iterator(&anchor, 0); + } + iterator end() { + return anchor == nullptr ? iterator(&anchor, 0) : iterator(&anchor, 1); + } + const_iterator end() const { + return anchor == nullptr ? const_iterator(&anchor, 0) : const_iterator(&anchor, 1); + } + Range_from_circulator() = default; + Range_from_circulator(const Circ& c) : anchor(get_min_circulator(c)) {} +}; + template < class C > class Container_from_circulator { private: diff --git a/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_3.h b/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_3.h index 1a070a77585..f42a6adab1d 100644 --- a/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_3.h +++ b/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_3.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -898,83 +899,6 @@ public: } /// @} // end triangulation section - /// \cond SKIP_IN_MANUAL - Conforming_constrained_Delaunay_triangulation_3 convert_for_remeshing() && - { - auto& tr = cdt_impl; - - for(auto v : tr.all_vertex_handles()) { - switch(v->ccdt_3_data().vertex_type()) { - case CDT_3_vertex_type::CORNER: - v->set_dimension(0); - v->set_index(0); - break; - case CDT_3_vertex_type::STEINER_ON_EDGE: - v->set_dimension(1); - v->set_index(static_cast(v->ccdt_3_data().constrained_polyline_id(tr).index())); - break; - case CDT_3_vertex_type::STEINER_IN_FACE: - v->set_dimension(2); - v->set_index(v->ccdt_3_data().face_index()); - break; - case CDT_3_vertex_type::FREE: - v->set_dimension(3); - v->set_index(1); - break; - default: - CGAL_error(); - break; - } - } - - if(tr.dimension() < 3) { - for(auto ch : tr.all_cell_handles()) { - ch->set_subdomain_index(0); - } - } else { - for(auto ch : tr.all_cell_handles()) { - ch->set_subdomain_index(1); - } - - std::stack stack; - stack.push(tr.infinite_cell()); - while(!stack.empty()) { - auto ch = stack.top(); - stack.pop(); - ch->set_subdomain_index(0); - for(int i = 0; i < 4; ++i) { - if(ch->ccdt_3_data().is_facet_constrained(i)) - continue; - auto n = ch->neighbor(i); - if(n->subdomain_index() == 1) { - stack.push(n); - } - } - } - - for(auto f : tr.finite_facets()) - { - const auto& mf = tr.mirror_facet(f); - if(f.first->ccdt_3_data().is_facet_constrained(f.second) || - mf.first->ccdt_3_data().is_facet_constrained(mf.second)) - { - const auto& patch = f.first->ccdt_3_data().face_constraint_index(f.second); - f.first->set_surface_patch_index(f.second, patch); - mf.first->set_surface_patch_index(mf.second, patch); - } - } - } - Conforming_constrained_Delaunay_triangulation_3 result{std::move(*this)}; - static_assert(CGAL::cdt_3_msvc_2019_or_older() || - CGAL::is_nothrow_movable_v == false || - CGAL::is_nothrow_movable_v); - static_assert(std::is_same_v, Conforming_constrained_Delaunay_triangulation_3>); - *this = Conforming_constrained_Delaunay_triangulation_3{}; - return result; - } - /// \endcond - // end SKIP_IN_MANUAL for convert_for_remeshing - /** * A bidirectional iterator for visiting all constrained facets of the triangulation. * The value type of this iterator is `Triangulation::Facet`. @@ -4098,27 +4022,103 @@ auto convert_to_triangulation_3(Conforming_constrained_Delaunay_triangulation_3< Triangulation_data_structure> { - constexpr bool has_ecmap = + for(auto v : ccdt.triangulation().all_vertex_handles()) { + switch(v->ccdt_3_data().vertex_type()) { + case CDT_3_vertex_type::CORNER: + v->set_dimension(0); + v->set_index(0); + break; + case CDT_3_vertex_type::STEINER_ON_EDGE: + v->set_dimension(1); + v->set_index(static_cast(v->ccdt_3_data().constrained_polyline_id(ccdt).index())); + break; + case CDT_3_vertex_type::STEINER_IN_FACE: + v->set_dimension(2); + v->set_index(v->ccdt_3_data().face_index()); + break; + case CDT_3_vertex_type::FREE: + v->set_dimension(3); + v->set_index(1); + break; + default: + CGAL_error(); + break; + } + } + + constexpr bool has_edge_is_constrained_map = !parameters::is_default_parameter::value; - if constexpr (has_ecmap) + if constexpr (has_edge_is_constrained_map) { const auto& tr = ccdt.triangulation(); - auto ecmap = parameters::get_parameter(np, internal_np::edge_is_constrained); + auto edge_is_constrained_map = parameters::get_parameter(np, internal_np::edge_is_constrained); for(auto e : tr.finite_edges()) { auto [v1, v2] = tr.vertices(e); - if( v1->ccdt_3_data().constrained_polyline_id(ccdt).index() - == v2->ccdt_3_data().constrained_polyline_id(ccdt).index()) + auto v1_dim = v1->in_dimension(); + auto v2_dim = v2->in_dimension(); + + if(v1_dim > 1 || v2_dim > 1) continue; + + if(v1_dim == 1 && v2_dim == 1 && + v1->ccdt_3_data().constrained_polyline_id(ccdt).index() + != v2->ccdt_3_data().constrained_polyline_id(ccdt).index()) continue; + + auto incident_facets = Range_from_circulator(tr.incident_facets(e)); + if(std::any_of(incident_facets.begin(), incident_facets.end(), + [&](const auto& f) { return ccdt.is_facet_constrained(f); })) { if(v2 > v1) std::swap(v1, v2); - put(ecmap, std::make_pair(v1, v2), true); + put(edge_is_constrained_map, std::make_pair(v1, v2), true); } } } - auto tmp = std::move(ccdt).convert_for_remeshing(); - return std::move(tmp).triangulation(); + auto tr = std::move(ccdt).triangulation(); + + using CDT_3 = Conforming_constrained_Delaunay_triangulation_3; + using TDS = typename CDT_3::Triangulation::Triangulation_data_structure; + static_assert(std::is_same_v>); + + if(tr.dimension() < 3) { + for(auto ch : tr.all_cell_handles()) { + ch->set_subdomain_index(0); + } + } else { + for(auto ch : tr.all_cell_handles()) { + ch->set_subdomain_index(1); + } + + std::stack stack; + stack.push(tr.infinite_cell()); + while(!stack.empty()) { + auto ch = stack.top(); + stack.pop(); + ch->set_subdomain_index(0); + for(int i = 0; i < 4; ++i) { + if(ch->ccdt_3_data().is_facet_constrained(i)) + continue; + auto n = ch->neighbor(i); + if(n->subdomain_index() == 1) { + stack.push(n); + } + } + } + + for(auto f : tr.finite_facets()) + { + auto mf = tr.mirror_facet(f); + if(f.first->ccdt_3_data().is_facet_constrained(f.second) || + mf.first->ccdt_3_data().is_facet_constrained(mf.second)) + { + auto patch = f.first->ccdt_3_data().face_constraint_index(f.second); + f.first->set_surface_patch_index(f.second, patch); + mf.first->set_surface_patch_index(mf.second, patch); + } + } + } + return tr; } } // end CGAL diff --git a/TDS_3/include/CGAL/TDS_3/internal/Triangulation_ds_circulators_3.h b/TDS_3/include/CGAL/TDS_3/internal/Triangulation_ds_circulators_3.h index 3568d783b53..33bd73b2fcd 100644 --- a/TDS_3/include/CGAL/TDS_3/internal/Triangulation_ds_circulators_3.h +++ b/TDS_3/include/CGAL/TDS_3/internal/Triangulation_ds_circulators_3.h @@ -184,8 +184,6 @@ operator!=(typename Tds_::Cell_handle ch, Triangulation_ds_cell_circulator_3 class Triangulation_ds_facet_circulator_3 - : public Bidirectional_circulator_base { // circulates on facets around a given edge @@ -199,6 +197,14 @@ class Triangulation_ds_facet_circulator_3 typedef Triangulation_ds_facet_circulator_3 Facet_circulator; public: + struct Proxy_Facet; + typedef Bidirectional_circulator_tag iterator_category; + typedef Facet value_type; + typedef std::ptrdiff_t difference_type; + typedef Proxy_Facet pointer; + typedef Facet reference; + typedef std::size_t size_type; + Triangulation_ds_facet_circulator_3() : _s(), _t(), pos()