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.
This commit is contained in:
Mael Rouxel-Labbé 2020-03-12 13:11:32 +01:00
parent 3a64414705
commit 1c622e0ba5
2 changed files with 46 additions and 26 deletions

View File

@ -54,10 +54,46 @@ struct Get_iterator_value_type<T,true>{
} } //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 Tr>
class Cdt_2_less_edge
: public CGAL::cpp98::binary_function<typename Tr::Edge, typename Tr::Edge, bool>
{
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 <class Gt,
class Tds_ = Default ,
@ -88,8 +124,9 @@ public:
typedef typename Ctr::List_faces List_faces;
typedef typename Ctr::List_vertices List_vertices;
typedef typename Ctr::List_constraints List_constraints;
typedef typename Ctr::Less_edge less_edge;
typedef typename Ctr::Edge_set Edge_set;
typedef internal::Cdt_2_less_edge<CDt> Less_edge;
typedef std::set<Edge, Less_edge> 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();

View File

@ -165,10 +165,6 @@ public:
// Tag to distinguish periodic triangulations from others
typedef Tag_false Periodic_tag;
class Less_edge;
typedef std::set<Edge,Less_edge> Edge_set;
Constrained_triangulation_2(const Gt& gt = Gt()) : Triangulation(gt) { }
Constrained_triangulation_2(std::list<Constraint>& lc, const Gt& gt=Gt())
@ -412,21 +408,6 @@ insert_constraint(Vertex_handle vaa, Vertex_handle vbb, OutputIterator out)
// OutputItEdges incident_constraints(Vertex_handle v,
// OutputItEdges out) const;
class Less_edge
: public CGAL::cpp98::binary_function<Edge, Edge, bool>
{
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;
protected: