From 1c622e0ba50c5903f053609670be5dc8bcd9d6ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 12 Mar 2020 13:11:32 +0100 Subject: [PATCH] Base CDT2's edge sets on geometry to ensure determinism When using face addresses, we do get the same combinatorics and geometry in the result, but it is possible to create different TDS' from one run to another, with a given face not having the same order of points in memory. --- .../Constrained_Delaunay_triangulation_2.h | 53 ++++++++++++++++--- .../CGAL/Constrained_triangulation_2.h | 19 ------- 2 files changed, 46 insertions(+), 26 deletions(-) diff --git a/Triangulation_2/include/CGAL/Constrained_Delaunay_triangulation_2.h b/Triangulation_2/include/CGAL/Constrained_Delaunay_triangulation_2.h index dd6f110c879..4847cc9fb78 100644 --- a/Triangulation_2/include/CGAL/Constrained_Delaunay_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Constrained_Delaunay_triangulation_2.h @@ -54,10 +54,46 @@ struct Get_iterator_value_type{ } } //namespace CGAL::internal #endif //CGAL_TRIANGULATION_2_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO - - namespace CGAL { +namespace internal { +// Compare geometry to ensure deterministic flips +template +class Cdt_2_less_edge + : public CGAL::cpp98::binary_function +{ + const Tr* tr_ptr; + + typedef typename Tr::Point Point; + typedef typename Tr::Edge Edge; + +public: + Cdt_2_less_edge(const Tr* tr_ptr) : tr_ptr(tr_ptr) { } + + // just a manual lexicographical_compare + bool operator() (const Edge& e1, const Edge& e2) const + { + const Point& e1p1 = tr_ptr->point(e1.first, Tr::ccw(e1.second)); + const Point& e2p1 = tr_ptr->point(e2.first, Tr::ccw(e2.second)); + + CGAL::Comparison_result res1 = tr_ptr->compare_xy(e1p1, e2p1); + if(res1 == CGAL::SMALLER) + return true; + if(res1 == CGAL::LARGER) + return false; + + const Point& e1p2 = tr_ptr->point(e1.first, Tr::cw(e1.second)); + const Point& e2p2 = tr_ptr->point(e2.first, Tr::cw(e2.second)); + + CGAL::Comparison_result res2 = tr_ptr->compare_xy(e1p2, e2p2); + if(res2 == CGAL::SMALLER) + return true; + + return false; + } +}; + +} // namespace internal template Less_edge; + typedef std::set Edge_set; //Tag to distinguish Delaunay from regular triangulations typedef Tag_false Weighted_tag; @@ -538,8 +575,10 @@ public: int i, ii, indf, indn; Face_handle ni, f,ff; Edge ei,eni; - typename Ctr::Edge_set edge_set; - typename Ctr::Less_edge less_edge; + + Less_edge less_edge(this); + Edge_set edge_set(less_edge); + Edge e[4]; typename List_edges::iterator itedge=edges.begin(); diff --git a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h index a453d120cd1..d8a7d762f9b 100644 --- a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h @@ -165,10 +165,6 @@ public: // Tag to distinguish periodic triangulations from others typedef Tag_false Periodic_tag; - class Less_edge; - typedef std::set Edge_set; - - Constrained_triangulation_2(const Gt& gt = Gt()) : Triangulation(gt) { } Constrained_triangulation_2(std::list& lc, const Gt& gt=Gt()) @@ -411,21 +407,6 @@ insert_constraint(Vertex_handle vaa, Vertex_handle vbb, OutputIterator out) // template // OutputItEdges incident_constraints(Vertex_handle v, // OutputItEdges out) const; - - - class Less_edge - : public CGAL::cpp98::binary_function - { - public: - Less_edge() {} - bool operator() (const Edge& e1, const Edge& e2) const - { - int ind1=e1.second, ind2=e2.second; - return( (&(*e1.first) < &(*e2.first)) - || ( (&(*e1.first) == &(*e2.first)) && (ind1 < ind2))); - } - }; - void file_output(std::ostream& os) const;