mirror of https://github.com/CGAL/cgal
Merge pull request #6826 from MaelRL/T23-Operator=-GF
Improvements for Triangulation_23 comparison operators
This commit is contained in:
commit
e037898fc1
|
|
@ -895,49 +895,77 @@ is_valid(bool verbose, int level) const
|
||||||
if (dimension() <= 0 || (dimension()==1 && number_of_vertices() == 2 ) )
|
if (dimension() <= 0 || (dimension()==1 && number_of_vertices() == 2 ) )
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (dimension() == 1) {
|
if (dimension() == 1)
|
||||||
|
{
|
||||||
Finite_vertices_iterator it1 = finite_vertices_begin(),
|
Finite_vertices_iterator it1 = finite_vertices_begin(),
|
||||||
it2(it1), it3(it1);
|
it2(it1), it3(it1);
|
||||||
++it2;
|
++it2;
|
||||||
++it3; ++it3;
|
++it3; ++it3;
|
||||||
while( it3 != finite_vertices_end()) {
|
while( it3 != finite_vertices_end()) {
|
||||||
Orientation s = orientation(it1->point(),
|
Orientation s = orientation(point(it1), point(it2), point(it3));
|
||||||
it2->point(),
|
result = result && (s == COLLINEAR) ;
|
||||||
it3->point());
|
if(verbose && (s != COLLINEAR))
|
||||||
result = result && s == COLLINEAR ;
|
{
|
||||||
|
std::cerr << "Error: " << point(it1) << " "
|
||||||
|
<< point(it2) << " and "
|
||||||
|
<< point(it3) << " are not collinear" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
CGAL_triangulation_assertion(result);
|
CGAL_triangulation_assertion(result);
|
||||||
++it1 ; ++it2; ++it3;
|
++it1 ; ++it2; ++it3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { //dimension() == 2
|
else //dimension() == 2
|
||||||
for(Finite_faces_iterator it=finite_faces_begin();
|
{
|
||||||
it!=finite_faces_end(); it++) {
|
for(Finite_faces_iterator it=finite_faces_begin(); it!=finite_faces_end(); it++)
|
||||||
|
{
|
||||||
CGAL_triangulation_assertion( ! is_infinite(it));
|
CGAL_triangulation_assertion( ! is_infinite(it));
|
||||||
Orientation s = orientation(it->vertex(0)->point(),
|
Orientation s = orientation(point(it, 0), point(it, 1), point(it, 2));
|
||||||
it->vertex(1)->point(),
|
|
||||||
it->vertex(2)->point());
|
|
||||||
CGAL_triangulation_assertion( s == LEFT_TURN );
|
|
||||||
result = result && ( s == LEFT_TURN );
|
result = result && ( s == LEFT_TURN );
|
||||||
|
|
||||||
|
if(verbose && (s != LEFT_TURN))
|
||||||
|
{
|
||||||
|
std::cerr << "Error: " << point(it, 0) << " "
|
||||||
|
<< point(it, 1) << " and "
|
||||||
|
<< point(it, 2) << " form a badly oriented face" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGAL_triangulation_assertion(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vertex_circulator start = incident_vertices(infinite_vertex());
|
Vertex_circulator start = incident_vertices(infinite_vertex());
|
||||||
Vertex_circulator pc(start);
|
Vertex_circulator pc(start);
|
||||||
Vertex_circulator qc(start); ++qc;
|
Vertex_circulator qc(start); ++qc;
|
||||||
Vertex_circulator rc(start); ++rc; ++rc;
|
Vertex_circulator rc(start); ++rc; ++rc;
|
||||||
do {
|
do
|
||||||
Orientation s = orientation(pc->point(),
|
{
|
||||||
qc->point(),
|
Orientation s = orientation(point(pc), point(qc), point(rc));
|
||||||
rc->point());
|
|
||||||
CGAL_triangulation_assertion( s != LEFT_TURN );
|
CGAL_triangulation_assertion( s != LEFT_TURN );
|
||||||
result = result && ( s != LEFT_TURN );
|
result = result && ( s != LEFT_TURN );
|
||||||
|
|
||||||
|
if(verbose && (s == LEFT_TURN))
|
||||||
|
{
|
||||||
|
std::cerr << "Error: " << point(pc) << " "
|
||||||
|
<< point(qc) << " and "
|
||||||
|
<< point(rc) << " form a badly oriented infinite face" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
++pc ; ++qc ; ++rc;
|
++pc ; ++qc ; ++rc;
|
||||||
} while(pc != start);
|
} while(pc != start);
|
||||||
|
|
||||||
// check number of faces. This cannot be done by the Tds
|
// check number of faces. This cannot be done by the Tds
|
||||||
// which does not know the number of components nor the genus
|
// which does not know the number of components nor the genus
|
||||||
result = result && (number_of_faces() == 2*(number_of_vertices()+1)
|
const bool genus_check = number_of_faces() == 2*(number_of_vertices()+1) - 4 - degree(infinite_vertex());
|
||||||
- 4
|
result = result && genus_check;
|
||||||
- degree(infinite_vertex()));
|
if(verbose && !genus_check)
|
||||||
|
{
|
||||||
|
std::cerr << "Error: Genus check fail " << number_of_faces()
|
||||||
|
<< " vs " << 2*(number_of_vertices()+1) - 4 - degree(infinite_vertex())
|
||||||
|
<< " (nv = " << number_of_vertices()
|
||||||
|
<< " nf = " << number_of_faces()
|
||||||
|
<< " and degree(infinite_vertex()) = " << degree(infinite_vertex()) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
CGAL_triangulation_assertion( result);
|
CGAL_triangulation_assertion( result);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -3789,6 +3817,219 @@ operator>>(std::istream& is, Triangulation_2<Gt, Tds> &tr)
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Internal function used by operator==.
|
||||||
|
template < class GT, class TDS1, class TDS2, typename FMAP, typename VMAP >
|
||||||
|
bool
|
||||||
|
test_next(const Triangulation_2<GT, TDS1>& t1,
|
||||||
|
const Triangulation_2<GT, TDS2>& t2,
|
||||||
|
typename Triangulation_2<GT, TDS1>::Face_handle f1,
|
||||||
|
typename Triangulation_2<GT, TDS2>::Face_handle f2,
|
||||||
|
FMAP& Fmap,
|
||||||
|
VMAP& Vmap)
|
||||||
|
{
|
||||||
|
// This function tests and registers the 3 neighbors of f1/f2,
|
||||||
|
// and recursively calls itself over them.
|
||||||
|
// We don't use the call stack as it may overflow
|
||||||
|
// Returns false if an inequality has been found.
|
||||||
|
|
||||||
|
// Precondition: f1, f2 have been registered as well as their 3 vertices.
|
||||||
|
CGAL_triangulation_precondition(t1.dimension() >= 2);
|
||||||
|
CGAL_triangulation_precondition(Fmap[f1] == f2);
|
||||||
|
CGAL_triangulation_precondition(Vmap.find(f1->vertex(0)) != Vmap.end());
|
||||||
|
CGAL_triangulation_precondition(Vmap.find(f1->vertex(1)) != Vmap.end());
|
||||||
|
CGAL_triangulation_precondition(t1.dimension() == 1 || Vmap.find(f1->vertex(2)) != Vmap.end());
|
||||||
|
|
||||||
|
typedef Triangulation_2<GT, TDS1> Tr1;
|
||||||
|
typedef Triangulation_2<GT, TDS2> Tr2;
|
||||||
|
typedef typename Tr1::Vertex_handle Vertex_handle1;
|
||||||
|
typedef typename Tr1::Face_handle Face_handle1;
|
||||||
|
typedef typename Tr2::Vertex_handle Vertex_handle2;
|
||||||
|
typedef typename Tr2::Face_handle Face_handle2;
|
||||||
|
|
||||||
|
typedef typename VMAP::const_iterator Vit;
|
||||||
|
typedef typename FMAP::const_iterator Fit;
|
||||||
|
|
||||||
|
typedef typename Tr1::Geom_traits::Construct_point_2 Construct_point_2;
|
||||||
|
typedef typename Tr1::Geom_traits::Compare_xy_2 Compare_xy_2;
|
||||||
|
|
||||||
|
Compare_xy_2 cmp1 = t1.geom_traits().compare_xy_2_object();
|
||||||
|
Construct_point_2 cp = t1.geom_traits().construct_point_2_object();
|
||||||
|
|
||||||
|
std::vector<std::pair<Face_handle1, Face_handle2> > face_stack;
|
||||||
|
face_stack.emplace_back(f1, f2);
|
||||||
|
|
||||||
|
while(! face_stack.empty())
|
||||||
|
{
|
||||||
|
Face_handle1 f1 = face_stack.back().first;
|
||||||
|
Face_handle2 f2 = face_stack.back().second;
|
||||||
|
face_stack.pop_back();
|
||||||
|
|
||||||
|
for(int i=0; i <= t1.dimension(); ++i)
|
||||||
|
{
|
||||||
|
Face_handle1 n1 = f1->neighbor(i);
|
||||||
|
Fit fit = Fmap.find(n1);
|
||||||
|
Vertex_handle1 v1 = f1->vertex(i);
|
||||||
|
Vertex_handle2 v2 = Vmap[v1];
|
||||||
|
Face_handle2 n2 = f2->neighbor(f2->index(v2));
|
||||||
|
if(fit != Fmap.end())
|
||||||
|
{
|
||||||
|
// n1 was already registered.
|
||||||
|
if(fit->second != n2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// n1 has not yet been registered.
|
||||||
|
// We check that the new vertices match geometrically.
|
||||||
|
// And we register them.
|
||||||
|
Vertex_handle1 vn1 = n1->vertex(n1->index(f1));
|
||||||
|
Vertex_handle2 vn2 = n2->vertex(n2->index(f2));
|
||||||
|
Vit vit = Vmap.find(vn1);
|
||||||
|
if(vit != Vmap.end())
|
||||||
|
{
|
||||||
|
// vn1 already registered
|
||||||
|
if(vit->second != vn2)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(t2.is_infinite(vn2))
|
||||||
|
return false; // vn1 can't be infinite,
|
||||||
|
|
||||||
|
// since it would have been registered.
|
||||||
|
if(cmp1(cp(vn1->point()), cp(vn2->point())) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// We register vn1/vn2.
|
||||||
|
Vmap.emplace(vn1, vn2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We register n1/n2.
|
||||||
|
Fmap.emplace(n1, n2);
|
||||||
|
face_stack.emplace_back(n1, n2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template < class GT, class TDS1, class TDS2 >
|
||||||
|
bool
|
||||||
|
operator==(const Triangulation_2<GT, TDS1>& t1,
|
||||||
|
const Triangulation_2<GT, TDS2>& t2)
|
||||||
|
{
|
||||||
|
typedef typename Triangulation_2<GT, TDS1>::Vertex_handle Vertex_handle1;
|
||||||
|
typedef typename Triangulation_2<GT, TDS1>::Face_handle Face_handle1;
|
||||||
|
typedef typename Triangulation_2<GT, TDS2>::Vertex_handle Vertex_handle2;
|
||||||
|
typedef typename Triangulation_2<GT, TDS2>::Face_handle Face_handle2;
|
||||||
|
|
||||||
|
typedef typename Triangulation_2<GT, TDS1>::Point Point;
|
||||||
|
|
||||||
|
typedef typename Triangulation_2<GT, TDS1>::Geom_traits::Equal_2 Equal_2;
|
||||||
|
typedef typename Triangulation_2<GT, TDS1>::Geom_traits::Compare_xy_2 Compare_xy_2;
|
||||||
|
typedef typename Triangulation_2<GT, TDS1>::Geom_traits::Construct_point_2 Construct_point_2;
|
||||||
|
|
||||||
|
Equal_2 equal = t1.geom_traits().equal_2_object();
|
||||||
|
Compare_xy_2 cmp1 = t1.geom_traits().compare_xy_2_object();
|
||||||
|
Compare_xy_2 cmp2 = t2.geom_traits().compare_xy_2_object();
|
||||||
|
Construct_point_2 cp = t1.geom_traits().construct_point_2_object();
|
||||||
|
|
||||||
|
// Some quick checks.
|
||||||
|
if(t1.dimension() != t2.dimension() ||
|
||||||
|
t1.number_of_vertices() != t2.number_of_vertices() ||
|
||||||
|
t1.number_of_faces() != t2.number_of_faces())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int dim = t1.dimension();
|
||||||
|
// Special case for dimension < 1.
|
||||||
|
// The triangulation is uniquely defined in these cases.
|
||||||
|
if(dim == -1)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Special case for dimensions 0 and 1.
|
||||||
|
if(dim < 2)
|
||||||
|
{
|
||||||
|
// It's enough to test that the points are the same,
|
||||||
|
// since the triangulation is uniquely defined in this case.
|
||||||
|
std::vector<Point> V1 (t1.points_begin(), t1.points_end());
|
||||||
|
std::vector<Point> V2 (t2.points_begin(), t2.points_end());
|
||||||
|
|
||||||
|
std::sort(V1.begin(), V1.end(),
|
||||||
|
[&cmp1, &cp](const Point& p1, const Point& p2){ return cmp1(cp(p1), cp(p2))==SMALLER; });
|
||||||
|
|
||||||
|
std::sort(V2.begin(), V2.end(),
|
||||||
|
[&cmp2, &cp](const Point& p1, const Point& p2){ return cmp2(cp(p1), cp(p2))==SMALLER; });
|
||||||
|
|
||||||
|
return V1 == V2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We will store the mapping between the 2 triangulations vertices and faces in 2 maps.
|
||||||
|
std::unordered_map<Vertex_handle1, Vertex_handle2> Vmap;
|
||||||
|
std::unordered_map<Face_handle1, Face_handle2> Fmap;
|
||||||
|
|
||||||
|
// Handle the infinite vertex.
|
||||||
|
Vertex_handle1 v1 = t1.infinite_vertex();
|
||||||
|
Vertex_handle2 iv2 = t2.infinite_vertex();
|
||||||
|
Vmap.emplace(v1, iv2);
|
||||||
|
|
||||||
|
// We pick one infinite face of t1, and try to match it against the infinite faces of t2.
|
||||||
|
Face_handle1 f = v1->face();
|
||||||
|
Vertex_handle1 v2 = f->vertex((f->index(v1)+1)%(dim+1));
|
||||||
|
Vertex_handle1 v3 = f->vertex((f->index(v1)+2)%(dim+1));
|
||||||
|
const Point& p2 = v2->point();
|
||||||
|
const Point& p3 = v3->point();
|
||||||
|
|
||||||
|
std::vector<Face_handle2> ifs;
|
||||||
|
auto fc = t2.incident_faces(iv2), done(fc);
|
||||||
|
do {
|
||||||
|
ifs.push_back(fc);
|
||||||
|
} while(++fc != done);
|
||||||
|
|
||||||
|
for(typename std::vector<Face_handle2>::const_iterator fit = ifs.begin();
|
||||||
|
fit != ifs.end(); ++fit)
|
||||||
|
{
|
||||||
|
int inf = (*fit)->index(iv2);
|
||||||
|
|
||||||
|
if(equal(cp(p2), cp((*fit)->vertex((inf+1)%(dim+1))->point())))
|
||||||
|
Vmap.emplace(v2, (*fit)->vertex((inf+1)%(dim+1)));
|
||||||
|
else if(dim == 2 && equal(cp(p2), cp((*fit)->vertex((inf+2)%(dim+1))->point())))
|
||||||
|
Vmap.emplace(v2, (*fit)->vertex((inf+2)%(dim+1)));
|
||||||
|
else
|
||||||
|
continue; // None matched v2.
|
||||||
|
|
||||||
|
if(equal(cp(p3), cp((*fit)->vertex((inf+1)%(dim+1))->point())))
|
||||||
|
Vmap.emplace(v3, (*fit)->vertex((inf+1)%(dim+1)));
|
||||||
|
else if(dim == 2 && equal(cp(p3), cp((*fit)->vertex((inf+2)%(dim+1))->point())))
|
||||||
|
Vmap.emplace(v3, (*fit)->vertex((inf+2)%(dim+1)));
|
||||||
|
else
|
||||||
|
continue; // None matched v3.
|
||||||
|
|
||||||
|
// Found it !
|
||||||
|
Fmap.emplace(f, *fit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Fmap.size() == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// We now have one face, we need to propagate recursively.
|
||||||
|
return internal::test_next(t1, t2, Fmap.begin()->first, Fmap.begin()->second, Fmap, Vmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < class GT, class Tds1, class Tds2 >
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
operator!=(const Triangulation_2<GT, Tds1>& t1,
|
||||||
|
const Triangulation_2<GT, Tds2>& t2)
|
||||||
|
{
|
||||||
|
return ! (t1 == t2);
|
||||||
|
}
|
||||||
|
|
||||||
} //namespace CGAL
|
} //namespace CGAL
|
||||||
|
|
||||||
#include <CGAL/enable_warnings.h>
|
#include <CGAL/enable_warnings.h>
|
||||||
|
|
|
||||||
|
|
@ -132,12 +132,10 @@ _test_cls_triangulation_2( const Triangul & )
|
||||||
assert( T1.number_of_vertices() == 0 );
|
assert( T1.number_of_vertices() == 0 );
|
||||||
|
|
||||||
Triangul T3(T1);
|
Triangul T3(T1);
|
||||||
assert(T3.tds().vertices().size() == T1.tds().vertices().size());
|
assert(T3 == T1);
|
||||||
assert(T3.tds().faces().size() == T1.tds().faces().size());
|
|
||||||
|
|
||||||
Triangul T4 = T1;
|
Triangul T4 = T1;
|
||||||
assert(T4.tds().vertices().size() == T1.tds().vertices().size());
|
assert(T4 == T1);
|
||||||
assert(T4.tds().faces().size() == T1.tds().faces().size());
|
|
||||||
|
|
||||||
T3.swap(T1);
|
T3.swap(T1);
|
||||||
|
|
||||||
|
|
@ -159,6 +157,7 @@ _test_cls_triangulation_2( const Triangul & )
|
||||||
assert( T0_0.number_of_vertices() == 0 );
|
assert( T0_0.number_of_vertices() == 0 );
|
||||||
assert( T0_0.number_of_faces() == 0);
|
assert( T0_0.number_of_faces() == 0);
|
||||||
assert( T0_0.is_valid() );
|
assert( T0_0.is_valid() );
|
||||||
|
assert( T0_0 == T0_0 );
|
||||||
|
|
||||||
Triangul T0_1;
|
Triangul T0_1;
|
||||||
Vertex_handle v0_1_0 = T0_1.insert(p0); assert( v0_1_0 != nullptr );
|
Vertex_handle v0_1_0 = T0_1.insert(p0); assert( v0_1_0 != nullptr );
|
||||||
|
|
@ -166,10 +165,18 @@ _test_cls_triangulation_2( const Triangul & )
|
||||||
assert( T0_1.number_of_vertices() == 1 );
|
assert( T0_1.number_of_vertices() == 1 );
|
||||||
assert( T0_1.number_of_faces() == 0);
|
assert( T0_1.number_of_faces() == 0);
|
||||||
assert( T0_1.is_valid() );
|
assert( T0_1.is_valid() );
|
||||||
|
assert( T0_0 != T0_1 );
|
||||||
|
|
||||||
Triangul T0_1b(T0_1);
|
Triangul T0_1b(T0_1);
|
||||||
assert(T0_1b.tds().vertices().size() == T0_1.tds().vertices().size());
|
assert(T0_1b == T0_1);
|
||||||
assert(T0_1b.tds().faces().size() == T0_1.tds().faces().size());
|
|
||||||
|
Triangul T0_1c;
|
||||||
|
v0_1_0 = T0_1c.insert(p1); assert( v0_1_0 != nullptr );
|
||||||
|
assert( T0_1c.dimension() == 0 );
|
||||||
|
assert( T0_1c.number_of_vertices() == 1 );
|
||||||
|
assert( T0_1c.number_of_faces() == 0);
|
||||||
|
assert( T0_1c.is_valid() );
|
||||||
|
assert( T0_1 != T0_1c );
|
||||||
|
|
||||||
// test insert_first()
|
// test insert_first()
|
||||||
Triangul T0_2;
|
Triangul T0_2;
|
||||||
|
|
@ -192,10 +199,10 @@ _test_cls_triangulation_2( const Triangul & )
|
||||||
assert( T1_2.number_of_vertices() == 2 );
|
assert( T1_2.number_of_vertices() == 2 );
|
||||||
assert( T1_2.number_of_faces() == 0 );
|
assert( T1_2.number_of_faces() == 0 );
|
||||||
assert( T1_2.is_valid() );
|
assert( T1_2.is_valid() );
|
||||||
|
assert( T1_2 != T0_1 );
|
||||||
|
|
||||||
Triangul T1_2b(T1_2);
|
Triangul T1_2b(T1_2);
|
||||||
assert(T1_2b.tds().vertices().size() == T1_2.tds().vertices().size());
|
assert(T1_2b == T1_2);
|
||||||
assert(T1_2b.tds().faces().size() == T1_2.tds().faces().size());
|
|
||||||
|
|
||||||
// p1,p3,p2 [endpoints first]
|
// p1,p3,p2 [endpoints first]
|
||||||
Triangul T1_3_0;
|
Triangul T1_3_0;
|
||||||
|
|
@ -206,6 +213,7 @@ _test_cls_triangulation_2( const Triangul & )
|
||||||
assert( T1_3_0.number_of_vertices() == 3 );
|
assert( T1_3_0.number_of_vertices() == 3 );
|
||||||
assert( T1_3_0.number_of_faces() == 0 );
|
assert( T1_3_0.number_of_faces() == 0 );
|
||||||
assert( T1_3_0.is_valid() );
|
assert( T1_3_0.is_valid() );
|
||||||
|
assert( T1_3_0 != T1_2 );
|
||||||
|
|
||||||
// p1,p2,p3 [middle point first]
|
// p1,p2,p3 [middle point first]
|
||||||
Triangul T1_3_1;
|
Triangul T1_3_1;
|
||||||
|
|
@ -216,6 +224,7 @@ _test_cls_triangulation_2( const Triangul & )
|
||||||
assert( T1_3_1.number_of_vertices() == 3 );
|
assert( T1_3_1.number_of_vertices() == 3 );
|
||||||
assert( T1_3_1.number_of_faces() == 0 );
|
assert( T1_3_1.number_of_faces() == 0 );
|
||||||
assert( T1_3_1.is_valid() );
|
assert( T1_3_1.is_valid() );
|
||||||
|
assert( T1_3_1 == T1_3_0 );
|
||||||
|
|
||||||
Triangul T1_5;
|
Triangul T1_5;
|
||||||
Vertex_handle v1_5_1 = T1_5.insert(p1);
|
Vertex_handle v1_5_1 = T1_5.insert(p1);
|
||||||
|
|
@ -227,6 +236,7 @@ _test_cls_triangulation_2( const Triangul & )
|
||||||
assert( T1_5.number_of_vertices() == 5 );
|
assert( T1_5.number_of_vertices() == 5 );
|
||||||
assert( T1_5.number_of_faces() == 0 );
|
assert( T1_5.number_of_faces() == 0 );
|
||||||
assert( T1_5.is_valid() );
|
assert( T1_5.is_valid() );
|
||||||
|
assert( T1_5 != T1_3_1 );
|
||||||
|
|
||||||
// test insert_second()
|
// test insert_second()
|
||||||
Triangul T1_6 = T0_2;
|
Triangul T1_6 = T0_2;
|
||||||
|
|
@ -298,11 +308,13 @@ _test_cls_triangulation_2( const Triangul & )
|
||||||
|
|
||||||
// test generic iterator insert
|
// test generic iterator insert
|
||||||
#ifndef CGAL_CFG_NO_MEMBER_TEMPLATES
|
#ifndef CGAL_CFG_NO_MEMBER_TEMPLATES
|
||||||
Triangul T2_4; T2_4.insert( Point_iterator(T2_1.finite_vertices_begin()),
|
Triangul T2_4;
|
||||||
Point_iterator(T2_1.finite_vertices_end()) );
|
T2_4.insert( Point_iterator(T2_1.finite_vertices_begin()),
|
||||||
|
Point_iterator(T2_1.finite_vertices_end()) );
|
||||||
assert( T2_4.dimension() == 2 );
|
assert( T2_4.dimension() == 2 );
|
||||||
assert( T2_4.number_of_vertices() == 11 );
|
assert( T2_4.number_of_vertices() == 11 );
|
||||||
assert( T2_4.is_valid() );
|
assert( T2_4.is_valid() );
|
||||||
|
assert( T2_4 == T2_1 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// test list iterator insert
|
// test list iterator insert
|
||||||
|
|
@ -320,6 +332,7 @@ _test_cls_triangulation_2( const Triangul & )
|
||||||
assert( T2_6.dimension() == 2 );
|
assert( T2_6.dimension() == 2 );
|
||||||
assert( T2_6.number_of_vertices() == 10 );
|
assert( T2_6.number_of_vertices() == 10 );
|
||||||
assert( T2_6.is_valid() );
|
assert( T2_6.is_valid() );
|
||||||
|
assert( T2_5 == T2_6 );
|
||||||
|
|
||||||
// test grid insert
|
// test grid insert
|
||||||
Triangul T2_7;
|
Triangul T2_7;
|
||||||
|
|
@ -496,21 +509,25 @@ _test_cls_triangulation_2( const Triangul & )
|
||||||
assert( T1_5_2.dimension() == 1 );
|
assert( T1_5_2.dimension() == 1 );
|
||||||
assert( T1_5_2.number_of_vertices() == 5 );
|
assert( T1_5_2.number_of_vertices() == 5 );
|
||||||
assert( T1_5_2.is_valid() );
|
assert( T1_5_2.is_valid() );
|
||||||
|
assert( T1_5_2 == T1_5 );
|
||||||
|
|
||||||
// test copy_constructor with non-empty 2-triangulation
|
// test copy_constructor with non-empty 2-triangulation
|
||||||
Triangul T2_8_1(T2_8);
|
Triangul T2_8_1(T2_8);
|
||||||
assert( T2_8_1.is_valid());
|
assert( T2_8_1.is_valid());
|
||||||
|
assert( T2_8 == T2_8);
|
||||||
|
|
||||||
Triangul T2_1_1( T2_1 );
|
Triangul T2_1_1( T2_1 );
|
||||||
assert( T2_1_1.dimension() == 2 );
|
assert( T2_1_1.dimension() == 2 );
|
||||||
assert( T2_1_1.number_of_vertices() == 11 );
|
assert( T2_1_1.number_of_vertices() == 11 );
|
||||||
assert( T2_1_1.is_valid() );
|
assert( T2_1_1.is_valid() );
|
||||||
|
assert( T2_1_1 == T2_1 );
|
||||||
|
|
||||||
// test assignment operator
|
// test assignment operator
|
||||||
Triangul T2_1_4 = T2_1;
|
Triangul T2_1_4 = T2_1;
|
||||||
assert( T2_1_4.dimension() == 2 );
|
assert( T2_1_4.dimension() == 2 );
|
||||||
assert( T2_1_4.number_of_vertices() == 11 );
|
assert( T2_1_4.number_of_vertices() == 11 );
|
||||||
assert( T2_1_4.is_valid() );
|
assert( T2_1_4.is_valid() );
|
||||||
|
assert( T2_1_4 == T2_1 );
|
||||||
|
|
||||||
/*********************************************/
|
/*********************************************/
|
||||||
/****** FINITE/INFINITE VERTICES/FACES *******/
|
/****** FINITE/INFINITE VERTICES/FACES *******/
|
||||||
|
|
|
||||||
|
|
@ -24,14 +24,6 @@
|
||||||
# include <CGAL/Profile_counter.h>
|
# include <CGAL/Profile_counter.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <list>
|
|
||||||
#include <set>
|
|
||||||
#include <map>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <utility>
|
|
||||||
#include <stack>
|
|
||||||
|
|
||||||
#include <CGAL/Unique_hash_map.h>
|
#include <CGAL/Unique_hash_map.h>
|
||||||
#include <CGAL/triangulation_assertions.h>
|
#include <CGAL/triangulation_assertions.h>
|
||||||
#include <CGAL/Triangulation_utils_3.h>
|
#include <CGAL/Triangulation_utils_3.h>
|
||||||
|
|
@ -77,6 +69,14 @@
|
||||||
# include <tbb/scalable_allocator.h>
|
# include <tbb/scalable_allocator.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <list>
|
||||||
|
#include <set>
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
#define CGAL_TRIANGULATION_3_USE_THE_4_POINTS_CONSTRUCTOR
|
#define CGAL_TRIANGULATION_3_USE_THE_4_POINTS_CONSTRUCTOR
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
@ -7154,16 +7154,14 @@ is_valid_finite(Cell_handle c, bool verbose, int) const
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// Internal function used by operator==.
|
// Internal function used by operator==.
|
||||||
template < class GT, class Tds1, class Tds2, class Lds >
|
template < class GT, class Tds1, class Tds2, class Lds, typename CMAP, typename VMAP >
|
||||||
bool
|
bool
|
||||||
test_next(const Triangulation_3<GT, Tds1, Lds>& t1,
|
test_next(const Triangulation_3<GT, Tds1, Lds>& t1,
|
||||||
const Triangulation_3<GT, Tds2, Lds>& t2,
|
const Triangulation_3<GT, Tds2, Lds>& t2,
|
||||||
typename Triangulation_3<GT, Tds1, Lds>::Cell_handle c1,
|
typename Triangulation_3<GT, Tds1, Lds>::Cell_handle c1,
|
||||||
typename Triangulation_3<GT, Tds2, Lds>::Cell_handle c2,
|
typename Triangulation_3<GT, Tds2, Lds>::Cell_handle c2,
|
||||||
std::map<typename Triangulation_3<GT, Tds1, Lds>::Cell_handle,
|
CMAP& Cmap,
|
||||||
typename Triangulation_3<GT, Tds2, Lds>::Cell_handle>& Cmap,
|
VMAP& Vmap)
|
||||||
std::map<typename Triangulation_3<GT, Tds1, Lds>::Vertex_handle,
|
|
||||||
typename Triangulation_3<GT, Tds2, Lds>::Vertex_handle>& Vmap)
|
|
||||||
{
|
{
|
||||||
// This function tests and registers the 4 neighbors of c1/c2,
|
// This function tests and registers the 4 neighbors of c1/c2,
|
||||||
// and recursively calls itself over them.
|
// and recursively calls itself over them.
|
||||||
|
|
@ -7186,8 +7184,8 @@ test_next(const Triangulation_3<GT, Tds1, Lds>& t1,
|
||||||
typedef typename Tr2::Vertex_handle Vertex_handle2;
|
typedef typename Tr2::Vertex_handle Vertex_handle2;
|
||||||
typedef typename Tr2::Cell_handle Cell_handle2;
|
typedef typename Tr2::Cell_handle Cell_handle2;
|
||||||
|
|
||||||
typedef typename std::map<Vertex_handle1, Vertex_handle2>::const_iterator Vit;
|
typedef typename std::unordered_map<Vertex_handle1, Vertex_handle2>::const_iterator Vit;
|
||||||
typedef typename std::map<Cell_handle1, Cell_handle2>::const_iterator Cit;
|
typedef typename std::unordered_map<Cell_handle1, Cell_handle2>::const_iterator Cit;
|
||||||
|
|
||||||
typedef typename Tr1::Geom_traits::Construct_point_3 Construct_point_3;
|
typedef typename Tr1::Geom_traits::Construct_point_3 Construct_point_3;
|
||||||
typedef typename Tr1::Geom_traits::Compare_xyz_3 Compare_xyz_3;
|
typedef typename Tr1::Geom_traits::Compare_xyz_3 Compare_xyz_3;
|
||||||
|
|
@ -7196,7 +7194,7 @@ test_next(const Triangulation_3<GT, Tds1, Lds>& t1,
|
||||||
Construct_point_3 cp = t1.geom_traits().construct_point_3_object();
|
Construct_point_3 cp = t1.geom_traits().construct_point_3_object();
|
||||||
|
|
||||||
std::vector<std::pair<Cell_handle1, Cell_handle2> > cell_stack;
|
std::vector<std::pair<Cell_handle1, Cell_handle2> > cell_stack;
|
||||||
cell_stack.push_back(std::make_pair(c1, c2));
|
cell_stack.emplace_back(c1, c2);
|
||||||
|
|
||||||
while(! cell_stack.empty())
|
while(! cell_stack.empty())
|
||||||
{
|
{
|
||||||
|
|
@ -7242,12 +7240,12 @@ test_next(const Triangulation_3<GT, Tds1, Lds>& t1,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// We register vn1/vn2.
|
// We register vn1/vn2.
|
||||||
Vmap.insert(std::make_pair(vn1, vn2));
|
Vmap.emplace(vn1, vn2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We register n1/n2.
|
// We register n1/n2.
|
||||||
Cmap.insert(std::make_pair(n1, n2));
|
Cmap.emplace(n1, n2);
|
||||||
cell_stack.push_back(std::make_pair(n1, n2));
|
cell_stack.emplace_back(n1, n2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7286,11 +7284,11 @@ operator==(const Triangulation_3<GT, Tds1, Lds>& t1,
|
||||||
int dim = t1.dimension();
|
int dim = t1.dimension();
|
||||||
// Special case for dimension < 1.
|
// Special case for dimension < 1.
|
||||||
// The triangulation is uniquely defined in these cases.
|
// The triangulation is uniquely defined in these cases.
|
||||||
if(dim < 1)
|
if(dim == - 1)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Special case for dimension == 1.
|
// Special case for dimensions 0 and 1.
|
||||||
if(dim == 1)
|
if(dim < 2)
|
||||||
{
|
{
|
||||||
// It's enough to test that the points are the same,
|
// It's enough to test that the points are the same,
|
||||||
// since the triangulation is uniquely defined in this case.
|
// since the triangulation is uniquely defined in this case.
|
||||||
|
|
@ -7308,13 +7306,13 @@ operator==(const Triangulation_3<GT, Tds1, Lds>& t1,
|
||||||
|
|
||||||
// We will store the mapping between the 2 triangulations vertices and
|
// We will store the mapping between the 2 triangulations vertices and
|
||||||
// cells in 2 maps.
|
// cells in 2 maps.
|
||||||
std::map<Vertex_handle1, Vertex_handle2> Vmap;
|
std::unordered_map<Vertex_handle1, Vertex_handle2> Vmap;
|
||||||
std::map<Cell_handle1, Cell_handle2> Cmap;
|
std::unordered_map<Cell_handle1, Cell_handle2> Cmap;
|
||||||
|
|
||||||
// Handle the infinite vertex.
|
// Handle the infinite vertex.
|
||||||
Vertex_handle1 v1 = t1.infinite_vertex();
|
Vertex_handle1 v1 = t1.infinite_vertex();
|
||||||
Vertex_handle2 iv2 = t2.infinite_vertex();
|
Vertex_handle2 iv2 = t2.infinite_vertex();
|
||||||
Vmap.insert(std::make_pair(v1, iv2));
|
Vmap.emplace(v1, iv2);
|
||||||
|
|
||||||
// We pick one infinite cell of t1, and try to match it against the
|
// We pick one infinite cell of t1, and try to match it against the
|
||||||
// infinite cells of t2.
|
// infinite cells of t2.
|
||||||
|
|
@ -7364,7 +7362,7 @@ operator==(const Triangulation_3<GT, Tds1, Lds>& t1,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Found it !
|
// Found it !
|
||||||
Cmap.insert(std::make_pair(c, *cit));
|
Cmap.emplace(c, *cit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -222,15 +222,23 @@ _test_cls_triangulation_3(const Triangulation &)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << " Constructor1 " << std::endl;
|
std::cout << " Constructor1 " << std::endl;
|
||||||
Point p10(0,0,0);
|
Vertex_handle v0=T0.insert(p[0]);
|
||||||
Vertex_handle v0=T0.insert(p10);
|
|
||||||
assert(T0.dimension() == 0);
|
assert(T0.dimension() == 0);
|
||||||
assert(T0.number_of_vertices() == 1);
|
assert(T0.number_of_vertices() == 1);
|
||||||
assert(T0.is_valid());
|
assert(T0.is_valid());
|
||||||
|
assert(T0 != Tm1);
|
||||||
|
|
||||||
Cls T0d0(T0);
|
Cls T0d0(T0);
|
||||||
assert(T0 == T0d0);
|
assert(T0 == T0d0);
|
||||||
|
|
||||||
|
Cls T0d0b;
|
||||||
|
v0=T0d0b.insert(p[1]);
|
||||||
|
assert(T0d0b.dimension() == 0);
|
||||||
|
assert(T0d0b.number_of_vertices() == 1);
|
||||||
|
assert(T0d0b.is_valid());
|
||||||
|
assert(T0d0b != T0d0);
|
||||||
|
assert(T0d0b != Tm1);
|
||||||
|
|
||||||
if (! del) // to avoid doing the following tests for both Delaunay
|
if (! del) // to avoid doing the following tests for both Delaunay
|
||||||
// and non Delaunay triangulations
|
// and non Delaunay triangulations
|
||||||
{
|
{
|
||||||
|
|
@ -244,6 +252,7 @@ _test_cls_triangulation_3(const Triangulation &)
|
||||||
assert(T0.dimension() == 1);
|
assert(T0.dimension() == 1);
|
||||||
assert(T0.number_of_vertices() == 2);
|
assert(T0.number_of_vertices() == 2);
|
||||||
assert(T0.is_valid());
|
assert(T0.is_valid());
|
||||||
|
assert(T0 != T0d0);
|
||||||
|
|
||||||
Cls T0d1(T0);
|
Cls T0d1(T0);
|
||||||
assert(T0 == T0d1);
|
assert(T0 == T0d1);
|
||||||
|
|
@ -261,6 +270,7 @@ _test_cls_triangulation_3(const Triangulation &)
|
||||||
assert(T0.dimension() == 2);
|
assert(T0.dimension() == 2);
|
||||||
assert(T0.number_of_vertices() == 3);
|
assert(T0.number_of_vertices() == 3);
|
||||||
assert(T0.is_valid());
|
assert(T0.is_valid());
|
||||||
|
assert(T0 != T0d1);
|
||||||
|
|
||||||
Cls T0d2(T0);
|
Cls T0d2(T0);
|
||||||
assert(T0 == T0d2);
|
assert(T0 == T0d2);
|
||||||
|
|
@ -278,6 +288,7 @@ _test_cls_triangulation_3(const Triangulation &)
|
||||||
assert(T0.dimension() == 3);
|
assert(T0.dimension() == 3);
|
||||||
assert(T0.number_of_vertices() == 4);
|
assert(T0.number_of_vertices() == 4);
|
||||||
assert(T0.is_valid());
|
assert(T0.is_valid());
|
||||||
|
assert(T0 != T0d2);
|
||||||
|
|
||||||
Cls T0d3(T0);
|
Cls T0d3(T0);
|
||||||
assert(T0 == T0d3);
|
assert(T0 == T0d3);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue