diff --git a/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h b/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h index 4fb60c08fbc..cef1af9c55f 100644 --- a/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h +++ b/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h @@ -293,6 +293,13 @@ std::size_t insert_constraints(PointIterator points_first, PointIterator points_ IndicesIterator indices_first, IndicesIterator indices_last); +/*! +splits into constraints the subconstraint graph g at vertices of degree greater than 2. + +\warning all existing constraints will be discarded. +*/ +void split_subconstraint_graph_into_constraints(); + /*! removes the constraint `cid`, without removing the points from the triangulation. */ diff --git a/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h b/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h index dad024bd902..676952750b9 100644 --- a/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h +++ b/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -315,6 +316,22 @@ public: return n; } */ + + void split_subconstraint_graph_into_constraints(const std::function& is_terminal + = std::function()) + { + internal::CTP2_graph_visitor visitor(*this); + if (is_terminal) + CGAL::split_graph_into_polylines (internal::CTP2_subconstraint_graph(*this), visitor, + [&is_terminal](Vertex_handle vh, + const internal::CTP2_subconstraint_graph&) -> bool + { + return is_terminal(vh); + }); + else + CGAL::split_graph_into_polylines (internal::CTP2_subconstraint_graph(*this), visitor); + } + Vertex_handle push_back(const Point& p) { return insert(p); diff --git a/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h b/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h new file mode 100644 index 00000000000..9e1346d3d2c --- /dev/null +++ b/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h @@ -0,0 +1,124 @@ +// Copyright (c) 2020 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Simon Giraudot + +#ifndef CGAL_CTP2_SUBCONSTRAINT_GRAPH_H +#define CGAL_CTP2_SUBCONSTRAINT_GRAPH_H + +#include + +#include +#include + +namespace CGAL +{ + +namespace internal +{ + +template +class CTP2_subconstraint_graph +{ + CTP2& ctp2; +public: + + typedef typename CTP2::Vertex_handle vertex_descriptor; + typedef typename CTP2::Subconstraint edge_descriptor; + typedef boost::undirected_tag directed_category; + typedef boost::disallow_parallel_edge_tag edge_parallel_category; + struct CTP2_graph_traversal_category : + public virtual boost::bidirectional_graph_tag, + public virtual boost::adjacency_graph_tag, + public virtual boost::edge_list_graph_tag, + public virtual boost::vertex_list_graph_tag + { }; + typedef CTP2_graph_traversal_category traversal_category; + typedef internal::Dereference_to_handle_enforcer< + CTP2, + typename CTP2::Finite_vertices_iterator, + vertex_descriptor> vertex_iterator; + + typedef typename CTP2::Subconstraint_iterator::value_type Subconstr_it_v_t; + typedef First_of_pair_property_map Subconstr_map; + typedef Property_map_to_unary_function Subconstr_uf; + typedef boost::transform_iterator edge_iterator; + + CTP2_subconstraint_graph (CTP2& ctp2) : ctp2(ctp2) { } + + friend Iterator_range vertices (const CTP2_subconstraint_graph& g) + { + return make_range (vertex_iterator(g.ctp2.finite_vertices_begin()), + vertex_iterator(g.ctp2.finite_vertices_end())); + } + + friend Iterator_range edges (const CTP2_subconstraint_graph& g) + { + return make_range (boost::make_transform_iterator(g.ctp2.subconstraints_begin(), Subconstr_uf(Subconstr_map())), + boost::make_transform_iterator(g.ctp2.subconstraints_end(), Subconstr_uf(Subconstr_map()))); + } + + friend vertex_descriptor source (edge_descriptor ed, const CTP2_subconstraint_graph& g) + { + return ed.first; + } + + friend vertex_descriptor target (edge_descriptor ed, const CTP2_subconstraint_graph& g) + { + return ed.second; + } +}; + + +template +class CTP2_graph_visitor +{ +private: + CTP2& ctp2; + std::vector to_remove; + typename CTP2::Constraint_id current; + typename CTP2::Vertex_handle latest_vertex; + +public: + + CTP2_graph_visitor (CTP2& ctp2) : ctp2 (ctp2) { } + + void start_new_polyline() + { + latest_vertex = typename CTP2::Vertex_handle(); + current = typename CTP2::Constraint_id(); + } + + void add_node (typename CTP2::Vertex_handle vh) + { + if (latest_vertex != typename CTP2::Vertex_handle()) + { + to_remove.push_back (ctp2.context(latest_vertex, vh).id()); + typename CTP2::Constraint_id cid = ctp2.insert_constraint(latest_vertex, vh); + if (current == typename CTP2::Constraint_id()) + current = cid; + else + current = ctp2.concatenate (current, cid); + } + latest_vertex = vh; + } + + void end_polyline() + { + for (typename CTP2::Constraint_id id : to_remove) + ctp2.remove_constraint(id); + to_remove.clear(); + } +}; + +} // namespace internal + +} // namespace CGAL + +#endif // CGAL_CTP2_SUBCONSTRAINT_GRAPH_H