major cleanup of Polyline_constraint_hierarchy_2

- remove all mentions of `Edge` and `Constraint`
- `Subconstraint_iterator` is renamed `Subconstraint_and_contexts_iterator` (because of its value type)
- a new `Subconstraint_iterator`, with value type `Subconstraint`
- a few unused/untested and uncompilable functions are removed from the code
- a lot of internal renamings

== Breaking changes ==

For `Constrained_triangulation_plus_2`, there are a few breaking changes...

- The value type of `subconstraints_begin()`, `subconstraints_end()`, of the range `subconstraints()` has changed to `Subconstraint` (a simple `std::pair` of vertex handles). That is actually a kind of bug-fix, because it was documented as such in the user manual.
- The new member functions `subconstraints_and_contexts_begin()`, `subconstraints_and_contexts_end()`, `subconstraints_and_contexts()` are created get the old value type (`std::pair<const Subconstraint, std::list<Context>*>`).
- A few range types have changed from `CGAL::Iterator_range<It>` to `unspecified_type`, for efficiency reasons.
- Doc fixes.

== Determinism ==

Even if it was not documented, the range `subconstraints()` is deterministic (used by Mesh_2), and `subconstraints_and_contexts()` is not.
This commit is contained in:
Laurent Rineau 2025-01-13 17:06:58 +01:00
parent 926bb0cf89
commit eafa97a862
9 changed files with 299 additions and 270 deletions

View File

@ -160,15 +160,14 @@ public:
void create_clusters(Tag_true) { void create_clusters(Tag_true) {
cluster_map.clear(); cluster_map.clear();
Unique_hash_map<Vertex_handle,bool> created(false); Unique_hash_map<Vertex_handle,bool> created(false);
for(typename Tr::Subconstraint_iterator it = tr.subconstraints_begin(); for(const auto& sc : tr.subconstraints()) {
it != tr.subconstraints_end(); ++it) { Vertex_handle vh = sc.first;
Vertex_handle vh = it->first.first;
if(!created[vh]){ if(!created[vh]){
created[vh] = true; created[vh] = true;
create_clusters_of_vertex(vh); create_clusters_of_vertex(vh);
} }
vh = it->first.second; vh = sc.second;
if(!created[vh]){ if(!created[vh]){
created[vh] = true; created[vh] = true;
create_clusters_of_vertex(vh); create_clusters_of_vertex(vh);

View File

@ -344,7 +344,7 @@ protected:
void scan_triangulation_impl(Tag_true) void scan_triangulation_impl(Tag_true)
{ {
for(const auto& [v1, v2] : tr.hierarchy_ref().edges()) for(const auto& [v1, v2] : tr.subconstraints())
{ {
if(!is_locally_conform(tr, v1, v2) ){ if(!is_locally_conform(tr, v1, v2) ){
add_constrained_edge_to_be_conformed(v1, v2); add_constrained_edge_to_be_conformed(v1, v2);

View File

@ -18,15 +18,7 @@ int main()
std::pair<Vertex_handle,Vertex_handle> p; std::pair<Vertex_handle,Vertex_handle> p;
for(CDT::Subconstraint_iterator sit = cdt.subconstraints_begin(); for(const auto& [vh1, vh2] : cdt.subconstraints()) {
sit != cdt.subconstraints_end();
++sit){
p = (*sit).first;
Vertex_handle vh1 = p.first;
Vertex_handle vh2 = p.second;
std::cerr << "subconstraint: " << vh1->point() << " -- " << vh2->point() << std::endl; std::cerr << "subconstraint: " << vh1->point() << " -- " << vh2->point() << std::endl;
} }
@ -36,15 +28,8 @@ int main()
int counter = 0; int counter = 0;
for(CDT::Subconstraint_iterator sit = cdt.subconstraints_begin(); for(const auto& [vh1, vh2] : cdt.subconstraints()) {
sit != cdt.subconstraints_end();
++sit){
++counter; ++counter;
p = (*sit).first;
Vertex_handle vh1 = p.first;
Vertex_handle vh2 = p.second;
std::cerr << "subconstraint: " << vh1->point() << " -- " << vh2->point() << std::endl; std::cerr << "subconstraint: " << vh1->point() << " -- " << vh2->point() << std::endl;
} }

View File

@ -84,9 +84,10 @@ The value type of this iterator is `Constraint_id`.
typedef unspecified_type Constraint_iterator; typedef unspecified_type Constraint_iterator;
/*! /*!
A range type for iterating over all constraints. A range type for iterating over all constraints. The iterator type of
the range is `Constraint_iterator`.
*/ */
typedef Iterator_range<Constraint_iterator> Constraints; typedef unspecified_type Constraints;
/*! /*!
@ -95,19 +96,30 @@ A subconstraint is a pair of vertices that correspond to an `Edge`.
typedef std::pair<Vertex_handle, Vertex_handle> Subconstraint; typedef std::pair<Vertex_handle, Vertex_handle> Subconstraint;
/*! /*!
An iterator An iterator to visit all the subconstraints of the triangulation.
to visit all the subconstraints of the triangulation.
The order of visit is undefined. The order of visit is undefined.
The value type of this iterator is `std::pair<Subconstraint,std::list<Context>*>` The value type of this iterator is `Subconstraint`.
corresponding to the vertices of the
subconstraint.
*/ */
typedef unspecified_type Subconstraint_iterator; typedef unspecified_type Subconstraint_iterator;
/*! /*!
A range type for iterating over all subconstraints. A range type for iterating over all subconstraints. The iterator type of
the range is `Subconstraint_iterator`.
*/ */
typedef Iterator_range<Subconstraint_iterator> Subconstraints; typedef unspecified_type Subconstraints;
/*!
An iterator to visit all the subconstraints of the triangulation and the
contexts of their enclosing constraints. The order of visit is undefined.
The value type of this iterator is `std::pair<const Subconstraint, std::list<Context>*>`.
*/
typedef unspecified_type Subconstraint_and_contexts_iterator;
/*!
A range type for iterating over all subconstraints. The iterator type of
the range is `Subconstraint_and_contexts_iterator`.
*/
typedef unspecified_type Subconstraints_and_contexts;
/*! /*!
An iterator on the An iterator on the
@ -381,6 +393,22 @@ returns a range of subconstraints.
*/ */
Subconstraints subconstraints() const; Subconstraints subconstraints() const;
/*!
returns a `Subconstraint_and_contexts_iterator` pointing at the first
subconstraint of the triangulation.
*/
Subconstraint_and_contexts_iterator subconstraints_and_contexts_begin() const;
/*!
returns the past-the-end iterator of the subconstraints of the triangulation.
*/
Subconstraint_and_contexts_iterator subconstraints_and_contexts_end() const;
/*!
returns a range of subconstraints with the contexts of their enclosing constraints.
*/
Subconstraints_and_contexts subconstraints_and_contexts() const;
/*! /*!
returns the number of constraints enclosing the subconstraint returns the number of constraints enclosing the subconstraint
`(va,vb)`. `(va,vb)`.

View File

@ -30,15 +30,15 @@ main( )
cdt.insert_constraint( Point(j,0), Point(j,6)); cdt.insert_constraint( Point(j,0), Point(j,6));
int count = 0; int count = 0;
for (Triangulation::Subconstraint_iterator scit = cdt.subconstraints_begin(); for (const Triangulation::Subconstraint& sc : cdt.subconstraints()) {
scit != cdt.subconstraints_end(); ++count;
++scit) ++count; }
std::cout << "The number of resulting constrained edges is "; std::cout << "The number of resulting constrained edges is ";
std::cout << count << std::endl; std::cout << count << std::endl;
//verbose mode of is_valid ; shows the number of vertices at each level //verbose mode of is_valid ; shows the number of vertices at each level
std::cout << "The number of vertices at successive levels" << std::endl; std::cout << "The number of vertices at successive levels" << std::endl;
assert(cdt.is_valid(true)); bool valid = cdt.is_valid(true);
return 0; return valid ? 0 : 1;
} }

View File

@ -28,13 +28,14 @@ print(const CDTP& cdtp, Cid cid)
void void
contexts(const CDTP& cdtp) contexts(const CDTP& cdtp)
{ {
for(auto sc : cdtp.subconstraints()){ for(const auto& sc_and_contexts : cdtp.subconstraints_and_contexts()) {
Vertex_handle vp = sc.first.first, vq = sc.first.second; const auto& [subconstraint, contexts_list_ptr] = sc_and_contexts;
Vertex_handle vp = subconstraint.first, vq = subconstraint.second;
if(cdtp.number_of_enclosing_constraints(vp, vq) == 2){ if(cdtp.number_of_enclosing_constraints(vp, vq) == 2){
std::cout << "subconstraint " << vp->point() << " " << vq->point() std::cout << "subconstraint " << vp->point() << " " << vq->point()
<< " is on constraints starting at:\n"; << " is on constraints starting at:\n";
for(const CDTP::Context& c : cdtp.contexts(vp,vq)){ for(const CDTP::Context& c : *contexts_list_ptr) {
std::cout << (*(c.vertices_begin()))->point() << std::endl; std::cout << (*(c.vertices_begin()))->point() << std::endl;
} }
} }

View File

@ -165,11 +165,14 @@ public:
typedef typename Constraint_hierarchy::Context_iterator Context_iterator; typedef typename Constraint_hierarchy::Context_iterator Context_iterator;
typedef Iterator_range<Context_iterator> Contexts; typedef Iterator_range<Context_iterator> Contexts;
typedef typename Constraint_hierarchy::C_iterator Constraint_iterator; typedef typename Constraint_hierarchy::Constraint_iterator Constraint_iterator;
typedef Iterator_range<Constraint_iterator> Constraints; typedef typename Constraint_hierarchy::Constraints Constraints;
typedef typename Constraint_hierarchy::Subconstraint_iterator Subconstraint_iterator; typedef typename Constraint_hierarchy::Subconstraint_iterator Subconstraint_iterator;
typedef Iterator_range<Subconstraint_iterator> Subconstraints; typedef typename Constraint_hierarchy::Subconstraints Subconstraints;
typedef typename Constraint_hierarchy::Subconstraint_and_contexts_iterator Subconstraint_and_contexts_iterator;
typedef typename Constraint_hierarchy::Subconstraints_and_contexts Subconstraints_and_contexts;
typedef typename Constraint_hierarchy::Constraint_id Constraint_id; typedef typename Constraint_hierarchy::Constraint_id Constraint_id;
@ -768,18 +771,15 @@ public:
// Query of the constraint hierarchy // Query of the constraint hierarchy
Constraint_iterator constraints_begin() const; Constraint_iterator constraints_begin() const;
Constraint_iterator constraints_end() const; Constraint_iterator constraints_end() const;
Constraints constraints() const Constraints constraints() const;
{
return Constraints(constraints_begin(),constraints_end());
}
Subconstraint_iterator subconstraints_begin() const; Subconstraint_iterator subconstraints_begin() const;
Subconstraint_iterator subconstraints_end() const; Subconstraint_iterator subconstraints_end() const;
Subconstraints subconstraints() const;
Subconstraints subconstraints() const Subconstraint_and_contexts_iterator subconstraints_and_contexts_begin() const;
{ Subconstraint_and_contexts_iterator subconstraints_and_contexts_end() const;
return Subconstraints(subconstraints_begin(),subconstraints_end()); Subconstraints_and_contexts subconstraints_and_contexts() const;
}
Context context(Vertex_handle va, Vertex_handle vb); //AF: const; Context context(Vertex_handle va, Vertex_handle vb); //AF: const;
@ -1266,7 +1266,7 @@ Constrained_triangulation_plus_2<Tr>::Constraint_iterator
Constrained_triangulation_plus_2<Tr>:: Constrained_triangulation_plus_2<Tr>::
constraints_begin() const constraints_begin() const
{ {
return hierarchy.c_begin(); return hierarchy.constraints_begin();
} }
template <class Tr> template <class Tr>
@ -1276,7 +1276,17 @@ Constrained_triangulation_plus_2<Tr>::Constraint_iterator
Constrained_triangulation_plus_2<Tr>:: Constrained_triangulation_plus_2<Tr>::
constraints_end() const constraints_end() const
{ {
return hierarchy.c_end(); return hierarchy.constraints_end();
}
template <class Tr>
inline
typename
Constrained_triangulation_plus_2<Tr>::Constraints
Constrained_triangulation_plus_2<Tr>::
constraints() const
{
return hierarchy.constraints();
} }
template <class Tr> template <class Tr>
@ -1286,7 +1296,7 @@ Constrained_triangulation_plus_2<Tr>::Subconstraint_iterator
Constrained_triangulation_plus_2<Tr>:: Constrained_triangulation_plus_2<Tr>::
subconstraints_begin() const subconstraints_begin() const
{ {
return hierarchy.subconstraint_begin(); return hierarchy.subconstraints_begin();
} }
template <class Tr> template <class Tr>
@ -1296,9 +1306,48 @@ Constrained_triangulation_plus_2<Tr>::Subconstraint_iterator
Constrained_triangulation_plus_2<Tr>:: Constrained_triangulation_plus_2<Tr>::
subconstraints_end() const subconstraints_end() const
{ {
return hierarchy.subconstraint_end(); return hierarchy.subconstraints_end();
} }
template <class Tr>
inline
typename
Constrained_triangulation_plus_2<Tr>::Subconstraints
Constrained_triangulation_plus_2<Tr>::
subconstraints() const
{
return hierarchy.subconstraints();
}
template <class Tr>
inline
typename
Constrained_triangulation_plus_2<Tr>::Subconstraint_and_contexts_iterator
Constrained_triangulation_plus_2<Tr>::
subconstraints_and_contexts_begin() const
{
return hierarchy.subconstraints_and_contexts_begin();
}
template <class Tr>
inline
typename
Constrained_triangulation_plus_2<Tr>::Subconstraint_and_contexts_iterator
Constrained_triangulation_plus_2<Tr>::
subconstraints_and_contexts_end() const
{
return hierarchy.subconstraints_and_contexts_end();
}
template <class Tr>
inline
typename
Constrained_triangulation_plus_2<Tr>::Subconstraints_and_contexts
Constrained_triangulation_plus_2<Tr>::
subconstraints_and_contexts() const
{
return hierarchy.subconstraints_and_contexts();
}
template <class Tr> template <class Tr>
inline inline
@ -1325,7 +1374,7 @@ inline bool
Constrained_triangulation_plus_2<Tr>:: Constrained_triangulation_plus_2<Tr>::
is_subconstraint(Vertex_handle va, Vertex_handle vb) is_subconstraint(Vertex_handle va, Vertex_handle vb)
{ {
return hierarchy.is_subconstrained_edge(va,vb); return hierarchy.is_subconstraint(va,vb);
} }

View File

@ -1,4 +1,4 @@
// Copyright (c) 2020 GeometryFactory (France). All rights reserved. // Copyright (c) 2020,2025 GeometryFactory (France). All rights reserved.
// //
// This file is part of CGAL (www.cgal.org) // This file is part of CGAL (www.cgal.org)
// //
@ -17,8 +17,6 @@
#include <CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h> #include <CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h>
#include <CGAL/boost/graph/split_graph_into_polylines.h> #include <CGAL/boost/graph/split_graph_into_polylines.h>
#include <CGAL/property_map.h>
namespace CGAL namespace CGAL
{ {
@ -30,90 +28,71 @@ class CTP2_subconstraint_graph
{ {
CTP2& ctp2; CTP2& ctp2;
public: public:
using vertex_descriptor = typename CTP2::Vertex_handle;
using edge_descriptor = typename CTP2::Subconstraint;
using directed_category = boost::undirected_tag;
using edge_parallel_category = boost::disallow_parallel_edge_tag;
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
{};
using traversal_category = CTP2_graph_traversal_category;
using vertex_iterator =
internal::Dereference_to_handle_enforcer<CTP2, typename CTP2::Finite_vertices_iterator, vertex_descriptor>;
typedef typename CTP2::Vertex_handle vertex_descriptor; using edge_iterator = typename CTP2::Subconstraint_iterator;
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; CTP2_subconstraint_graph(CTP2& ctp2)
typedef First_of_pair_property_map<Subconstr_it_v_t> Subconstr_map; : ctp2(ctp2) {}
typedef Property_map_to_unary_function<Subconstr_map> Subconstr_uf;
typedef boost::transform_iterator<Subconstr_uf, typename CTP2::Subconstraint_iterator> edge_iterator;
CTP2_subconstraint_graph (CTP2& ctp2) : ctp2(ctp2) { } friend Iterator_range<vertex_iterator> 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<vertex_iterator> 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<edge_iterator> edges (const CTP2_subconstraint_graph& g) friend Iterator_range<edge_iterator> edges(const CTP2_subconstraint_graph& g) {
{ return g.ctp2.subconstraints();
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&) friend vertex_descriptor source(edge_descriptor ed, const CTP2_subconstraint_graph&) { return ed.first; }
{
return ed.first;
}
friend vertex_descriptor target (edge_descriptor ed, const CTP2_subconstraint_graph&) friend vertex_descriptor target(edge_descriptor ed, const CTP2_subconstraint_graph&) { return ed.second; }
{
return ed.second;
}
}; };
template <typename CTP2> template <typename CTP2>
class CTP2_graph_visitor class CTP2_graph_visitor
{ {
private: private:
using Constraint_id = typename CTP2::Constraint_id;
using Vertex_handle = typename CTP2::Vertex_handle;
CTP2& ctp2; CTP2& ctp2;
std::vector<typename CTP2::Constraint_id> to_remove; std::vector<Constraint_id> to_remove;
typename CTP2::Constraint_id current; Constraint_id current{};
typename CTP2::Vertex_handle latest_vertex; Vertex_handle latest_vertex{};
public: public:
CTP2_graph_visitor(CTP2& ctp2)
: ctp2(ctp2) {}
CTP2_graph_visitor (CTP2& ctp2) : ctp2 (ctp2) { } void start_new_polyline() {
latest_vertex = Vertex_handle();
void start_new_polyline() current = Constraint_id();
{
latest_vertex = typename CTP2::Vertex_handle();
current = typename CTP2::Constraint_id();
} }
void add_node (typename CTP2::Vertex_handle vh) void add_node(Vertex_handle vh) {
{ if(latest_vertex != Vertex_handle()) {
if (latest_vertex != typename CTP2::Vertex_handle()) to_remove.push_back(ctp2.context(latest_vertex, vh).id());
{ Constraint_id cid = ctp2.insert_constraint(latest_vertex, vh);
to_remove.push_back (ctp2.context(latest_vertex, vh).id()); if(current == Constraint_id())
typename CTP2::Constraint_id cid = ctp2.insert_constraint(latest_vertex, vh);
if (current == typename CTP2::Constraint_id())
current = cid; current = cid;
else else
current = ctp2.concatenate (current, cid); current = ctp2.concatenate(current, cid);
} }
latest_vertex = vh; latest_vertex = vh;
} }
void end_polyline() void end_polyline() {
{ for(Constraint_id id : to_remove)
for (typename CTP2::Constraint_id id : to_remove)
ctp2.remove_constraint(id); ctp2.remove_constraint(id);
to_remove.clear(); to_remove.clear();
} }

View File

@ -45,8 +45,6 @@ class Polyline_constraint_hierarchy_2
{ {
public: public:
typedef T Vertex_handle; typedef T Vertex_handle;
typedef std::pair<T, T> Edge;
typedef std::pair<T, T> Constraint;
typedef std::pair<T, T> Subconstraint; typedef std::pair<T, T> Subconstraint;
using size_type = std::size_t; using size_type = std::size_t;
@ -125,9 +123,10 @@ public:
Vertex_list_ptr vl_ptr() const { return vl; } Vertex_list_ptr vl_ptr() const { return vl; }
operator std::pair<Edge, Vertex_list_ptr>() const{ operator std::pair<Subconstraint, Vertex_list_ptr>() const {
Edge edge = vl == nullptr ? Edge() : Edge(vl->front().vertex(), vl->back().vertex()); Subconstraint subconstraint =
return std::make_pair(edge, vl); vl == nullptr ? Subconstraint() : Subconstraint(vl->front().vertex(), vl->back().vertex());
return { subconstraint, vl };
} }
Constraint_id& operator=(std::nullptr_t) { Constraint_id& operator=(std::nullptr_t) {
@ -173,11 +172,11 @@ public:
public: public:
Pair_compare(const Compare& comp) : comp(comp) {} Pair_compare(const Compare& comp) : comp(comp) {}
bool operator()(const Edge& e1, const Edge& e2) const { bool operator()(const Subconstraint& sc1, const Subconstraint& sc2) const {
if(comp(e1.first, e2.first)) { if(comp(sc1.first, sc2.first)) {
return true; return true;
} else if((! comp(e2.first, e1.first)) && // !less(e1,e2) && !less(e2,e1) == equal } else if((! comp(sc2.first, sc1.first)) && // !less(sc1,sc2) && !less(sc2,sc1) == equal
comp(e1.second, e2.second)) { comp(sc1.second, sc2.second)) {
return true; return true;
} else { } else {
return false; return false;
@ -203,57 +202,61 @@ public:
typedef std::list<Context> Context_list; typedef std::list<Context> Context_list;
typedef typename Context_list::iterator Context_iterator; typedef typename Context_list::iterator Context_iterator;
typedef std::set<Constraint_id> Constraint_set; typedef std::set<Constraint_id> Constraints_set;
#if CGAL_USE_BARE_STD_MAP #if CGAL_USE_BARE_STD_MAP
typedef std::map<Edge, Context_list*, typedef std::map<Subconstraint, Context_list*,
Pair_compare> Sc_to_c_map; Pair_compare> Sc_to_c_map;
#else #else
typedef CGAL::unordered_flat_map<Edge, Context_list*, boost::hash<Edge>> Sc_to_c_map; typedef CGAL::unordered_flat_map<Subconstraint, Context_list*,
boost::hash<Subconstraint>> Sc_to_c_map;
#endif #endif
typedef typename Constraint_set::iterator C_iterator; typedef typename Constraints_set::iterator Constraint_iterator;
typedef const Constraints_set& Constraints;
typedef typename Sc_to_c_map::const_iterator Sc_iterator; typedef typename Sc_to_c_map::const_iterator Sc_iterator;
typedef Sc_iterator Subconstraint_iterator; typedef Sc_iterator Subconstraint_and_contexts_iterator;
typedef const Sc_to_c_map& Subconstraints_and_contexts;
class Edge_iterator : public boost::stl_interfaces::proxy_iterator_interface< class Subconstraint_iterator : public boost::stl_interfaces::proxy_iterator_interface<
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS #if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
Edge_iterator, Subconstraint_iterator,
#endif #endif
std::bidirectional_iterator_tag, std::bidirectional_iterator_tag,
Edge> Subconstraint>
{ {
using base_type = boost::stl_interfaces::proxy_iterator_interface< using base_type = boost::stl_interfaces::proxy_iterator_interface<
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS #if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
Edge_iterator, Subconstraint_iterator,
#endif #endif
std::bidirectional_iterator_tag, std::bidirectional_iterator_tag,
Edge>; Subconstraint>;
const Constraint_set* constraint_set = nullptr; const Constraints_set* constraints_set = nullptr;
C_iterator constraint_it{}; Constraint_iterator constraint_it{};
Vertex_it vertex_it{}; Vertex_it vertex_it{};
public: public:
// - The object is singular if and only if `constraint_set==nullptr`. // - The object is singular if and only if `constraints_set==nullptr`.
// //
// - The end value is when `constraint_it` is the end iterator of `constraint_set`. // - The end value is when `constraint_it` is the end iterator of `constraints_set`.
// In that case `vertex_it` must be singular. // In that case `vertex_it` must be singular.
// //
// - Otherwise all members must be valid pointers or dereferencable iterators. // - Otherwise all members must be valid pointers or dereferencable iterators.
bool equal(const Edge_iterator& other) const { bool equal(const Subconstraint_iterator& other) const {
return constraint_set == other.constraint_set && return constraints_set == other.constraints_set &&
(constraint_set == nullptr || (constraint_it == other.constraint_it && vertex_it == other.vertex_it)); (constraints_set == nullptr || (constraint_it == other.constraint_it &&
vertex_it == other.vertex_it));
} }
Vertex_it first_vertex_it(C_iterator constraint_it) const { Vertex_it begin_or_null(Constraint_iterator constraint_it) const {
if(constraint_it == constraint_set->end()) { if(constraint_it == constraints_set->end()) {
return Vertex_it(); return Vertex_it();
} }
return constraint_it->begin(); return constraint_it->begin();
} }
public: public:
Edge_iterator() = default; Subconstraint_iterator() = default;
// Constructors for begin and end. The constructors are public, but only the // Constructors for begin and end. The constructors are public, but only the
// hierarchy can create an iterator of this class, through its friendship of // hierarchy can create an iterator of this class, through its friendship of
@ -262,7 +265,7 @@ public:
class Construction_access class Construction_access
{ {
private: private:
friend class Edge_iterator; friend class Subconstraint_iterator;
friend class Polyline_constraint_hierarchy_2<T, Compare, Point>; friend class Polyline_constraint_hierarchy_2<T, Compare, Point>;
static auto begin_tag() { return Begin_tag(); } static auto begin_tag() { return Begin_tag(); }
@ -275,45 +278,49 @@ public:
}; };
// //
// constructor for the begin iterator // constructor for the begin iterator
explicit Edge_iterator(Construction_access::Begin_tag, const Constraint_set* constraint_set) explicit Subconstraint_iterator(typename Construction_access::Begin_tag,
: constraint_set(constraint_set) const Constraints_set* constraints_set)
, constraint_it(constraint_set->begin()) : constraints_set(constraints_set)
, vertex_it(first_vertex_it(constraint_set->begin())) {} , constraint_it(constraints_set->begin())
, vertex_it(begin_or_null(constraints_set->begin())) {}
// //
// constructor for the end iterator // constructor for the end iterator
explicit Edge_iterator(Construction_access::End_tag, const Constraint_set* constraint_set) explicit Subconstraint_iterator(typename Construction_access::End_tag,
: constraint_set(constraint_set) const Constraints_set* constraints_set)
, constraint_it(constraint_set->end()) : constraints_set(constraints_set)
, constraint_it(constraints_set->end())
, vertex_it() {} , vertex_it() {}
Edge operator*() const { Subconstraint operator*() const {
CGAL_precondition(constraint_set != nullptr && constraint_it != constraint_set->end()); CGAL_precondition(constraints_set != nullptr && constraint_it != constraints_set->end());
CGAL_assertion(vertex_it != constraint_it->end()); CGAL_assertion(vertex_it != constraint_it->end());
CGAL_assertion(std::next(vertex_it) != constraint_it->end()); CGAL_assertion(std::next(vertex_it) != constraint_it->end());
return Edge(*vertex_it, *std::next(vertex_it)); return Subconstraint(*vertex_it, *std::next(vertex_it));
} }
friend bool operator==(const Edge_iterator& lhs, const Edge_iterator& rhs) { return lhs.equal(rhs); } friend bool operator==(const Subconstraint_iterator& lhs, const Subconstraint_iterator& rhs) {
return lhs.equal(rhs);
}
using base_type::operator++; using base_type::operator++;
Edge_iterator& operator++() { Subconstraint_iterator& operator++() {
CGAL_precondition(constraint_set != nullptr && constraint_it != constraint_set->end()); CGAL_precondition(constraints_set != nullptr && constraint_it != constraints_set->end());
++vertex_it; ++vertex_it;
CGAL_assertion(vertex_it != constraint_it->end()); CGAL_assertion(vertex_it != constraint_it->end());
if(std::next(vertex_it) == constraint_it->end()) { if(std::next(vertex_it) == constraint_it->end()) {
++constraint_it; ++constraint_it;
vertex_it = first_vertex_it(constraint_it); vertex_it = begin_or_null(constraint_it);
} }
return *this; return *this;
} }
using base_type::operator--; using base_type::operator--;
Edge_iterator& operator--() { Subconstraint_iterator& operator--() {
CGAL_precondition(constraint_set != nullptr); CGAL_precondition(constraints_set != nullptr);
CGAL_precondition(constraint_it != constraint_set->begin() || vertex_it != constraint_it->begin()); CGAL_precondition(constraint_it != constraints_set->begin() || vertex_it != constraint_it->begin());
if(constraint_it == constraint_set->end() || vertex_it == constraint_it->begin()) { if(constraint_it == constraints_set->end() || vertex_it == constraint_it->begin()) {
--constraint_it; --constraint_it;
vertex_it = std::prev(constraint_it->end(), 2); vertex_it = std::prev(constraint_it->end(), 2);
} else { } else {
@ -321,12 +328,12 @@ public:
} }
return *this; return *this;
} }
}; // end class Edge_iterator }; // end class Subconstraint_iterator
typedef Iterator_range<Subconstraint_iterator> Subconstraints;
private: private:
// data for the 1d hierarchy
Compare comp; Compare comp;
Constraint_set constraint_set; Constraints_set constraints_set;
Sc_to_c_map sc_to_c_map; Sc_to_c_map sc_to_c_map;
public: public:
@ -346,7 +353,7 @@ public:
Polyline_constraint_hierarchy_2& operator=(Polyline_constraint_hierarchy_2&& ch) = default; Polyline_constraint_hierarchy_2& operator=(Polyline_constraint_hierarchy_2&& ch) = default;
// Query // Query
bool is_subconstrained_edge(T va, T vb) const; bool is_subconstraint(T va, T vb) const;
Vertex_it vertices_in_constraint_begin(Constraint_id cid) const Vertex_it vertices_in_constraint_begin(Constraint_id cid) const
{ return cid.begin(); } { return cid.begin(); }
@ -361,7 +368,6 @@ public:
Point_it points_in_constraint_end(Constraint_id cid) const Point_it points_in_constraint_end(Constraint_id cid) const
{ return cid.vl_ptr()->all_end(); } { return cid.vl_ptr()->all_end(); }
bool enclosing_constraint(Edge he, Constraint& hc) const;
bool enclosing_constraint(T vaa, T vbb, T& va, T& vb) const; bool enclosing_constraint(T vaa, T vbb, T& va, T& vb) const;
bool next_along_sc(T va, T vb, T& w) const; bool next_along_sc(T va, T vb, T& w) const;
void oriented_end(T va, T vb, T& vc) const; void oriented_end(T va, T vb, T& vc) const;
@ -371,7 +377,7 @@ public:
Context_iterator contexts_begin(T va, T vb) const; Context_iterator contexts_begin(T va, T vb) const;
Context_iterator contexts_end(T va, T vb) const; Context_iterator contexts_end(T va, T vb) const;
Iterator_range<Context_iterator> contexts_range(T va, T vb) const; Iterator_range<Context_iterator> contexts_range(T va, T vb) const;
size_type number_of_constraints() const { return constraint_set.size();} size_type number_of_constraints() const { return constraints_set.size();}
size_type number_of_subconstraints()const {return sc_to_c_map.size();} size_type number_of_subconstraints()const {return sc_to_c_map.size();}
@ -399,39 +405,41 @@ public:
// iterators // iterators
Subconstraint_iterator subconstraint_begin() const Subconstraint_and_contexts_iterator subconstraints_and_contexts_begin() const
{ {
return sc_to_c_map.begin(); return sc_to_c_map.begin();
} }
Subconstraint_iterator subconstraint_end() const Subconstraint_and_contexts_iterator subconstraints_and_contexts_end() const
{ {
return sc_to_c_map.end(); return sc_to_c_map.end();
} }
Edge_iterator edges_begin() const { Subconstraint_iterator subconstraints_begin() const {
BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(Edge_iterator, std::bidirectional_iterator); BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(Subconstraint_iterator, std::bidirectional_iterator);
BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(Edge_iterator, std::bidirectional_iterator_tag, BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
std::bidirectional_iterator, Edge, Edge, Subconstraint_iterator, std::bidirectional_iterator_tag, std::bidirectional_iterator,
typename Edge_iterator::pointer, std::ptrdiff_t); Subconstraint, Subconstraint, typename Subconstraint_iterator::pointer, std::ptrdiff_t);
return Edge_iterator(Edge_iterator::Construction_access::begin_tag(), &constraint_set); return Subconstraint_iterator(Subconstraint_iterator::Construction_access::begin_tag(),
&constraints_set);
} }
Edge_iterator edges_end() const { Subconstraint_iterator subconstraints_end() const {
return Edge_iterator(Edge_iterator::Construction_access::end_tag(), &constraint_set); return Subconstraint_iterator(Subconstraint_iterator::Construction_access::end_tag(),
&constraints_set);
} }
auto edges() const { return Iterator_range<Edge_iterator>(edges_begin(), edges_end()); }
Sc_iterator sc_begin() const{ return sc_to_c_map.begin(); } Sc_iterator sc_begin() const{ return sc_to_c_map.begin(); }
Sc_iterator sc_end() const{ return sc_to_c_map.end(); } Sc_iterator sc_end() const{ return sc_to_c_map.end(); }
C_iterator c_begin() const{ return constraint_set.begin(); } Constraint_iterator constraints_begin() const{ return constraints_set.begin(); }
C_iterator c_end() const{ return constraint_set.end(); } Constraint_iterator constraints_end() const{ return constraints_set.end(); }
// Ranges // Ranges
auto constraints() const { return Iterator_range<C_iterator>(c_begin(), c_end()); } const auto& constraints() const { return constraints_set; }
const auto & subconstraints() const { return sc_to_c_map; } const auto& subconstraints_and_contexts() const { return sc_to_c_map; }
auto subconstraints() const {
return Iterator_range<Subconstraint_iterator>(subconstraints_begin(), subconstraints_end());
}
// Helper functions // Helper functions
void copy(const Polyline_constraint_hierarchy_2& ch); void copy(const Polyline_constraint_hierarchy_2& ch);
@ -440,11 +448,13 @@ public:
private: private:
Constraint_id new_constraint_id() const { Constraint_id new_constraint_id() const {
auto id = number_of_constraints() == 0 ? 0 : constraint_set.rbegin()->id + 1; auto id = number_of_constraints() == 0 ? 0 : constraints_set.rbegin()->id + 1;
return Constraint_id(new Vertex_list, id); return Constraint_id(new Vertex_list, id);
} }
Edge make_edge(T va, T vb) const; Subconstraint sorted_pair(T va, T vb) const;
Edge make_edge(Edge e) { const auto& [va, vb] = e; return make_edge(va, vb); } Subconstraint sorted_pair(Subconstraint sc) {
const auto& [va, vb] = sc; return sorted_pair(va, vb);
}
Vertex_it get_pos(T va, T vb) const; Vertex_it get_pos(T va, T vb) const;
bool get_contexts(T va, T vb, bool get_contexts(T va, T vb,
Context_iterator& ctxt, Context_iterator& ctxt,
@ -498,22 +508,22 @@ copy(const Polyline_constraint_hierarchy_2& other, std::map<Vertex_handle,Vertex
{ {
std::map<Constraint_id, Constraint_id> cstr_map; std::map<Constraint_id, Constraint_id> cstr_map;
clear(); clear();
// copy constraint_set // copy constraints_set
for(const auto& cid1: other.constraints()) { for(const auto& cid1: other.constraints()) {
Constraint_id cid2 = new_constraint_id(); Constraint_id cid2 = new_constraint_id();
cstr_map[cid1] = cid2; cstr_map[cid1] = cid2;
for(const auto& node : cid1.elements()) { for(const auto& node : cid1.elements()) {
cid2.vl_ptr()->push_back(Node(vmap[node.vertex()], node.input())); cid2.vl_ptr()->push_back(Node(vmap[node.vertex()], node.input()));
} }
constraint_set.insert(cid2); constraints_set.insert(cid2);
} }
// copy sc_to_c_map // copy sc_to_c_map
for(const auto& [edge1, hcl1] : other.subconstraints()) { for(const auto& [sc1, hcl1] : other.subconstraints_and_contexts()) {
Context_list* hcl2 = new Context_list; Context_list* hcl2 = new Context_list;
Vertex_handle uu2 = vmap[edge1.first]; Vertex_handle uu2 = vmap[sc1.first];
Vertex_handle vv2 = vmap[edge1.second]; Vertex_handle vv2 = vmap[sc1.second];
Edge edge2 = make_edge(uu2, vv2); Subconstraint sc2 = sorted_pair(uu2, vv2);
sc_to_c_map[edge2] = hcl2; sc_to_c_map[sc2] = hcl2;
for(const Context& ctxt1 : *hcl1) { for(const Context& ctxt1 : *hcl1) {
// vertices of the enclosing constraints // vertices of the enclosing constraints
Context ctxt2; Context ctxt2;
@ -540,37 +550,16 @@ swap(Polyline_constraint_hierarchy_2& ch)
{ {
using std::swap; using std::swap;
swap(comp, ch.comp); swap(comp, ch.comp);
constraint_set.swap(ch.constraint_set); constraints_set.swap(ch.constraints_set);
sc_to_c_map.swap(ch.sc_to_c_map); sc_to_c_map.swap(ch.sc_to_c_map);
} }
/*
template <class T, class Compare, class Point> template <class T, class Compare, class Point>
bool Polyline_constraint_hierarchy_2<T,Compare,Point>:: bool Polyline_constraint_hierarchy_2<T,Compare,Point>::
is_constrained_edge(T va, T vb) const is_subconstraint(T va, T vb) const
{ {
return( c_to_sc_map.find(make_edge(va, vb)) != c_to_sc_map.end() ); return( sc_to_c_map.find(sorted_pair(va, vb)) != sc_to_c_map.end() );
}
*/
template <class T, class Compare, class Point>
bool Polyline_constraint_hierarchy_2<T,Compare,Point>::
is_subconstrained_edge(T va, T vb) const
{
return( sc_to_c_map.find(make_edge(va, vb)) != sc_to_c_map.end() );
}
// af: obsolete
template <class T, class Compare, class Point>
bool Polyline_constraint_hierarchy_2<T,Compare,Point>::
enclosing_constraint(Edge he, Constraint& hc) const
{
Context_iterator hcit, past;
if ( !get_contexts(he.first,he.second, hcit ,past)) return false;
hc = make_edge(hcit->enclosing.front(), hcit->enclosing.back());
return true;
} }
@ -659,7 +648,7 @@ swap(Constraint_id constr_a, Constraint_id constr_b) {
auto substitute_enclosing_in_vertex_list = [this](Vertex_list_ptr vl, Constraint_id old_id, Constraint_id new_id) { auto substitute_enclosing_in_vertex_list = [this](Vertex_list_ptr vl, Constraint_id old_id, Constraint_id new_id) {
// We have to look at all subconstraints // We have to look at all subconstraints
for(Vertex_it it = vl->skip_begin(), succ = it, end = vl->skip_end(); ++succ != end; ++it) { for(Vertex_it it = vl->skip_begin(), succ = it, end = vl->skip_end(); ++succ != end; ++it) {
typename Sc_to_c_map::iterator scit = this->sc_to_c_map.find(make_edge(*it, *succ)); typename Sc_to_c_map::iterator scit = this->sc_to_c_map.find(sorted_pair(*it, *succ));
CGAL_assertion(scit != this->sc_to_c_map.end()); CGAL_assertion(scit != this->sc_to_c_map.end());
Context_list* hcl = scit->second; Context_list* hcl = scit->second;
@ -687,13 +676,13 @@ template <class T, class Compare, class Point>
void void
Polyline_constraint_hierarchy_2<T,Compare,Point>:: Polyline_constraint_hierarchy_2<T,Compare,Point>::
remove_constraint(Constraint_id cid){ remove_constraint(Constraint_id cid){
constraint_set.erase(cid); constraints_set.erase(cid);
// We have to look at all subconstraints // We have to look at all subconstraints
for(Vertex_it it = cid.begin(), succ = it, end = cid.end(); for(Vertex_it it = cid.begin(), succ = it, end = cid.end();
++succ != end; ++succ != end;
++it){ ++it){
typename Sc_to_c_map::iterator scit = sc_to_c_map.find(make_edge(*it,*succ)); typename Sc_to_c_map::iterator scit = sc_to_c_map.find(sorted_pair(*it,*succ));
CGAL_assertion(scit != sc_to_c_map.end()); CGAL_assertion(scit != sc_to_c_map.end());
Context_list* hcl = scit->second; Context_list* hcl = scit->second;
@ -722,14 +711,13 @@ remove_constraint(Constraint_id cid){
// and for the case that the constrained edge u,w has no intersections // and for the case that the constrained edge u,w has no intersections
template <class T, class Compare, class Point> template <class T, class Compare, class Point>
void Polyline_constraint_hierarchy_2<T,Compare,Point>::simplify(Vertex_it uc, void Polyline_constraint_hierarchy_2<T,Compare,Point>::simplify(Vertex_it uc,
Vertex_it vc, Vertex_it vc,
Vertex_it wc) Vertex_it wc)
{ {
// TODO: How do we (want to) deal with u == w ??? // TODO: How do we (want to) deal with u == w ???
Vertex_handle u = *uc, v = *vc, w = *wc; Vertex_handle u = *uc, v = *vc, w = *wc;
typename Sc_to_c_map::iterator uv_sc_iter = sc_to_c_map.find(make_edge(u, v)); typename Sc_to_c_map::iterator uv_sc_iter = sc_to_c_map.find(sorted_pair(u, v));
typename Sc_to_c_map::iterator vw_sc_iter = sc_to_c_map.find(make_edge(v, w)); typename Sc_to_c_map::iterator vw_sc_iter = sc_to_c_map.find(sorted_pair(v, w));
Context_list* uv_hcl = uv_sc_iter->second; Context_list* uv_hcl = uv_sc_iter->second;
Context_list* vw_hcl = vw_sc_iter->second; Context_list* vw_hcl = vw_sc_iter->second;
// AF: what is input() about??? // AF: what is input() about???
@ -777,7 +765,7 @@ void Polyline_constraint_hierarchy_2<T,Compare,Point>::simplify(Vertex_it uc,
sc_to_c_map.erase(vw_sc_iter); sc_to_c_map.erase(vw_sc_iter);
// reuse other context list // reuse other context list
sc_to_c_map[make_edge(u,w)] = uv_hcl; sc_to_c_map[sorted_pair(u,w)] = uv_hcl;
} }
@ -803,8 +791,8 @@ typename Polyline_constraint_hierarchy_2<T,Compare,Point>::size_type
Polyline_constraint_hierarchy_2<T,Compare,Point>::remove_points_without_corresponding_vertex() Polyline_constraint_hierarchy_2<T,Compare,Point>::remove_points_without_corresponding_vertex()
{ {
size_type n = 0; size_type n = 0;
for(C_iterator it = constraint_set.begin(); it!= constraint_set.end(); ++it){ for(const auto& cid : constraints_set){
n+= remove_points_without_corresponding_vertex(*it); n+= remove_points_without_corresponding_vertex(cid);
} }
return n; return n;
} }
@ -817,13 +805,13 @@ Polyline_constraint_hierarchy_2<T,Compare,Point>::concatenate(Constraint_id cons
// std::cerr << std::format("concatenate({}, {}) ", constr_a.id, constr_b.id) << std::endl; // std::cerr << std::format("concatenate({}, {}) ", constr_a.id, constr_b.id) << std::endl;
Vertex_list_ptr constr_a_vl = constr_a.vl_ptr(); Vertex_list_ptr constr_a_vl = constr_a.vl_ptr();
Vertex_list_ptr constr_b_vl = constr_b.vl_ptr(); Vertex_list_ptr constr_b_vl = constr_b.vl_ptr();
constraint_set.erase(constr_a); constraints_set.erase(constr_a);
constraint_set.erase(constr_b); constraints_set.erase(constr_b);
// We have to look at all subconstraints // We have to look at all subconstraints
for(Vertex_it it = constr_b_vl->skip_begin(), succ = it, end = constr_b_vl->skip_end(); for(Vertex_it it = constr_b_vl->skip_begin(), succ = it, end = constr_b_vl->skip_end();
++succ != end; ++succ != end;
++it){ ++it){
typename Sc_to_c_map::iterator scit = sc_to_c_map.find(make_edge(*it,*succ)); typename Sc_to_c_map::iterator scit = sc_to_c_map.find(sorted_pair(*it,*succ));
CGAL_assertion(scit != sc_to_c_map.end()); CGAL_assertion(scit != sc_to_c_map.end());
Context_list* hcl = scit->second; Context_list* hcl = scit->second;
@ -848,7 +836,7 @@ Polyline_constraint_hierarchy_2<T,Compare,Point>::concatenate(Constraint_id cons
for(Vertex_it it = back_it, succ = it, end = constr_a_vl->skip_end(); for(Vertex_it it = back_it, succ = it, end = constr_a_vl->skip_end();
++succ != end; ++succ != end;
++it){ ++it){
typename Sc_to_c_map::iterator scit = sc_to_c_map.find(make_edge(*it,*succ)); typename Sc_to_c_map::iterator scit = sc_to_c_map.find(sorted_pair(*it,*succ));
CGAL_assertion(scit != sc_to_c_map.end()); CGAL_assertion(scit != sc_to_c_map.end());
Context_list* hcl = scit->second; Context_list* hcl = scit->second;
@ -860,7 +848,7 @@ Polyline_constraint_hierarchy_2<T,Compare,Point>::concatenate(Constraint_id cons
} }
} }
} }
constraint_set.insert(constr_a); constraints_set.insert(constr_a);
delete constr_b_vl; delete constr_b_vl;
return constr_a; return constr_a;
@ -872,13 +860,13 @@ Polyline_constraint_hierarchy_2<T,Compare,Point>::concatenate2(Constraint_id con
{ {
Vertex_list_ptr constr_a_vl = constr_a.vl_ptr(); Vertex_list_ptr constr_a_vl = constr_a.vl_ptr();
Vertex_list_ptr constr_b_vl = constr_b.vl_ptr(); Vertex_list_ptr constr_b_vl = constr_b.vl_ptr();
constraint_set.erase(constr_a); constraints_set.erase(constr_a);
constraint_set.erase(constr_b); constraints_set.erase(constr_b);
// We have to look at all subconstraints // We have to look at all subconstraints
for(Vertex_it it = constr_a_vl->skip_begin(), succ = it, end = constr_a_vl->skip_end(); for(Vertex_it it = constr_a_vl->skip_begin(), succ = it, end = constr_a_vl->skip_end();
++succ != end; ++succ != end;
++it){ ++it){
typename Sc_to_c_map::iterator scit = sc_to_c_map.find(make_edge(*it,*succ)); typename Sc_to_c_map::iterator scit = sc_to_c_map.find(sorted_pair(*it,*succ));
CGAL_assertion(scit != sc_to_c_map.end()); CGAL_assertion(scit != sc_to_c_map.end());
Context_list* hcl = scit->second; Context_list* hcl = scit->second;
@ -902,7 +890,7 @@ Polyline_constraint_hierarchy_2<T,Compare,Point>::concatenate2(Constraint_id con
for(Vertex_it it = constr_b_vl->skip_begin(), succ = it, end = back_it; for(Vertex_it it = constr_b_vl->skip_begin(), succ = it, end = back_it;
++succ != end; ++succ != end;
++it){ ++it){
typename Sc_to_c_map::iterator scit = sc_to_c_map.find(make_edge(*it,*succ)); typename Sc_to_c_map::iterator scit = sc_to_c_map.find(sorted_pair(*it,*succ));
CGAL_assertion(scit != sc_to_c_map.end()); CGAL_assertion(scit != sc_to_c_map.end());
Context_list* hcl = scit->second; Context_list* hcl = scit->second;
@ -914,7 +902,7 @@ Polyline_constraint_hierarchy_2<T,Compare,Point>::concatenate2(Constraint_id con
} }
} }
} }
constraint_set.insert(constr_b); constraints_set.insert(constr_b);
delete constr_a_vl; delete constr_a_vl;
return constr_b; return constr_b;
@ -929,7 +917,7 @@ typename Polyline_constraint_hierarchy_2<T,Compare,Point>::Constraint_id
Polyline_constraint_hierarchy_2<T,Compare,Point>::split(Constraint_id constr, Vertex_it vcit) Polyline_constraint_hierarchy_2<T,Compare,Point>::split(Constraint_id constr, Vertex_it vcit)
{ {
Constraint_id new_constr = new_constraint_id(); Constraint_id new_constr = new_constraint_id();
constraint_set.erase(constr); constraints_set.erase(constr);
Vertex_list_ptr new_vl = new_constr.vl_ptr(); Vertex_list_ptr new_vl = new_constr.vl_ptr();
Vertex_list_ptr constr_vl = constr.vl_ptr(); Vertex_list_ptr constr_vl = constr.vl_ptr();
new_vl->splice(new_vl->skip_end(), *(constr_vl), vcit.base(), constr_vl->skip_end()); new_vl->splice(new_vl->skip_end(), *(constr_vl), vcit.base(), constr_vl->skip_end());
@ -939,13 +927,13 @@ Polyline_constraint_hierarchy_2<T,Compare,Point>::split(Constraint_id constr, Ve
vit = constr_vl->skip_end(); vit = constr_vl->skip_end();
--vit; --vit;
vit.input() = true; vit.input() = true;
constraint_set.insert(constr); constraints_set.insert(constr);
constraint_set.insert(new_constr); constraints_set.insert(new_constr);
// We have to look at all subconstraints // We have to look at all subconstraints
for(Vertex_it it = new_vl->skip_begin(), succ = it, end = new_vl->skip_end(); for(Vertex_it it = new_vl->skip_begin(), succ = it, end = new_vl->skip_end();
++succ != end; ++succ != end;
++it){ ++it){
typename Sc_to_c_map::iterator scit = sc_to_c_map.find(make_edge(*it,*succ)); typename Sc_to_c_map::iterator scit = sc_to_c_map.find(sorted_pair(*it,*succ));
CGAL_assertion(scit != sc_to_c_map.end()); CGAL_assertion(scit != sc_to_c_map.end());
Context_list* hcl = scit->second; Context_list* hcl = scit->second;
@ -965,7 +953,7 @@ typename Polyline_constraint_hierarchy_2<T,Compare,Point>::Constraint_id
Polyline_constraint_hierarchy_2<T,Compare,Point>::split2(Constraint_id constr, Vertex_it vcit) Polyline_constraint_hierarchy_2<T,Compare,Point>::split2(Constraint_id constr, Vertex_it vcit)
{ {
Constraint_id new_constr = new_constraint_id(); Constraint_id new_constr = new_constraint_id();
constraint_set.erase(constr); constraints_set.erase(constr);
Vertex_list_ptr new_vl = new_constr.vl_ptr(); Vertex_list_ptr new_vl = new_constr.vl_ptr();
Vertex_list_ptr constr_vl = constr.vl_ptr(); Vertex_list_ptr constr_vl = constr.vl_ptr();
new_vl->splice(new_vl->skip_end(), *constr_vl, constr_vl->skip_begin(), vcit.base()); new_vl->splice(new_vl->skip_end(), *constr_vl, constr_vl->skip_begin(), vcit.base());
@ -975,13 +963,13 @@ Polyline_constraint_hierarchy_2<T,Compare,Point>::split2(Constraint_id constr, V
vit.input() = true; vit.input() = true;
vit = constr_vl->skip_begin(); vit = constr_vl->skip_begin();
vit.input() = true; vit.input() = true;
constraint_set.insert(constr); constraints_set.insert(constr);
constraint_set.insert(new_constr); constraints_set.insert(new_constr);
// We have to look at all subconstraints // We have to look at all subconstraints
for(Vertex_it it = new_vl->skip_begin(), succ = it, end = new_vl->skip_end(); for(Vertex_it it = new_vl->skip_begin(), succ = it, end = new_vl->skip_end();
++succ != end; ++succ != end;
++it){ ++it){
typename Sc_to_c_map::iterator scit = sc_to_c_map.find(make_edge(*it,*succ)); typename Sc_to_c_map::iterator scit = sc_to_c_map.find(sorted_pair(*it,*succ));
CGAL_assertion(scit != sc_to_c_map.end()); CGAL_assertion(scit != sc_to_c_map.end());
Context_list* hcl = scit->second; Context_list* hcl = scit->second;
@ -1011,17 +999,17 @@ insert_constraint(T va, T vb){
<< "C_hierachy.insert_constraint( " << "C_hierachy.insert_constraint( "
<< IO::oformat(va) << ", " << IO::oformat(vb) << ")\n"; << IO::oformat(va) << ", " << IO::oformat(vb) << ")\n";
#endif // CGAL_CDT_2_DEBUG_INTERSECTIONS #endif // CGAL_CDT_2_DEBUG_INTERSECTIONS
Edge he = make_edge(va, vb); Subconstraint sc = sorted_pair(va, vb);
Constraint_id cid = new_constraint_id(); Constraint_id cid = new_constraint_id();
auto children = cid.vl_ptr(); auto children = cid.vl_ptr();
auto& fathers = sc_to_c_map[he]; auto& fathers = sc_to_c_map[sc];
if(fathers == nullptr){ if(fathers == nullptr){
fathers = new Context_list; fathers = new Context_list;
} }
children->push_front(Node(va, true)); // was he.first children->push_front(Node(va, true)); // was sc.first
children->push_back(Node(vb, true)); // was he.second children->push_back(Node(vb, true)); // was sc.second
constraint_set.insert(cid); constraints_set.insert(cid);
Context ctxt; Context ctxt;
ctxt.enclosing = cid; ctxt.enclosing = cid;
ctxt.pos = children->skip_begin(); ctxt.pos = children->skip_begin();
@ -1049,8 +1037,8 @@ append_constraint(Constraint_id cid, T va, T vb){
<< "C_hierachy.append_constraint( ..., " << "C_hierachy.append_constraint( ..., "
<< IO::oformat(va) << ", " << IO::oformat(vb) << ")\n"; << IO::oformat(va) << ", " << IO::oformat(vb) << ")\n";
#endif // CGAL_CDT_2_DEBUG_INTERSECTIONS #endif // CGAL_CDT_2_DEBUG_INTERSECTIONS
Edge he = make_edge(va, vb); Subconstraint sc = sorted_pair(va, vb);
auto& fathers = sc_to_c_map[he]; auto& fathers = sc_to_c_map[sc];
if(fathers == nullptr){ if(fathers == nullptr){
fathers = new Context_list; fathers = new Context_list;
} }
@ -1080,7 +1068,7 @@ clear()
delete cl_ptr; delete cl_ptr;
} }
sc_to_c_map.clear(); sc_to_c_map.clear();
constraint_set.clear(); constraints_set.clear();
} }
@ -1176,28 +1164,28 @@ add_Steiner(T va, T vb, T vc){
hcl3->splice(hcl3->end(), *hcl); hcl3->splice(hcl3->end(), *hcl);
delete hcl; delete hcl;
} }
else sc_to_c_map.emplace(make_edge(va,vc), hcl); else sc_to_c_map.emplace(sorted_pair(va,vc), hcl);
if (get_contexts(vc,vb,hcl3)) {// (vc,vb) is already a subconstraint if (get_contexts(vc,vb,hcl3)) {// (vc,vb) is already a subconstraint
hcl3->splice(hcl3->end(),*hcl2); hcl3->splice(hcl3->end(),*hcl2);
delete hcl2; delete hcl2;
} }
else sc_to_c_map.emplace(make_edge(vc,vb), hcl2); else sc_to_c_map.emplace(sorted_pair(vc,vb), hcl2);
sc_to_c_map.erase(make_edge(va,vb)); sc_to_c_map.erase(sorted_pair(va,vb));
return; return;
} }
template <class T, class Compare, class Point> template <class T, class Compare, class Point>
inline inline
typename Polyline_constraint_hierarchy_2<T,Compare,Point>::Edge typename Polyline_constraint_hierarchy_2<T,Compare,Point>::Subconstraint
Polyline_constraint_hierarchy_2<T,Compare,Point>:: Polyline_constraint_hierarchy_2<T,Compare,Point>::
make_edge(T va, T vb) const sorted_pair(T va, T vb) const
{ {
return comp(va, vb) ? Edge(va,vb) : Edge(vb,va); return comp(va, vb) ? Subconstraint(va,vb) : Subconstraint(vb,va);
} }
template <class T, class Compare, class Point> template <class T, class Compare, class Point>
@ -1206,7 +1194,7 @@ bool
Polyline_constraint_hierarchy_2<T,Compare,Point>:: Polyline_constraint_hierarchy_2<T,Compare,Point>::
get_contexts(T va, T vb, Context_list* & hcl) const get_contexts(T va, T vb, Context_list* & hcl) const
{ {
Sc_iterator sc_iter = sc_to_c_map.find(make_edge(va,vb)); Sc_iterator sc_iter = sc_to_c_map.find(sorted_pair(va,vb));
if( sc_iter == sc_to_c_map.end() ) return(false); if( sc_iter == sc_to_c_map.end() ) return(false);
hcl = sc_iter->second; hcl = sc_iter->second;
return true; return true;
@ -1236,7 +1224,7 @@ Polyline_constraint_hierarchy_2<T,Compare,Point>::
get_pos(T va, T vb) const get_pos(T va, T vb) const
//return pos in the first context //return pos in the first context
{ {
return (*sc_to_c_map.find(make_edge(va,vb))).second->begin().pos; return (*sc_to_c_map.find(sorted_pair(va,vb))).second->begin().pos;
} }
template <class T, class Compare, class Point> template <class T, class Compare, class Point>
@ -1299,11 +1287,11 @@ print() const
} }
} }
std::cout << std::endl; std::cout << std::endl;
for(const auto& [edge, _] : subconstraints()) { for(const auto& subconstraint : subconstraints()) {
std::cout << "subconstraint "; std::cout << "subconstraint ";
std::cout << vertex_num[edge.first] << " " << vertex_num[edge.second]; std::cout << vertex_num[subconstraint.first] << " " << vertex_num[subconstraint.second];
Context_iterator cb, ce; Context_iterator cb, ce;
get_contexts(edge.first, edge.second, cb, ce); get_contexts(subconstraint.first, subconstraint.second, cb, ce);
std::cout << " enclosing "; std::cout << " enclosing ";
for(; cb != ce; cb++) { for(; cb != ce; cb++) {