Skip to content

Commit

Permalink
CDT_plus_2 hierarchy: add Edge_iterator, that is deterministic
Browse files Browse the repository at this point in the history
That uses Boost.STLInterfaces from Boost >= 1.74.
  • Loading branch information
lrineau committed Jan 10, 2025
1 parent e1adc38 commit e0ba29f
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 21 deletions.
22 changes: 1 addition & 21 deletions Mesh_2/include/CGAL/Mesh_2/Refine_edges.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,27 +344,7 @@ class Refine_edges_base :

void scan_triangulation_impl(Tag_true)
{
// with constraint hierarchy

// create a vector of pairs of vertex handles, from the subconstraints
// and sort it to ensure the determinism
std::vector<std::array<Vertex_handle, 2>> subconstraints_vector(tr.number_of_subconstraints());
std::transform(tr.subconstraints_begin(), tr.subconstraints_end(), subconstraints_vector.begin(),
[](const auto& sc) {
return std::array<Vertex_handle, 2>{sc.first.first, sc.first.second};
});

auto comp_vh = [&] (Vertex_handle va, Vertex_handle vb) {
return tr.compare_xy(va->point(), vb->point()) == SMALLER;
};
auto comp_pair_vh = [&] (const auto& e1, const auto& e2) {
return comp_vh(e1[0], e2[0]) ||
(!comp_vh(e2[0], e1[0]) && comp_vh(e1[1], e2[1]));
};

std::sort(subconstraints_vector.begin(), subconstraints_vector.end(), comp_pair_vh);

for(const auto& [v1, v2] : subconstraints_vector)
for(const auto& [v1, v2] : tr.hierarchy_ref().edges())
{
if(!is_locally_conform(tr, v1, v2) ){
add_constrained_edge_to_be_conformed(v1, v2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include <set>
#include <list>

#include <boost/stl_interfaces/iterator_interface.hpp>

#include <CGAL/unordered_flat_map.h>
#include <CGAL/Skiplist.h>
#include <CGAL/Iterator_range.h>
Expand Down Expand Up @@ -212,6 +214,115 @@ class Polyline_constraint_hierarchy_2
typedef typename Sc_to_c_map::const_iterator Sc_iterator;
typedef Sc_iterator Subconstraint_iterator;

class Edge_iterator : public boost::stl_interfaces::proxy_iterator_interface<
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
Edge_iterator,
#endif
std::bidirectional_iterator_tag,
Edge>
{
using base_type = boost::stl_interfaces::proxy_iterator_interface<
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
Edge_iterator,
#endif
std::bidirectional_iterator_tag,
Edge>;

const Constraint_set* constraint_set = nullptr;
C_iterator constraint_it{};
Vertex_it vertex_it{};

public:
// - The object is singular if and only if `constraint_set==nullptr`.
//
// - The end value is when `constraint_it` is the end iterator of `constraint_set`.
// In that case `vertex_it` must be singular.
//
// - Otherwise all members must be valid pointers or dereferencable iterators.

bool equal(const Edge_iterator& other) const {
return constraint_set == other.constraint_set &&
(constraint_set == nullptr || (constraint_it == other.constraint_it && vertex_it == other.vertex_it));
}

Vertex_it first_vertex_it(C_iterator constraint_it) const {
if(constraint_it == constraint_set->end()) {
return Vertex_it();
}
return constraint_it->begin();
}

public:
Edge_iterator() = default;

// Constructors for begin and end. The constructors are public, but only the
// hierarchy can create an iterator of this class, through its friendship of
// the nested class `Construction_access`: Construction_access::begin_tag() and
// Construction_access::end_tag().
class Construction_access
{
private:
friend class Edge_iterator;
friend class Polyline_constraint_hierarchy_2<T, Compare, Point>;

static auto begin_tag() { return Begin_tag(); }
static auto end_tag() { return End_tag(); }

struct Begin_tag
{};
struct End_tag
{};
};
//
// constructor for the begin iterator
explicit Edge_iterator(Construction_access::Begin_tag, const Constraint_set* constraint_set)
: constraint_set(constraint_set)
, constraint_it(constraint_set->begin())
, vertex_it(first_vertex_it(constraint_set->begin())) {}
//
// constructor for the end iterator
explicit Edge_iterator(Construction_access::End_tag, const Constraint_set* constraint_set)
: constraint_set(constraint_set)
, constraint_it(constraint_set->end())
, vertex_it() {}

Edge operator*() const {
CGAL_precondition(constraint_set != nullptr && constraint_it != constraint_set->end());
CGAL_assertion(vertex_it != constraint_it->end());
CGAL_assertion(std::next(vertex_it) != constraint_it->end());
return Edge(*vertex_it, *std::next(vertex_it));
}

friend bool operator==(const Edge_iterator& lhs, const Edge_iterator& rhs) { return lhs.equal(rhs); }

using base_type::operator++;
Edge_iterator& operator++() {
CGAL_precondition(constraint_set != nullptr && constraint_it != constraint_set->end());

++vertex_it;
CGAL_assertion(vertex_it != constraint_it->end());

if(std::next(vertex_it) == constraint_it->end()) {
++constraint_it;
vertex_it = first_vertex_it(constraint_it);
}
return *this;
}

using base_type::operator--;
Edge_iterator& operator--() {
CGAL_precondition(constraint_set != nullptr);
CGAL_precondition(constraint_it != constraint_set->begin() || vertex_it != constraint_it->begin());
if(constraint_it == constraint_set->end() || vertex_it == constraint_it->begin()) {
--constraint_it;
vertex_it = std::prev(constraint_it->end(), 2);
} else {
--vertex_it;
}
return *this;
}
}; // end class Edge_iterator

private:
// data for the 1d hierarchy
Compare comp;
Expand Down Expand Up @@ -302,6 +413,20 @@ class Polyline_constraint_hierarchy_2
return sc_to_c_map.end();
}

Edge_iterator edges_begin() const {
BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(Edge_iterator, std::bidirectional_iterator);
BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(Edge_iterator, std::bidirectional_iterator_tag,
std::bidirectional_iterator, Edge, Edge,
typename Edge_iterator::pointer, std::ptrdiff_t);
return Edge_iterator(Edge_iterator::Construction_access::begin_tag(), &constraint_set);
}

Edge_iterator edges_end() const {
return Edge_iterator(Edge_iterator::Construction_access::end_tag(), &constraint_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_end() const{ return sc_to_c_map.end(); }
C_iterator c_begin() const{ return constraint_set.begin(); }
Expand Down

0 comments on commit e0ba29f

Please sign in to comment.