mirror of https://github.com/CGAL/cgal
Add unique simplex iterators
This commit is contained in:
parent
f7a78677fc
commit
5759ce49ae
|
|
@ -119,6 +119,14 @@ public:
|
|||
/// Unique_vertex_iterator iterates over exactly one representative.
|
||||
typedef Periodic_2_triangulation_unique_vertex_iterator_2<Self>
|
||||
Unique_vertex_iterator;
|
||||
/// Iterator over the canonical edges, i.e. for each set of periodic copies the
|
||||
/// Unique_edge_iterator iterates over exactly one representative.
|
||||
typedef Periodic_2_triangulation_unique_edge_iterator_2<Self>
|
||||
Unique_edge_iterator;
|
||||
/// Iterator over the canonical faces, i.e. for each set of periodic copies the
|
||||
/// Unique_face_iterator iterates over exactly one representative.
|
||||
typedef Periodic_2_triangulation_unique_face_iterator_2<Self>
|
||||
Unique_face_iterator;
|
||||
|
||||
/// \name For compatibility with the Triangulation_2 class
|
||||
// \{
|
||||
|
|
@ -676,6 +684,32 @@ public:
|
|||
Periodic_2_triangulation_2_internal::Domain_tester<Self>(this));
|
||||
}
|
||||
|
||||
Unique_edge_iterator unique_edges_begin() const
|
||||
{
|
||||
return CGAL::filter_iterator(edges_end(),
|
||||
Periodic_2_triangulation_2_internal::Domain_tester<Self>(this),
|
||||
edges_begin());
|
||||
}
|
||||
/// past-the-end iterator over the canonical edges
|
||||
Unique_edge_iterator unique_edges_end() const
|
||||
{
|
||||
return CGAL::filter_iterator(edges_end(),
|
||||
Periodic_2_triangulation_2_internal::Domain_tester<Self>(this));
|
||||
}
|
||||
|
||||
Unique_face_iterator unique_faces_begin() const
|
||||
{
|
||||
return CGAL::filter_iterator(faces_end(),
|
||||
Periodic_2_triangulation_2_internal::Domain_tester<Self>(this),
|
||||
faces_begin());
|
||||
}
|
||||
/// past-the-end iterator over the non-virtual vertices
|
||||
Unique_face_iterator unique_faces_end() const
|
||||
{
|
||||
return CGAL::filter_iterator(faces_end(),
|
||||
Periodic_2_triangulation_2_internal::Domain_tester<Self>(this));
|
||||
}
|
||||
|
||||
// \}
|
||||
/// \name Geometric iterators
|
||||
//\{
|
||||
|
|
@ -972,6 +1006,32 @@ public:
|
|||
return Offset();
|
||||
}
|
||||
|
||||
// Gets the canonicalized offsets of a face.
|
||||
void get_offsets(Face_handle fh,
|
||||
Offset& off0, Offset& off1, Offset& off2) const
|
||||
{
|
||||
Offset face_off0 = int_to_off(fh->offset(0));
|
||||
Offset face_off1 = int_to_off(fh->offset(1));
|
||||
Offset face_off2 = int_to_off(fh->offset(2));
|
||||
Offset diff_off((face_off0.x() == 1 && face_off1.x() == 1 && face_off2.x() == 1) ? -1 : 0,
|
||||
(face_off0.y() == 1 && face_off1.y() == 1 && face_off2.y() == 1) ? -1 : 0);
|
||||
off0 = combine_offsets(get_offset(fh, 0), diff_off);
|
||||
off1 = combine_offsets(get_offset(fh, 1), diff_off);
|
||||
off2 = combine_offsets(get_offset(fh, 2), diff_off);
|
||||
}
|
||||
|
||||
// Gets the canonicalized offsets of an edge.
|
||||
void get_offsets(const Edge& e,
|
||||
Offset& off0, Offset& off1) const
|
||||
{
|
||||
Offset edge_off0 = int_to_off(e.first->offset(cw(e.second)));
|
||||
Offset edge_off1 = int_to_off(e.first->offset(ccw(e.second)));
|
||||
Offset diff_off((edge_off0.x() == 1 && edge_off1.x() == 1) ? -1 : 0,
|
||||
(edge_off0.y() == 1 && edge_off1.y() == 1) ? -1 : 0);
|
||||
off0 = combine_offsets(get_offset(e.first, cw(e.second)), diff_off);
|
||||
off1 = combine_offsets(get_offset(e.first, ccw(e.second)), diff_off);
|
||||
}
|
||||
|
||||
/// Converts an offset to a bit pattern where bit1==offx and bit0==offy.
|
||||
int off_to_int(const Offset & off) const
|
||||
{
|
||||
|
|
@ -986,13 +1046,12 @@ public:
|
|||
return Offset((i >> 1) & 1, i & 1);
|
||||
}
|
||||
|
||||
// \}
|
||||
// Protected functions of Periodic_2_triangulation_2
|
||||
/// Const accessor to the virtual vertices reverse map,
|
||||
/// used to optimize point location for periodic copies.
|
||||
const Virtual_vertex_reverse_map &virtual_vertices_reverse() const
|
||||
/// Tests whether a vertex is a periodic copy of a vertex in the 3-cover.
|
||||
bool is_virtual(Vertex_handle v) const
|
||||
{
|
||||
return _virtual_vertices_reverse;
|
||||
if (is_1_cover())
|
||||
return false;
|
||||
return (_virtual_vertices.find(v) != _virtual_vertices.end());
|
||||
}
|
||||
|
||||
/// [Undoc] Returns the non-virtual copy of the vertex.
|
||||
|
|
@ -1007,15 +1066,6 @@ public:
|
|||
return vh;
|
||||
}
|
||||
|
||||
|
||||
/// Tests whether a vertex is a periodic copy of a vertex in the 3-cover.
|
||||
bool is_virtual(Vertex_handle v)
|
||||
{
|
||||
if (is_1_cover())
|
||||
return false;
|
||||
return (_virtual_vertices.find(v) != _virtual_vertices.end());
|
||||
}
|
||||
|
||||
const std::vector<Vertex_handle>& periodic_copies(const Vertex_handle v) const
|
||||
{
|
||||
CGAL_precondition(number_of_sheets() != make_array(1, 1) );
|
||||
|
|
@ -1024,6 +1074,77 @@ public:
|
|||
return _virtual_vertices_reverse.find(v)->second;
|
||||
}
|
||||
|
||||
// Protected functions of Periodic_2_triangulation_2
|
||||
/// Const accessor to the virtual vertices reverse map,
|
||||
/// used to optimize point location for periodic copies.
|
||||
const Virtual_vertex_reverse_map& virtual_vertices_reverse() const
|
||||
{
|
||||
return _virtual_vertices_reverse;
|
||||
}
|
||||
|
||||
// check whether pos points onto a unique edge or not.
|
||||
// If we are computing in 1-sheeted covering this should
|
||||
// always be true.
|
||||
bool is_canonical(Face_handle fh) const
|
||||
{
|
||||
if(is_1_cover())
|
||||
return true;
|
||||
|
||||
Offset off0, off1, off2;
|
||||
get_offsets(fh, off0, off1, off2);
|
||||
|
||||
// If there is one offset with entries larger than 1 then we are
|
||||
// talking about a vertex that is too far away from the original
|
||||
// domain to belong to a canonical triangle.
|
||||
if (off0.x() > 1) return false;
|
||||
if (off0.y() > 1) return false;
|
||||
if (off1.x() > 1) return false;
|
||||
if (off1.y() > 1) return false;
|
||||
if (off2.x() > 1) return false;
|
||||
if (off2.y() > 1) return false;
|
||||
|
||||
// If there is one direction of space for which all offsets are
|
||||
// non-zero then the edge is not canonical because we can
|
||||
// take the copy closer towards the origin in that direction.
|
||||
int offx = off0.x() & off1.x() & off2.x();
|
||||
int offy = off0.y() & off1.y() & off2.y();
|
||||
|
||||
return (offx == 0 && offy == 0);
|
||||
}
|
||||
|
||||
bool is_canonical(const Edge& e) const
|
||||
{
|
||||
if(is_1_cover())
|
||||
return true;
|
||||
|
||||
// fetch all offsets
|
||||
Offset off0, off1;
|
||||
get_offsets(e, off0, off1);
|
||||
|
||||
// If there is one offset with entries larger than 1 then we are
|
||||
// talking about a vertex that is too far away from the original
|
||||
// domain to belong to a canonical edge.
|
||||
if (off0.x() > 1) return false;
|
||||
if (off0.y() > 1) return false;
|
||||
if (off1.x() > 1) return false;
|
||||
if (off1.y() > 1) return false;
|
||||
|
||||
// If there is one direction of space for which all offsets are
|
||||
// non-zero then the edge is not canonical because we can
|
||||
// take the copy closer towards the origin in that direction.
|
||||
int offx = off0.x() & off1.x();
|
||||
int offy = off0.y() & off1.y();
|
||||
|
||||
return (offx == 0 && offy == 0);
|
||||
}
|
||||
|
||||
// checks whether pos points onto a vertex inside the original domain
|
||||
bool is_canonical(Vertex_handle vh) const
|
||||
{
|
||||
return !is_virtual(vh);
|
||||
}
|
||||
|
||||
public:
|
||||
template<class Stream>
|
||||
Stream& draw_triangulation(Stream& os) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public:
|
|||
{
|
||||
if (_it == T::UNIQUE || _it == T::UNIQUE_COVER_DOMAIN)
|
||||
{
|
||||
while (pos != _t->faces_end() && !is_canonical() )
|
||||
while (pos != _t->faces_end() && !_t->is_canonical(pos) )
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ public:
|
|||
{
|
||||
++pos;
|
||||
}
|
||||
while (pos != _t->faces_end() && !is_canonical());
|
||||
while (pos != _t->faces_end() && !_t->is_canonical(pos));
|
||||
break;
|
||||
case T::STORED_COVER_DOMAIN:
|
||||
case T::UNIQUE_COVER_DOMAIN:
|
||||
|
|
@ -112,7 +112,7 @@ public:
|
|||
{
|
||||
--pos;
|
||||
}
|
||||
while (pos != _t->faces_begin() && !is_canonical());
|
||||
while (pos != _t->faces_begin() && !_t->is_canonical(pos));
|
||||
break;
|
||||
case T::STORED_COVER_DOMAIN:
|
||||
case T::UNIQUE_COVER_DOMAIN:
|
||||
|
|
@ -172,37 +172,6 @@ private:
|
|||
mutable Periodic_triangle periodic_triangle; // current triangle.
|
||||
|
||||
private:
|
||||
// check whether pos points onto a unique edge or not.
|
||||
// If we are computing in 1-sheeted covering this should
|
||||
// always be true.
|
||||
bool is_canonical()
|
||||
{
|
||||
// fetch all offsets
|
||||
Offset off0, off1, off2;
|
||||
get_edge_offsets(off0, off1, off2);
|
||||
|
||||
if (_t->number_of_sheets() != make_array(1, 1))
|
||||
{
|
||||
// If there is one offset with entries larger than 1 then we are
|
||||
// talking about a vertex that is too far away from the original
|
||||
// domain to belong to a canonical triangle.
|
||||
if (off0.x() > 1) return false;
|
||||
if (off0.y() > 1) return false;
|
||||
if (off1.x() > 1) return false;
|
||||
if (off1.y() > 1) return false;
|
||||
if (off2.x() > 1) return false;
|
||||
if (off2.y() > 1) return false;
|
||||
}
|
||||
|
||||
// If there is one direction of space for which all offsets are
|
||||
// non-zero then the edge is not canonical because we can
|
||||
// take the copy closer towards the origin in that direction.
|
||||
int offx = off0.x() & off1.x() & off2.x();
|
||||
int offy = off0.y() & off1.y() & off2.y();
|
||||
|
||||
return (offx == 0 && offy == 0);
|
||||
}
|
||||
|
||||
// Artificial incrementation function that takes periodic
|
||||
// copies into account.
|
||||
void increment_domain()
|
||||
|
|
@ -217,7 +186,7 @@ private:
|
|||
++pos;
|
||||
}
|
||||
while (_it == T::UNIQUE_COVER_DOMAIN
|
||||
&& pos != _t->faces_end() && !is_canonical());
|
||||
&& pos != _t->faces_end() && !_t->is_canonical(pos));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -241,7 +210,7 @@ private:
|
|||
{
|
||||
--pos;
|
||||
}
|
||||
while (_it == T::UNIQUE_COVER_DOMAIN && !is_canonical());
|
||||
while (_it == T::UNIQUE_COVER_DOMAIN && !_t->is_canonical(pos));
|
||||
_off = get_drawing_offsets();
|
||||
}
|
||||
else
|
||||
|
|
@ -256,25 +225,6 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
// Get the canonicalized offsets of an edge.
|
||||
// This works in any cover that is encoded in _t->combine_offsets
|
||||
void get_edge_offsets(Offset &off0, Offset &off1,
|
||||
Offset &off2) const
|
||||
{
|
||||
Offset face_off0 = _t->int_to_off(pos->offset(0));
|
||||
Offset face_off1 = _t->int_to_off(pos->offset(1));
|
||||
Offset face_off2 = _t->int_to_off(pos->offset(2));
|
||||
Offset diff_off((face_off0.x() == 1
|
||||
&& face_off1.x() == 1
|
||||
&& face_off2.x() == 1) ? -1 : 0,
|
||||
(face_off0.y() == 1
|
||||
&& face_off1.y() == 1
|
||||
&& face_off2.y() == 1) ? -1 : 0);
|
||||
off0 = _t->combine_offsets(_t->get_offset(pos, 0), diff_off);
|
||||
off1 = _t->combine_offsets(_t->get_offset(pos, 1), diff_off);
|
||||
off2 = _t->combine_offsets(_t->get_offset(pos, 2), diff_off);
|
||||
}
|
||||
|
||||
// return an integer that encodes the translations which have to be
|
||||
// applied to the edge *pos
|
||||
int get_drawing_offsets()
|
||||
|
|
@ -287,7 +237,7 @@ private:
|
|||
// internally stored inside the cell telling us that this cell
|
||||
// wraps around the domain.
|
||||
if (_it == T::UNIQUE_COVER_DOMAIN)
|
||||
get_edge_offsets(off0, off1, off2);
|
||||
_t->get_offsets(pos, off0, off1, off2);
|
||||
else
|
||||
{
|
||||
CGAL_assertion(_it == T::STORED_COVER_DOMAIN);
|
||||
|
|
@ -319,7 +269,7 @@ private:
|
|||
{
|
||||
CGAL_assertion(pos != typename T::Face_handle());
|
||||
Offset off0, off1, off2;
|
||||
get_edge_offsets(off0, off1, off2);
|
||||
_t->get_offsets(pos, off0, off1, off2);
|
||||
Offset transl_off = Offset((((_off >> 1) & 1) == 1 ? -1 : 0),
|
||||
(((_off ) & 1) == 1 ? -1 : 0));
|
||||
if (_it == T::STORED_COVER_DOMAIN)
|
||||
|
|
@ -385,7 +335,7 @@ public:
|
|||
{
|
||||
if (_it == T::UNIQUE || _it == T::UNIQUE_COVER_DOMAIN)
|
||||
{
|
||||
while (pos != _t->edges_end() && !is_canonical() )
|
||||
while (pos != _t->edges_end() && !_t->is_canonical(*pos) )
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
|
@ -407,7 +357,7 @@ public:
|
|||
{
|
||||
++pos;
|
||||
}
|
||||
while (pos != _t->edges_end() && !is_canonical());
|
||||
while (pos != _t->edges_end() && !_t->is_canonical(*pos));
|
||||
break;
|
||||
case T::STORED_COVER_DOMAIN:
|
||||
case T::UNIQUE_COVER_DOMAIN:
|
||||
|
|
@ -431,7 +381,7 @@ public:
|
|||
{
|
||||
--pos;
|
||||
}
|
||||
while (pos != _t->edges_begin() && !is_canonical());
|
||||
while (pos != _t->edges_begin() && !_t->is_canonical(*pos));
|
||||
break;
|
||||
case T::STORED_COVER_DOMAIN:
|
||||
case T::UNIQUE_COVER_DOMAIN:
|
||||
|
|
@ -490,35 +440,6 @@ private:
|
|||
mutable Periodic_segment periodic_segment; // current segment.
|
||||
|
||||
private:
|
||||
// check whether pos points onto a unique edge or not.
|
||||
// If we are computing in 1-sheeted covering this should
|
||||
// always be true.
|
||||
bool is_canonical()
|
||||
{
|
||||
// fetch all offsets
|
||||
Offset off0, off1;
|
||||
get_edge_offsets(off0, off1);
|
||||
|
||||
if (_t->number_of_sheets() != make_array(1, 1))
|
||||
{
|
||||
// If there is one offset with entries larger than 1 then we are
|
||||
// talking about a vertex that is too far away from the original
|
||||
// domain to belong to a canonical triangle.
|
||||
if (off0.x() > 1) return false;
|
||||
if (off0.y() > 1) return false;
|
||||
if (off1.x() > 1) return false;
|
||||
if (off1.y() > 1) return false;
|
||||
}
|
||||
|
||||
// If there is one direction of space for which all offsets are
|
||||
// non-zero then the edge is not canonical because we can
|
||||
// take the copy closer towards the origin in that direction.
|
||||
int offx = off0.x() & off1.x();
|
||||
int offy = off0.y() & off1.y();
|
||||
|
||||
return (offx == 0 && offy == 0);
|
||||
}
|
||||
|
||||
// Artificial incrementation function that takes periodic
|
||||
// copies into account.
|
||||
void increment_domain()
|
||||
|
|
@ -533,7 +454,7 @@ private:
|
|||
++pos;
|
||||
}
|
||||
while (_it == T::UNIQUE_COVER_DOMAIN
|
||||
&& pos != _t->edges_end() && !is_canonical());
|
||||
&& pos != _t->edges_end() && !_t->is_canonical(*pos));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -557,7 +478,7 @@ private:
|
|||
{
|
||||
--pos;
|
||||
}
|
||||
while (_it == T::UNIQUE_COVER_DOMAIN && !is_canonical());
|
||||
while (_it == T::UNIQUE_COVER_DOMAIN && !_t->is_canonical(*pos));
|
||||
_off = get_drawing_offsets();
|
||||
}
|
||||
else
|
||||
|
|
@ -572,20 +493,6 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
// Get the canonicalized offsets of an edge.
|
||||
// This works in any cover that is encoded in _t->combine_offsets
|
||||
void get_edge_offsets(Offset &off0, Offset &off1) const
|
||||
{
|
||||
Offset cell_off0 = _t->int_to_off(pos->first->offset(_t->cw(pos->second)));
|
||||
Offset cell_off1 = _t->int_to_off(pos->first->offset(_t->ccw(pos->second)));
|
||||
Offset diff_off((cell_off0.x() == 1 && cell_off1.x() == 1) ? -1 : 0,
|
||||
(cell_off0.y() == 1 && cell_off1.y() == 1) ? -1 : 0);
|
||||
off0 = _t->combine_offsets(_t->get_offset(pos->first, _t->cw(pos->second)),
|
||||
diff_off);
|
||||
off1 = _t->combine_offsets(_t->get_offset(pos->first, _t->ccw(pos->second)),
|
||||
diff_off);
|
||||
}
|
||||
|
||||
// return an integer that encodes the translations which have to be
|
||||
// applied to the edge *pos
|
||||
int get_drawing_offsets()
|
||||
|
|
@ -598,7 +505,7 @@ private:
|
|||
// internally stored inside the cell telling us that this cell
|
||||
// wraps around the domain.
|
||||
if (_it == T::UNIQUE_COVER_DOMAIN)
|
||||
get_edge_offsets(off0, off1);
|
||||
_t->get_offsets(*pos, off0, off1);
|
||||
else
|
||||
{
|
||||
CGAL_assertion(_it == T::STORED_COVER_DOMAIN);
|
||||
|
|
@ -618,7 +525,7 @@ private:
|
|||
{
|
||||
CGAL_assertion(pos->first != typename T::Face_handle());
|
||||
Offset off0, off1;
|
||||
get_edge_offsets(off0, off1);
|
||||
_t->get_offsets(*pos, off0, off1);
|
||||
Offset transl_off = Offset((((_off >> 1) & 1) == 1 ? -1 : 0),
|
||||
(( _off & 1) == 1 ? -1 : 0));
|
||||
if (_it == T::STORED_COVER_DOMAIN)
|
||||
|
|
@ -681,7 +588,7 @@ public:
|
|||
{
|
||||
if (_it == T::UNIQUE || _it == T::UNIQUE_COVER_DOMAIN)
|
||||
{
|
||||
while (pos != _t->vertices_end() && !is_canonical() )
|
||||
while (pos != _t->vertices_end() && !_t->is_canonical(pos) )
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
|
@ -705,7 +612,7 @@ public:
|
|||
{
|
||||
++pos;
|
||||
}
|
||||
while (pos != _t->vertices_end() && !is_canonical());
|
||||
while (pos != _t->vertices_end() && !_t->is_canonical(pos));
|
||||
break;
|
||||
default:
|
||||
CGAL_assertion(false);
|
||||
|
|
@ -727,7 +634,7 @@ public:
|
|||
{
|
||||
--pos;
|
||||
}
|
||||
while (pos != _t->vertices_begin() && !is_canonical());
|
||||
while (pos != _t->vertices_begin() && !_t->is_canonical(pos));
|
||||
break;
|
||||
default:
|
||||
CGAL_assertion(false);
|
||||
|
|
@ -785,14 +692,6 @@ private:
|
|||
mutable Periodic_point periodic_point; // current point.
|
||||
|
||||
private:
|
||||
// check whether pos points onto a vertex inside the original
|
||||
// domain. If we are computing in 1-sheeted covering this should
|
||||
// always be true.
|
||||
bool is_canonical()
|
||||
{
|
||||
return (_t->get_offset(pos).is_null());
|
||||
}
|
||||
|
||||
Periodic_point construct_periodic_point() const
|
||||
{
|
||||
CGAL_assertion(pos != typename T::Vertex_handle());
|
||||
|
|
@ -801,23 +700,91 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
namespace Periodic_2_triangulation_2_internal
|
||||
{
|
||||
namespace Periodic_2_triangulation_2_internal {
|
||||
|
||||
// returns `true` if the simplex is not canonical, and has to be filtered out
|
||||
template <class T>
|
||||
class Domain_tester
|
||||
{
|
||||
typedef typename T::Offset Offset;
|
||||
|
||||
const T *t;
|
||||
|
||||
public:
|
||||
Domain_tester() {}
|
||||
Domain_tester(const T *tr) : t(tr) {}
|
||||
|
||||
bool operator()(const typename T::Vertex_iterator & v) const
|
||||
bool operator()(const typename T::Vertex_iterator v) const
|
||||
{
|
||||
return (t->get_offset(v) != typename T::Offset(0, 0));
|
||||
return !(t->get_offset(v).is_null());
|
||||
}
|
||||
|
||||
bool operator()(const typename T::Edge_iterator e) const
|
||||
{
|
||||
Offset eo_0 = t->int_to_off(e->first->offset(t->cw(e->second)));
|
||||
Offset eo_1 = t->int_to_off(e->first->offset(t->ccw(e->second)));
|
||||
|
||||
Offset diff_off((eo_0.x() == 1 && eo_1.x() == 1) ? -1 : 0,
|
||||
(eo_0.y() == 1 && eo_1.y() == 1) ? -1 : 0);
|
||||
Offset off0 = t->combine_offsets(t->get_offset(e->first, t->cw(e->second)), diff_off);
|
||||
Offset off1 = t->combine_offsets(t->get_offset(e->first, t->ccw(e->second)), diff_off);
|
||||
|
||||
if (t->number_of_sheets() != make_array(1, 1))
|
||||
{
|
||||
// If there is one offset with entries larger than 1 then we are
|
||||
// talking about a vertex that is too far away from the original
|
||||
// domain to belong to a canonical edge.
|
||||
if (off0.x() > 1) return true;
|
||||
if (off0.y() > 1) return true;
|
||||
if (off1.x() > 1) return true;
|
||||
if (off1.y() > 1) return true;
|
||||
}
|
||||
|
||||
// If there is one direction of space for which all offsets are
|
||||
// non-zero then the edge is not canonical because we can
|
||||
// take the copy closer towards the origin in that direction.
|
||||
int offx = off0.x() & off1.x();
|
||||
int offy = off0.y() & off1.y();
|
||||
|
||||
return (offx != 0 || offy != 0);
|
||||
}
|
||||
|
||||
bool operator()(const typename T::Face_iterator f) const
|
||||
{
|
||||
Offset fo_0 = t->int_to_off(f->offset(0));
|
||||
Offset fo_1 = t->int_to_off(f->offset(1));
|
||||
Offset fo_2 = t->int_to_off(f->offset(2));
|
||||
|
||||
Offset diff_off((fo_0.x() == 1 && fo_1.x() == 1 && fo_2.x() == 1) ? -1 : 0,
|
||||
(fo_0.y() == 1 && fo_1.y() == 1 && fo_2.y() == 1) ? -1 : 0);
|
||||
Offset off0 = t->combine_offsets(t->get_offset(f, 0), diff_off);
|
||||
Offset off1 = t->combine_offsets(t->get_offset(f, 1), diff_off);
|
||||
Offset off2 = t->combine_offsets(t->get_offset(f, 2), diff_off);
|
||||
|
||||
if (t->number_of_sheets() != make_array(1, 1))
|
||||
{
|
||||
// If there is one offset with entries larger than 1 then we are
|
||||
// talking about a vertex that is too far away from the original
|
||||
// domain to belong to a canonical triangle.
|
||||
if (off0.x() > 1) return true;
|
||||
if (off0.y() > 1) return true;
|
||||
if (off1.x() > 1) return true;
|
||||
if (off1.y() > 1) return true;
|
||||
if (off2.x() > 1) return true;
|
||||
if (off2.y() > 1) return true;
|
||||
}
|
||||
|
||||
// If there is one direction of space for which all offsets are
|
||||
// non-zero then the edge is not canonical because we can
|
||||
// take the copy closer towards the origin in that direction.
|
||||
int offx = off0.x() & off1.x() & off2.x();
|
||||
int offy = off0.y() & off1.y() & off2.y();
|
||||
|
||||
return (offx != 0 || offy != 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // Periodic_2_triangulation_2_internal
|
||||
|
||||
// Iterates over the vertices in a periodic triangulation that are
|
||||
// located inside the original cube.
|
||||
|
|
@ -872,6 +839,108 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
// Iterates over the canonical edges in a periodic triangulation.
|
||||
// Derives from Filter_iterator in order to add a conversion to handle
|
||||
//
|
||||
// Comments:
|
||||
// When computing in 1-sheeted covering, there will be no difference
|
||||
// between a normal Edge_iterator and this iterator
|
||||
template <class T>
|
||||
class Periodic_2_triangulation_unique_edge_iterator_2
|
||||
: public Filter_iterator<typename T::Edge_iterator, Periodic_2_triangulation_2_internal::Domain_tester<T> >
|
||||
{
|
||||
typedef typename T::Edge Edge;
|
||||
typedef typename T::Edge_iterator Edge_iterator;
|
||||
|
||||
typedef typename Periodic_2_triangulation_2_internal::Domain_tester<T> Tester;
|
||||
|
||||
typedef Filter_iterator<Edge_iterator, Tester > Base;
|
||||
typedef Periodic_2_triangulation_unique_edge_iterator_2 Self;
|
||||
|
||||
public:
|
||||
Periodic_2_triangulation_unique_edge_iterator_2() : Base() {}
|
||||
Periodic_2_triangulation_unique_edge_iterator_2(const Base &b) : Base(b) {}
|
||||
|
||||
Self & operator++()
|
||||
{
|
||||
Base::operator++();
|
||||
return *this;
|
||||
}
|
||||
Self & operator--()
|
||||
{
|
||||
Base::operator--();
|
||||
return *this;
|
||||
}
|
||||
Self operator++(int)
|
||||
{
|
||||
Self tmp(*this);
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
Self operator--(int)
|
||||
{
|
||||
Self tmp(*this);
|
||||
--(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
operator Edge() const
|
||||
{
|
||||
return Base::base();
|
||||
}
|
||||
};
|
||||
|
||||
// Iterates over the canonical faces in a periodic triangulation.
|
||||
// Derives from Filter_iterator in order to add a conversion to handle
|
||||
//
|
||||
// Comments:
|
||||
// When computing in 1-sheeted covering, there will be no difference
|
||||
// between a normal Face_iterator and this iterator
|
||||
template <class T>
|
||||
class Periodic_2_triangulation_unique_face_iterator_2
|
||||
: public Filter_iterator<typename T::Face_iterator, Periodic_2_triangulation_2_internal::Domain_tester<T> >
|
||||
{
|
||||
typedef typename T::Face_handle Face_handle;
|
||||
typedef typename T::Face_iterator Face_iterator;
|
||||
|
||||
typedef typename Periodic_2_triangulation_2_internal::Domain_tester<T> Tester;
|
||||
|
||||
typedef Filter_iterator<Face_iterator, Tester > Base;
|
||||
typedef Periodic_2_triangulation_unique_face_iterator_2 Self;
|
||||
|
||||
public:
|
||||
Periodic_2_triangulation_unique_face_iterator_2() : Base() {}
|
||||
Periodic_2_triangulation_unique_face_iterator_2(const Base &b) : Base(b) {}
|
||||
|
||||
Self & operator++()
|
||||
{
|
||||
Base::operator++();
|
||||
return *this;
|
||||
}
|
||||
Self & operator--()
|
||||
{
|
||||
Base::operator--();
|
||||
return *this;
|
||||
}
|
||||
Self operator++(int)
|
||||
{
|
||||
Self tmp(*this);
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
Self operator--(int)
|
||||
{
|
||||
Self tmp(*this);
|
||||
--(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
operator Face_handle() const
|
||||
{
|
||||
return Base::base();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_PERIODIC_2_TRIANGULATION_ITERATORS_2_H
|
||||
|
|
|
|||
|
|
@ -217,19 +217,19 @@ void test_iterators()
|
|||
}
|
||||
assert(size == t_const.number_of_stored_vertices());
|
||||
size = 0;
|
||||
for (typename T::Unique_vertex_iterator uvit = t_const.unique_vertices_begin();
|
||||
uvit != t_const.unique_vertices_end(); ++uvit)
|
||||
{
|
||||
++size;
|
||||
}
|
||||
assert(size == t_const.number_of_vertices());
|
||||
size = 0;
|
||||
for (typename T::Vertex_iterator vit = t_const.all_vertices_begin();
|
||||
vit != t_const.all_vertices_end(); ++vit)
|
||||
{
|
||||
++size;
|
||||
}
|
||||
assert(size == t_const.number_of_stored_vertices());
|
||||
size = 0;
|
||||
for (typename T::Unique_vertex_iterator uvit = t_const.unique_vertices_begin();
|
||||
uvit != t_const.unique_vertices_end(); ++uvit)
|
||||
{
|
||||
++size;
|
||||
}
|
||||
assert(size == t_const.number_of_vertices());
|
||||
|
||||
// edges
|
||||
size = 0;
|
||||
|
|
@ -246,6 +246,13 @@ void test_iterators()
|
|||
++size;
|
||||
}
|
||||
assert(size == t_const.number_of_stored_edges());
|
||||
size = 0;
|
||||
for (typename T::Unique_edge_iterator uvit = t_const.unique_edges_begin();
|
||||
uvit != t_const.unique_edges_end(); ++uvit)
|
||||
{
|
||||
++size;
|
||||
}
|
||||
assert(size == t_const.number_of_edges());
|
||||
|
||||
// faces
|
||||
size = 0;
|
||||
|
|
@ -262,6 +269,13 @@ void test_iterators()
|
|||
++size;
|
||||
}
|
||||
assert(size == t_const.number_of_stored_faces());
|
||||
size = 0;
|
||||
for (typename T::Unique_face_iterator uvit = t_const.unique_faces_begin();
|
||||
uvit != t_const.unique_faces_end(); ++uvit)
|
||||
{
|
||||
++size;
|
||||
}
|
||||
assert(size == t_const.number_of_faces());
|
||||
|
||||
/// Geometric iterators
|
||||
for (typename T::Periodic_point_iterator ppit = t_const.periodic_points_begin();
|
||||
|
|
|
|||
|
|
@ -169,6 +169,13 @@ public:
|
|||
typedef Facet_iterator All_facets_iterator;
|
||||
typedef Edge_iterator All_edges_iterator;
|
||||
typedef Vertex_iterator All_vertices_iterator;
|
||||
|
||||
typedef Periodic_3_triangulation_unique_cell_iterator_3<Self>
|
||||
Unique_cell_iterator;
|
||||
typedef Periodic_3_triangulation_unique_facet_iterator_3<Self>
|
||||
Unique_facet_iterator;
|
||||
typedef Periodic_3_triangulation_unique_edge_iterator_3<Self>
|
||||
Unique_edge_iterator;
|
||||
typedef Periodic_3_triangulation_unique_vertex_iterator_3<Self>
|
||||
Unique_vertex_iterator;
|
||||
|
||||
|
|
@ -397,26 +404,14 @@ public:
|
|||
}
|
||||
|
||||
const Covering_sheets& number_of_sheets() const { return _cover; }
|
||||
const std::pair<Vertex_handle, Offset> original_vertex(const Vertex_handle v) const
|
||||
{
|
||||
return (virtual_vertices.find(v) == virtual_vertices.end()) ?
|
||||
std::make_pair(v,Offset()) : virtual_vertices.find(v)->second;
|
||||
}
|
||||
const std::vector<Vertex_handle>& periodic_copies(const Vertex_handle v) const
|
||||
{
|
||||
CGAL_precondition(number_of_sheets() != CGAL::make_array(1,1,1));
|
||||
CGAL_precondition(virtual_vertices.find(v) == virtual_vertices.end());
|
||||
CGAL_assertion(
|
||||
virtual_vertices_reverse.find(v) != virtual_vertices_reverse.end());
|
||||
return virtual_vertices_reverse.find(v)->second;
|
||||
}
|
||||
|
||||
bool is_triangulation_in_1_sheet() const;
|
||||
|
||||
void convert_to_1_sheeted_covering();
|
||||
|
||||
virtual void update_cover_data_after_converting_to_27_sheeted_covering() { }
|
||||
void convert_to_27_sheeted_covering();
|
||||
|
||||
public:
|
||||
size_type number_of_cells() const {
|
||||
if(is_1_cover()) return _tds.number_of_cells();
|
||||
else return _tds.number_of_cells()/27;
|
||||
|
|
@ -460,14 +455,6 @@ public:
|
|||
_cover = cover;
|
||||
}
|
||||
|
||||
public:
|
||||
bool is_virtual(Vertex_handle v)
|
||||
{
|
||||
if(is_1_cover())
|
||||
return false;
|
||||
return (virtual_vertices.find(v) != virtual_vertices.end());
|
||||
}
|
||||
|
||||
public:
|
||||
// Offset converters
|
||||
int off_to_int(const Offset& off) const
|
||||
|
|
@ -549,6 +536,232 @@ public:
|
|||
c->set_offsets(o0i,o1i,o2i,o3i);
|
||||
}
|
||||
|
||||
public:
|
||||
// undocumented access functions
|
||||
Offset get_offset(Cell_handle ch, int i) const
|
||||
{
|
||||
if(is_1_cover())
|
||||
return int_to_off(ch->offset(i));
|
||||
|
||||
Virtual_vertex_map_it it = virtual_vertices.find(ch->vertex(i));
|
||||
if(it != virtual_vertices.end())
|
||||
return combine_offsets(it->second.second, int_to_off(ch->offset(i)));
|
||||
else
|
||||
return combine_offsets(Offset(), int_to_off(ch->offset(i)));
|
||||
}
|
||||
|
||||
Offset get_offset(Vertex_handle vh) const
|
||||
{
|
||||
if(is_1_cover())
|
||||
return Offset();
|
||||
|
||||
Virtual_vertex_map_it it = virtual_vertices.find(vh);
|
||||
if(it != virtual_vertices.end())
|
||||
return it->second.second;
|
||||
else
|
||||
return Offset();
|
||||
}
|
||||
|
||||
// Get the canonicalized offsets of a cell.
|
||||
void get_offsets(Cell_handle ch,
|
||||
Offset& off0, Offset& off1, Offset& off2, Offset& off3) const
|
||||
{
|
||||
Offset cell_off0 = int_to_off(ch->offset(0));
|
||||
Offset cell_off1 = int_to_off(ch->offset(1));
|
||||
Offset cell_off2 = int_to_off(ch->offset(2));
|
||||
Offset cell_off3 = int_to_off(ch->offset(3));
|
||||
Offset diff_off((cell_off0.x() == 1 && cell_off1.x() == 1 &&
|
||||
cell_off2.x() == 1 && cell_off3.x() == 1) ? -1 : 0,
|
||||
(cell_off0.y() == 1 && cell_off1.y() == 1 &&
|
||||
cell_off2.y() == 1 && cell_off3.y() == 1) ? -1 : 0,
|
||||
(cell_off0.z() == 1 && cell_off1.z() == 1 &&
|
||||
cell_off2.z() == 1 && cell_off3.z() == 1) ? -1 : 0);
|
||||
off0 = combine_offsets(get_offset(ch,0), diff_off);
|
||||
off1 = combine_offsets(get_offset(ch,1), diff_off);
|
||||
off2 = combine_offsets(get_offset(ch,2), diff_off);
|
||||
off3 = combine_offsets(get_offset(ch,3), diff_off);
|
||||
}
|
||||
|
||||
// Gets the canonicalized offsets of a face.
|
||||
void get_offsets(const Facet& f,
|
||||
Offset& off0, Offset& off1, Offset& off2) const
|
||||
{
|
||||
Offset cell_off0 = int_to_off(f.first->offset((f.second+1)&3));
|
||||
Offset cell_off1 = int_to_off(f.first->offset((f.second+2)&3));
|
||||
Offset cell_off2 = int_to_off(f.first->offset((f.second+3)&3));
|
||||
Offset diff_off((cell_off0.x() == 1 && cell_off1.x() == 1 && cell_off2.x() == 1) ? -1 : 0,
|
||||
(cell_off0.y() == 1 && cell_off1.y() == 1 && cell_off2.y() == 1) ? -1 : 0,
|
||||
(cell_off0.z() == 1 && cell_off1.z() == 1 && cell_off2.z() == 1) ? -1 : 0);
|
||||
off0 = combine_offsets(get_offset(f.first, (f.second+1)&3), diff_off);
|
||||
off1 = combine_offsets(get_offset(f.first, (f.second+2)&3), diff_off);
|
||||
off2 = combine_offsets(get_offset(f.first, (f.second+3)&3), diff_off);
|
||||
}
|
||||
|
||||
// Gets the canonicalized offsets of an edge.
|
||||
void get_offsets(const Edge& e,
|
||||
Offset& off0, Offset& off1) const
|
||||
{
|
||||
Offset cell_off0 = int_to_off(e.first->offset(e.second));
|
||||
Offset cell_off1 = int_to_off(e.first->offset(e.third));
|
||||
Offset diff_off((cell_off0.x()==1 && cell_off1.x()==1) ? -1 : 0,
|
||||
(cell_off0.y()==1 && cell_off1.y()==1) ? -1 : 0,
|
||||
(cell_off0.z()==1 && cell_off1.z()==1) ? -1 : 0);
|
||||
off0 = combine_offsets(get_offset(e.first, e.second), diff_off);
|
||||
off1 = combine_offsets(get_offset(e.first, e.third), diff_off);
|
||||
}
|
||||
|
||||
public:
|
||||
Offset combine_offsets(const Offset& o_c, const Offset& o_t) const
|
||||
{
|
||||
Offset o_ct(_cover[0]*o_t.x(), _cover[1]*o_t.y(), _cover[2]*o_t.z());
|
||||
return o_c + o_ct;
|
||||
}
|
||||
|
||||
public:
|
||||
Offset neighbor_offset(Cell_handle ch, int i, Cell_handle nb) const;
|
||||
|
||||
Offset neighbor_offset(Cell_handle ch, int i) const
|
||||
{
|
||||
return neighbor_offset(ch, i, ch->neighbor(i));
|
||||
}
|
||||
|
||||
public:
|
||||
/// Tests whether a vertex is a periodic copy of a vertex in the 3-cover.
|
||||
bool is_virtual(Vertex_handle vh) const
|
||||
{
|
||||
if(is_1_cover())
|
||||
return false;
|
||||
return (virtual_vertices.find(vh) != virtual_vertices.end());
|
||||
}
|
||||
|
||||
/// Returns the non-virtual (i.e. canonical) copy of the vertex.
|
||||
Vertex_handle get_original_vertex(Vertex_handle vh) const
|
||||
{
|
||||
if(is_1_cover())
|
||||
return vh;
|
||||
|
||||
Virtual_vertex_map_it it = virtual_vertices.find(vh);
|
||||
if(it != virtual_vertices.end())
|
||||
return it->second.first;
|
||||
else
|
||||
return vh;
|
||||
}
|
||||
|
||||
const std::pair<Vertex_handle, Offset> original_vertex(const Vertex_handle v) const
|
||||
{
|
||||
return (virtual_vertices.find(v) == virtual_vertices.end()) ?
|
||||
std::make_pair(v,Offset()) : virtual_vertices.find(v)->second;
|
||||
}
|
||||
|
||||
const std::vector<Vertex_handle>& periodic_copies(const Vertex_handle v) const
|
||||
{
|
||||
CGAL_precondition(number_of_sheets() != CGAL::make_array(1,1,1));
|
||||
CGAL_precondition(virtual_vertices.find(v) == virtual_vertices.end());
|
||||
CGAL_assertion(
|
||||
virtual_vertices_reverse.find(v) != virtual_vertices_reverse.end());
|
||||
return virtual_vertices_reverse.find(v)->second;
|
||||
}
|
||||
|
||||
public:
|
||||
bool is_canonical(Cell_handle ch) const
|
||||
{
|
||||
if(is_1_cover())
|
||||
return true;
|
||||
|
||||
Offset off0, off1, off2, off3;
|
||||
get_offsets(ch, off0, off1, off2, off3);
|
||||
|
||||
// If there is one offset with entries larger than 1 then we are
|
||||
// talking about a vertex that is too far away from the original
|
||||
// domain to belong to a canonical triangle.
|
||||
if (off0.x() > 1) return false;
|
||||
if (off0.y() > 1) return false;
|
||||
if (off0.z() > 1) return false;
|
||||
if (off1.x() > 1) return false;
|
||||
if (off1.y() > 1) return false;
|
||||
if (off1.z() > 1) return false;
|
||||
if (off2.x() > 1) return false;
|
||||
if (off2.y() > 1) return false;
|
||||
if (off2.z() > 1) return false;
|
||||
if (off3.x() > 1) return false;
|
||||
if (off3.y() > 1) return false;
|
||||
if (off3.z() > 1) return false;
|
||||
|
||||
// If there is one direction of space for which all offsets are
|
||||
// non-zero then the edge is not canonical because we can
|
||||
// take the copy closer towards the origin in that direction.
|
||||
int offx = off0.x() & off1.x() & off2.x() & off3.x();
|
||||
int offy = off0.y() & off1.y() & off2.y() & off3.y();
|
||||
int offz = off0.z() & off1.z() & off2.z() & off3.z();
|
||||
|
||||
return (offx == 0 && offy == 0 && offz == 0);
|
||||
}
|
||||
|
||||
bool is_canonical(const Edge& e) const
|
||||
{
|
||||
if(is_1_cover())
|
||||
return true;
|
||||
|
||||
Offset off0, off1;
|
||||
get_offsets(e, off0, off1);
|
||||
|
||||
// If there is one offset with entries larger than 1 then we are
|
||||
// talking about a vertex that is too far away from the original
|
||||
// domain to belong to a canonical edge.
|
||||
if (off0.x() > 1) return false;
|
||||
if (off0.y() > 1) return false;
|
||||
if (off0.z() > 1) return false;
|
||||
if (off1.x() > 1) return false;
|
||||
if (off1.y() > 1) return false;
|
||||
if (off1.z() > 1) return false;
|
||||
|
||||
// If there is one direction of space for which all offsets are
|
||||
// non-zero then the edge is not canonical because we can
|
||||
// take the copy closer towards the origin in that direction.
|
||||
int offx = off0.x() & off1.x();
|
||||
int offy = off0.y() & off1.y();
|
||||
int offz = off0.z() & off1.z();
|
||||
|
||||
return (offx == 0 && offy == 0 && offz == 0);
|
||||
}
|
||||
|
||||
bool is_canonical(const Facet& f) const
|
||||
{
|
||||
if(is_1_cover())
|
||||
return true;
|
||||
|
||||
Offset off0, off1, off2;
|
||||
get_offsets(f, off0, off1, off2);
|
||||
|
||||
// If there is one offset with entries larger than 1 then we are
|
||||
// talking about a vertex that is too far away from the original
|
||||
// domain to belong to a canonical triangle.
|
||||
if(off0.x() > 1) return false;
|
||||
if(off0.y() > 1) return false;
|
||||
if(off0.z() > 1) return false;
|
||||
if(off1.x() > 1) return false;
|
||||
if(off1.y() > 1) return false;
|
||||
if(off1.z() > 1) return false;
|
||||
if(off2.x() > 1) return false;
|
||||
if(off2.y() > 1) return false;
|
||||
if(off2.z() > 1) return false;
|
||||
|
||||
// If there is one direction of space for which all offsets are
|
||||
// non-zero then the facet is not canonical because we can
|
||||
// take the copy closer towards the origin in that direction.
|
||||
int offx = off0.x() & off1.x() & off2.x();
|
||||
int offy = off0.y() & off1.y() & off2.y();
|
||||
int offz = off0.z() & off1.z() & off2.z();
|
||||
|
||||
return (offx == 0 && offy == 0 && offz == 0);
|
||||
}
|
||||
|
||||
/// Tests whether a vertex belongs to the original (canonical) domain.
|
||||
bool is_canonical(Vertex_handle vh) const
|
||||
{
|
||||
return !is_virtual(vh);
|
||||
}
|
||||
|
||||
public:
|
||||
/** @name Wrapping the traits */
|
||||
// Note that calling functors with "construct_point(p), offset" and not
|
||||
|
|
@ -988,6 +1201,14 @@ public:
|
|||
// end of geometric functions
|
||||
|
||||
public:
|
||||
// These functions give the pair (vertex, offset) that corresponds to the
|
||||
// i-th vertex of cell ch or vertex vh, respectively.
|
||||
void get_vertex(Cell_handle ch, int i, Vertex_handle& vh, Offset& off) const;
|
||||
void get_vertex(Vertex_handle vh_i, Vertex_handle& vh, Offset& off) const;
|
||||
|
||||
// Auxiliary functions
|
||||
Cell_handle get_cell(const Vertex_handle* vh) const;
|
||||
|
||||
/** @name Queries */
|
||||
bool is_vertex(const Point& p, Vertex_handle& v) const;
|
||||
|
||||
|
|
@ -1305,6 +1526,14 @@ public:
|
|||
std::vector<Vertex_handle> insert_generic_dummy_points();
|
||||
|
||||
protected:
|
||||
template<class Conflict_tester>
|
||||
Offset get_location_offset(const Conflict_tester& tester,
|
||||
Cell_handle c) const;
|
||||
|
||||
template<class Conflict_tester>
|
||||
Offset get_location_offset(const Conflict_tester& tester,
|
||||
Cell_handle c, bool& found) const;
|
||||
|
||||
// this is needed for compatibility reasons
|
||||
template <class Conflict_test, class OutputIteratorBoundaryFacets,
|
||||
class OutputIteratorCells, class OutputIteratorInternalFacets>
|
||||
|
|
@ -1530,6 +1759,16 @@ public:
|
|||
return _tds.facets_end();
|
||||
}
|
||||
|
||||
// Unique iterators
|
||||
|
||||
Unique_cell_iterator unique_cells_begin() const {
|
||||
return CGAL::filter_iterator(cells_end(), Domain_tester<Self>(this),
|
||||
cells_begin());
|
||||
}
|
||||
Unique_cell_iterator unique_cells_end() const {
|
||||
return CGAL::filter_iterator(cells_end(), Domain_tester<Self>(this));
|
||||
}
|
||||
|
||||
Unique_vertex_iterator unique_vertices_begin() const {
|
||||
return CGAL::filter_iterator(vertices_end(), Domain_tester<Self>(this),
|
||||
vertices_begin());
|
||||
|
|
@ -1538,6 +1777,22 @@ public:
|
|||
return CGAL::filter_iterator(vertices_end(), Domain_tester<Self>(this));
|
||||
}
|
||||
|
||||
Unique_edge_iterator unique_edges_begin() const {
|
||||
return CGAL::filter_iterator(edges_end(), Domain_tester<Self>(this),
|
||||
edges_begin());
|
||||
}
|
||||
Unique_edge_iterator unique_edges_end() const {
|
||||
return CGAL::filter_iterator(edges_end(), Domain_tester<Self>(this));
|
||||
}
|
||||
|
||||
Unique_facet_iterator unique_facets_begin() const {
|
||||
return CGAL::filter_iterator(facets_end(), Domain_tester<Self>(this),
|
||||
facets_begin());
|
||||
}
|
||||
Unique_facet_iterator unique_facets_end() const {
|
||||
return CGAL::filter_iterator(facets_end(), Domain_tester<Self>(this));
|
||||
}
|
||||
|
||||
// Geometric iterators
|
||||
Periodic_tetrahedron_iterator periodic_tetrahedra_begin(
|
||||
Iterator_type it = STORED) const {
|
||||
|
|
@ -1695,75 +1950,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
public:
|
||||
// undocumented access functions
|
||||
Offset get_offset(Cell_handle ch, int i) const
|
||||
{
|
||||
if(is_1_cover())
|
||||
return int_to_off(ch->offset(i));
|
||||
|
||||
Virtual_vertex_map_it it = virtual_vertices.find(ch->vertex(i));
|
||||
if(it != virtual_vertices.end())
|
||||
return combine_offsets(it->second.second, int_to_off(ch->offset(i)));
|
||||
else
|
||||
return combine_offsets(Offset(), int_to_off(ch->offset(i)));
|
||||
}
|
||||
|
||||
Offset get_offset(Vertex_handle vh) const
|
||||
{
|
||||
if(is_1_cover())
|
||||
return Offset();
|
||||
|
||||
Virtual_vertex_map_it it = virtual_vertices.find(vh);
|
||||
if(it != virtual_vertices.end())
|
||||
return it->second.second;
|
||||
else
|
||||
return Offset();
|
||||
}
|
||||
|
||||
Vertex_handle get_original_vertex(Vertex_handle vh) const
|
||||
{
|
||||
if(is_1_cover())
|
||||
return vh;
|
||||
|
||||
Virtual_vertex_map_it it = virtual_vertices.find(vh);
|
||||
if(it != virtual_vertices.end())
|
||||
return it->second.first;
|
||||
else
|
||||
return vh;
|
||||
}
|
||||
|
||||
Offset combine_offsets(const Offset& o_c, const Offset& o_t) const
|
||||
{
|
||||
Offset o_ct(_cover[0]*o_t.x(), _cover[1]*o_t.y(), _cover[2]*o_t.z());
|
||||
return o_c + o_ct;
|
||||
}
|
||||
|
||||
// These functions give the pair (vertex, offset) that corresponds to the
|
||||
// i-th vertex of cell ch or vertex vh, respectively.
|
||||
void get_vertex(Cell_handle ch, int i, Vertex_handle& vh, Offset& off) const;
|
||||
void get_vertex(Vertex_handle vh_i, Vertex_handle& vh, Offset& off) const;
|
||||
|
||||
protected:
|
||||
// Auxiliary functions
|
||||
Cell_handle get_cell(const Vertex_handle* vh) const;
|
||||
|
||||
template<class Conflict_tester>
|
||||
Offset get_location_offset(const Conflict_tester& tester,
|
||||
Cell_handle c) const;
|
||||
|
||||
template<class Conflict_tester>
|
||||
Offset get_location_offset(const Conflict_tester& tester,
|
||||
Cell_handle c, bool& found) const;
|
||||
|
||||
Offset neighbor_offset(Cell_handle ch, int i, Cell_handle nb) const;
|
||||
|
||||
public:
|
||||
Offset neighbor_offset(Cell_handle ch, int i) const
|
||||
{
|
||||
return neighbor_offset(ch, i, ch->neighbor(i));
|
||||
}
|
||||
|
||||
protected:
|
||||
/** @name Friends */
|
||||
friend std::istream& operator>> <>
|
||||
|
|
@ -1788,51 +1974,6 @@ protected:
|
|||
return construct_periodic_point(p);
|
||||
}
|
||||
|
||||
public:
|
||||
bool is_canonical(const Facet& f) const
|
||||
{
|
||||
if(number_of_sheets() == CGAL::make_array(1,1,1))
|
||||
return true;
|
||||
|
||||
Offset cell_off0 = int_to_off(f.first->offset((f.second+1)&3));
|
||||
Offset cell_off1 = int_to_off(f.first->offset((f.second+2)&3));
|
||||
Offset cell_off2 = int_to_off(f.first->offset((f.second+3)&3));
|
||||
Offset diff_off((cell_off0.x() == 1
|
||||
&& cell_off1.x() == 1
|
||||
&& cell_off2.x() == 1) ? -1 : 0,
|
||||
(cell_off0.y() == 1
|
||||
&& cell_off1.y() == 1
|
||||
&& cell_off2.y() == 1) ? -1 : 0,
|
||||
(cell_off0.z() == 1
|
||||
&& cell_off1.z() == 1
|
||||
&& cell_off2.z() == 1) ? -1 : 0);
|
||||
Offset off0 = combine_offsets(get_offset(f.first, (f.second+1)&3), diff_off);
|
||||
Offset off1 = combine_offsets(get_offset(f.first, (f.second+2)&3), diff_off);
|
||||
Offset off2 = combine_offsets(get_offset(f.first, (f.second+3)&3), diff_off);
|
||||
|
||||
// If there is one offset with entries larger than 1 then we are
|
||||
// talking about a vertex that is too far away from the original
|
||||
// domain to belong to a canonical triangle.
|
||||
if(off0.x() > 1) return false;
|
||||
if(off0.y() > 1) return false;
|
||||
if(off0.z() > 1) return false;
|
||||
if(off1.x() > 1) return false;
|
||||
if(off1.y() > 1) return false;
|
||||
if(off1.z() > 1) return false;
|
||||
if(off2.x() > 1) return false;
|
||||
if(off2.y() > 1) return false;
|
||||
if(off2.z() > 1) return false;
|
||||
|
||||
// If there is one direction of space for which all offsets are
|
||||
// non-zero then the edge is not canonical because we can
|
||||
// take the copy closer towards the origin in that direction.
|
||||
int offx = off0.x() & off1.x() & off2.x();
|
||||
int offy = off0.y() & off1.y() & off2.y();
|
||||
int offz = off0.z() & off1.z() & off2.z();
|
||||
|
||||
return (offx == 0 && offy == 0 && offz == 0);
|
||||
}
|
||||
|
||||
protected:
|
||||
template <class ConstructCircumcenter>
|
||||
bool canonical_dual_segment(Cell_handle c, int i, Periodic_segment_3& ps,
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public:
|
|||
Iterator_type it = T::STORED)
|
||||
: _t(t), pos(_t->cells_begin()), _it(it), _off(0) {
|
||||
if (_it == T::UNIQUE || _it == T::UNIQUE_COVER_DOMAIN) {
|
||||
while (pos != _t->cells_end() && !is_canonical() )
|
||||
while (pos != _t->cells_end() && !_t->is_canonical(pos) )
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
|
@ -79,7 +79,7 @@ public:
|
|||
++pos;
|
||||
break;
|
||||
case T::UNIQUE:
|
||||
do { ++pos; } while (pos != _t->cells_end() && !is_canonical());
|
||||
do { ++pos; } while (pos != _t->cells_end() && !_t->is_canonical(pos));
|
||||
break;
|
||||
case T::STORED_COVER_DOMAIN:
|
||||
case T::UNIQUE_COVER_DOMAIN:
|
||||
|
|
@ -97,7 +97,7 @@ public:
|
|||
--pos;
|
||||
break;
|
||||
case T::UNIQUE:
|
||||
do { --pos; } while (pos != _t->cells_begin() && !is_canonical());
|
||||
do { --pos; } while (pos != _t->cells_begin() && !_t->is_canonical(pos));
|
||||
break;
|
||||
case T::STORED_COVER_DOMAIN:
|
||||
case T::UNIQUE_COVER_DOMAIN:
|
||||
|
|
@ -156,42 +156,6 @@ private:
|
|||
mutable Periodic_tetrahedron periodic_tetrahedron; // current tetrahedron.
|
||||
|
||||
private:
|
||||
// check whether pos points onto a unique edge or not.
|
||||
// If we are computing in 1-sheeted covering this should
|
||||
// always be true.
|
||||
bool is_canonical() {
|
||||
// fetch all offsets
|
||||
Offset off0, off1, off2, off3;
|
||||
get_edge_offsets(off0, off1, off2, off3);
|
||||
|
||||
if (_t->number_of_sheets() != make_array(1,1,1)) {
|
||||
// If there is one offset with entries larger than 1 then we are
|
||||
// talking about a vertex that is too far away from the original
|
||||
// domain to belong to a canonical triangle.
|
||||
if (off0.x() > 1) return false;
|
||||
if (off0.y() > 1) return false;
|
||||
if (off0.z() > 1) return false;
|
||||
if (off1.x() > 1) return false;
|
||||
if (off1.y() > 1) return false;
|
||||
if (off1.z() > 1) return false;
|
||||
if (off2.x() > 1) return false;
|
||||
if (off2.y() > 1) return false;
|
||||
if (off2.z() > 1) return false;
|
||||
if (off3.x() > 1) return false;
|
||||
if (off3.y() > 1) return false;
|
||||
if (off3.z() > 1) return false;
|
||||
}
|
||||
|
||||
// If there is one direction of space for which all offsets are
|
||||
// non-zero then the edge is not canonical because we can
|
||||
// take the copy closer towards the origin in that direction.
|
||||
int offx = off0.x() & off1.x() & off2.x() & off3.x();
|
||||
int offy = off0.y() & off1.y() & off2.y() & off3.y();
|
||||
int offz = off0.z() & off1.z() & off2.z() & off3.z();
|
||||
|
||||
return (offx == 0 && offy == 0 && offz == 0);
|
||||
}
|
||||
|
||||
// Artificial incrementation function that takes periodic
|
||||
// copies into account.
|
||||
void increment_domain() {
|
||||
|
|
@ -200,7 +164,7 @@ private:
|
|||
if (_off == off) {
|
||||
_off = 0;
|
||||
do { ++pos; } while (_it == T::UNIQUE_COVER_DOMAIN
|
||||
&& pos != _t->cells_end() && !is_canonical());
|
||||
&& pos != _t->cells_end() && !_t->is_canonical(pos));
|
||||
} else {
|
||||
do {
|
||||
++_off;
|
||||
|
|
@ -214,7 +178,7 @@ private:
|
|||
void decrement_domain() {
|
||||
if (_off == 0) {
|
||||
if (pos == _t->cells_begin()) return;
|
||||
do { --pos; } while (_it == T::UNIQUE_COVER_DOMAIN && !is_canonical());
|
||||
do { --pos; } while (_it == T::UNIQUE_COVER_DOMAIN && !_t->is_canonical(pos));
|
||||
_off = get_drawing_offsets();
|
||||
} else {
|
||||
int off = get_drawing_offsets();
|
||||
|
|
@ -225,32 +189,6 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
// Get the canonicalized offsets of an edge.
|
||||
// This works in any cover that is encoded in _t->combine_offsets
|
||||
void get_edge_offsets(Offset &off0, Offset &off1,
|
||||
Offset &off2, Offset &off3) const {
|
||||
Offset cell_off0 = _t->int_to_off(pos->offset(0));
|
||||
Offset cell_off1 = _t->int_to_off(pos->offset(1));
|
||||
Offset cell_off2 = _t->int_to_off(pos->offset(2));
|
||||
Offset cell_off3 = _t->int_to_off(pos->offset(3));
|
||||
Offset diff_off((cell_off0.x() == 1
|
||||
&& cell_off1.x() == 1
|
||||
&& cell_off2.x() == 1
|
||||
&& cell_off3.x() == 1)?-1:0,
|
||||
(cell_off0.y() == 1
|
||||
&& cell_off1.y() == 1
|
||||
&& cell_off2.y() == 1
|
||||
&& cell_off3.y() == 1)?-1:0,
|
||||
(cell_off0.z() == 1
|
||||
&& cell_off1.z() == 1
|
||||
&& cell_off2.z() == 1
|
||||
&& cell_off3.z() == 1)?-1:0);
|
||||
off0 = _t->combine_offsets(_t->get_offset(pos,0), diff_off);
|
||||
off1 = _t->combine_offsets(_t->get_offset(pos,1), diff_off);
|
||||
off2 = _t->combine_offsets(_t->get_offset(pos,2), diff_off);
|
||||
off3 = _t->combine_offsets(_t->get_offset(pos,3), diff_off);
|
||||
}
|
||||
|
||||
// return an integer that encodes the translations which have to be
|
||||
// applied to the edge *pos
|
||||
int get_drawing_offsets() {
|
||||
|
|
@ -262,7 +200,7 @@ private:
|
|||
// internally stored inside the cell telling us that this cell
|
||||
// wraps around the domain.
|
||||
if (_it == T::UNIQUE_COVER_DOMAIN)
|
||||
get_edge_offsets(off0,off1,off2,off3);
|
||||
_t->get_offsets(pos, off0, off1, off2, off3);
|
||||
else {
|
||||
CGAL_assertion(_it == T::STORED_COVER_DOMAIN);
|
||||
off0 = _t->int_to_off(pos->offset(0));
|
||||
|
|
@ -303,7 +241,7 @@ private:
|
|||
Periodic_tetrahedron construct_periodic_tetrahedron() const {
|
||||
CGAL_assertion(pos != typename T::Cell_handle());
|
||||
Offset off0, off1, off2, off3;
|
||||
get_edge_offsets(off0, off1, off2, off3);
|
||||
_t->get_offsets(pos, off0, off1, off2, off3);
|
||||
Offset transl_off = Offset((((_off>>2)&1)==1 ? -1:0),
|
||||
(((_off>>1)&1)==1 ? -1:0),
|
||||
(( _off &1)==1 ? -1:0));
|
||||
|
|
@ -369,7 +307,7 @@ public:
|
|||
Iterator_type it = T::STORED)
|
||||
: _t(t), pos(_t->facets_begin()), _it(it), _off(0) {
|
||||
if (_it == T::UNIQUE || _it == T::UNIQUE_COVER_DOMAIN) {
|
||||
while (pos != _t->facets_end() && !is_canonical() )
|
||||
while (pos != _t->facets_end() && !_t->is_canonical(*pos) )
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
|
@ -385,7 +323,7 @@ public:
|
|||
++pos;
|
||||
break;
|
||||
case T::UNIQUE:
|
||||
do { ++pos; } while (pos != _t->facets_end() && !is_canonical());
|
||||
do { ++pos; } while (pos != _t->facets_end() && !_t->is_canonical(*pos));
|
||||
break;
|
||||
case T::STORED_COVER_DOMAIN:
|
||||
case T::UNIQUE_COVER_DOMAIN:
|
||||
|
|
@ -403,7 +341,7 @@ public:
|
|||
--pos;
|
||||
break;
|
||||
case T::UNIQUE:
|
||||
do { --pos; } while (pos != _t->facets_begin() && !is_canonical());
|
||||
do { --pos; } while (pos != _t->facets_begin() && !_t->is_canonical(*pos));
|
||||
break;
|
||||
case T::STORED_COVER_DOMAIN:
|
||||
case T::UNIQUE_COVER_DOMAIN:
|
||||
|
|
@ -462,39 +400,6 @@ private:
|
|||
mutable Periodic_triangle periodic_triangle; // current segment.
|
||||
|
||||
private:
|
||||
// check whether pos points onto a unique edge or not.
|
||||
// If we are computing in 1-sheeted covering this should
|
||||
// always be true.
|
||||
bool is_canonical() {
|
||||
// fetch all offsets
|
||||
Offset off0, off1, off2;
|
||||
get_edge_offsets(off0, off1, off2);
|
||||
|
||||
if (_t->number_of_sheets() != make_array(1,1,1)) {
|
||||
// If there is one offset with entries larger than 1 then we are
|
||||
// talking about a vertex that is too far away from the original
|
||||
// domain to belong to a canonical triangle.
|
||||
if (off0.x() > 1) return false;
|
||||
if (off0.y() > 1) return false;
|
||||
if (off0.z() > 1) return false;
|
||||
if (off1.x() > 1) return false;
|
||||
if (off1.y() > 1) return false;
|
||||
if (off1.z() > 1) return false;
|
||||
if (off2.x() > 1) return false;
|
||||
if (off2.y() > 1) return false;
|
||||
if (off2.z() > 1) return false;
|
||||
}
|
||||
|
||||
// If there is one direction of space for which all offsets are
|
||||
// non-zero then the edge is not canonical because we can
|
||||
// take the copy closer towards the origin in that direction.
|
||||
int offx = off0.x() & off1.x() & off2.x();
|
||||
int offy = off0.y() & off1.y() & off2.y();
|
||||
int offz = off0.z() & off1.z() & off2.z();
|
||||
|
||||
return (offx == 0 && offy == 0 && offz == 0);
|
||||
}
|
||||
|
||||
// Artificial incrementation function that takes periodic
|
||||
// copies into account.
|
||||
void increment_domain() {
|
||||
|
|
@ -503,7 +408,7 @@ private:
|
|||
if (_off == off) {
|
||||
_off = 0;
|
||||
do { ++pos; } while (_it == T::UNIQUE_COVER_DOMAIN
|
||||
&& pos != _t->facets_end() && !is_canonical());
|
||||
&& pos != _t->facets_end() && !_t->is_canonical(*pos));
|
||||
} else {
|
||||
do {
|
||||
++_off;
|
||||
|
|
@ -517,7 +422,7 @@ private:
|
|||
void decrement_domain() {
|
||||
if (_off == 0) {
|
||||
if (pos == _t->facets_begin()) return;
|
||||
do { --pos; } while (_it == T::UNIQUE_COVER_DOMAIN && !is_canonical());
|
||||
do { --pos; } while (_it == T::UNIQUE_COVER_DOMAIN && !_t->is_canonical(*pos));
|
||||
_off = get_drawing_offsets();
|
||||
} else {
|
||||
int off = get_drawing_offsets();
|
||||
|
|
@ -528,32 +433,6 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
// Get the canonicalized offsets of an edge.
|
||||
// This works in any cover that is encoded in _t->combine_offsets
|
||||
void get_edge_offsets(Offset &off0, Offset &off1, Offset &off2) const {
|
||||
Offset cell_off0 = _t->int_to_off(pos->first->offset((pos->second+1)&3));
|
||||
Offset cell_off1 = _t->int_to_off(pos->first->offset((pos->second+2)&3));
|
||||
Offset cell_off2 = _t->int_to_off(pos->first->offset((pos->second+3)&3));
|
||||
Offset diff_off((cell_off0.x() == 1
|
||||
&& cell_off1.x() == 1
|
||||
&& cell_off2.x() == 1)?-1:0,
|
||||
(cell_off0.y() == 1
|
||||
&& cell_off1.y() == 1
|
||||
&& cell_off2.y() == 1)?-1:0,
|
||||
(cell_off0.z() == 1
|
||||
&& cell_off1.z() == 1
|
||||
&& cell_off2.z() == 1)?-1:0);
|
||||
off0 = _t->combine_offsets(_t->get_offset(pos->first,
|
||||
(pos->second+1)&3),
|
||||
diff_off);
|
||||
off1 = _t->combine_offsets(_t->get_offset(pos->first,
|
||||
(pos->second+2)&3),
|
||||
diff_off);
|
||||
off2 = _t->combine_offsets(_t->get_offset(pos->first,
|
||||
(pos->second+3)&3),
|
||||
diff_off);
|
||||
}
|
||||
|
||||
// return an integer that encodes the translations which have to be
|
||||
// applied to the edge *pos
|
||||
int get_drawing_offsets() {
|
||||
|
|
@ -565,7 +444,7 @@ private:
|
|||
// internally stored inside the cell telling us that this cell
|
||||
// wraps around the domain.
|
||||
if (_it == T::UNIQUE_COVER_DOMAIN)
|
||||
get_edge_offsets(off0,off1,off2);
|
||||
_t->get_offsets(*pos, off0, off1, off2);
|
||||
else {
|
||||
CGAL_assertion(_it == T::STORED_COVER_DOMAIN);
|
||||
off0 = _t->int_to_off(pos->first->offset((pos->second+1)&3));
|
||||
|
|
@ -596,7 +475,7 @@ private:
|
|||
Periodic_triangle construct_periodic_triangle() const {
|
||||
CGAL_assertion(pos->first != typename T::Cell_handle());
|
||||
Offset off0, off1, off2;
|
||||
get_edge_offsets(off0, off1, off2);
|
||||
_t->get_offsets(*pos, off0, off1, off2);
|
||||
Offset transl_off = Offset((((_off>>2)&1)==1 ? -1:0),
|
||||
(((_off>>1)&1)==1 ? -1:0),
|
||||
(( _off &1)==1 ? -1:0));
|
||||
|
|
@ -659,7 +538,7 @@ public:
|
|||
Iterator_type it = T::STORED)
|
||||
: _t(t), pos(_t->edges_begin()), _it(it), _off(0) {
|
||||
if (_it == T::UNIQUE || _it == T::UNIQUE_COVER_DOMAIN) {
|
||||
while (pos != _t->edges_end() && !is_canonical() )
|
||||
while (pos != _t->edges_end() && !_t->is_canonical(*pos) )
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
|
@ -675,7 +554,7 @@ public:
|
|||
++pos;
|
||||
break;
|
||||
case T::UNIQUE:
|
||||
do { ++pos; } while (pos != _t->edges_end() && !is_canonical());
|
||||
do { ++pos; } while (pos != _t->edges_end() && !_t->is_canonical(*pos));
|
||||
break;
|
||||
case T::STORED_COVER_DOMAIN:
|
||||
case T::UNIQUE_COVER_DOMAIN:
|
||||
|
|
@ -693,7 +572,7 @@ public:
|
|||
--pos;
|
||||
break;
|
||||
case T::UNIQUE:
|
||||
do { --pos; } while (pos != _t->edges_begin() && !is_canonical());
|
||||
do { --pos; } while (pos != _t->edges_begin() && !_t->is_canonical(*pos));
|
||||
break;
|
||||
case T::STORED_COVER_DOMAIN:
|
||||
case T::UNIQUE_COVER_DOMAIN:
|
||||
|
|
@ -751,36 +630,6 @@ private:
|
|||
mutable Periodic_segment periodic_segment; // current segment.
|
||||
|
||||
private:
|
||||
// check whether pos points onto a unique edge or not.
|
||||
// If we are computing in 1-sheeted covering this should
|
||||
// always be true.
|
||||
bool is_canonical() {
|
||||
// fetch all offsets
|
||||
Offset off0, off1;
|
||||
get_edge_offsets(off0, off1);
|
||||
|
||||
if (_t->number_of_sheets() != make_array(1,1,1)) {
|
||||
// If there is one offset with entries larger than 1 then we are
|
||||
// talking about a vertex that is too far away from the original
|
||||
// domain to belong to a canonical triangle.
|
||||
if (off0.x() > 1) return false;
|
||||
if (off0.y() > 1) return false;
|
||||
if (off0.z() > 1) return false;
|
||||
if (off1.x() > 1) return false;
|
||||
if (off1.y() > 1) return false;
|
||||
if (off1.z() > 1) return false;
|
||||
}
|
||||
|
||||
// If there is one direction of space for which all offsets are
|
||||
// non-zero then the edge is not canonical because we can
|
||||
// take the copy closer towards the origin in that direction.
|
||||
int offx = off0.x() & off1.x();
|
||||
int offy = off0.y() & off1.y();
|
||||
int offz = off0.z() & off1.z();
|
||||
|
||||
return (offx == 0 && offy == 0 && offz == 0);
|
||||
}
|
||||
|
||||
// Artificial incrementation function that takes periodic
|
||||
// copies into account.
|
||||
void increment_domain() {
|
||||
|
|
@ -789,7 +638,7 @@ private:
|
|||
if (_off == off) {
|
||||
_off = 0;
|
||||
do { ++pos; } while (_it == T::UNIQUE_COVER_DOMAIN
|
||||
&& pos != _t->edges_end() && !is_canonical());
|
||||
&& pos != _t->edges_end() && !_t->is_canonical(*pos));
|
||||
} else {
|
||||
do {
|
||||
++_off;
|
||||
|
|
@ -803,7 +652,7 @@ private:
|
|||
void decrement_domain() {
|
||||
if (_off == 0) {
|
||||
if (pos == _t->edges_begin()) return;
|
||||
do { --pos; } while (_it == T::UNIQUE_COVER_DOMAIN && !is_canonical());
|
||||
do { --pos; } while (_it == T::UNIQUE_COVER_DOMAIN && !_t->is_canonical(*pos));
|
||||
_off = get_drawing_offsets();
|
||||
} else {
|
||||
int off = get_drawing_offsets();
|
||||
|
|
@ -814,20 +663,6 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
// Get the canonicalized offsets of an edge.
|
||||
// This works in any cover that is encoded in _t->combine_offsets
|
||||
void get_edge_offsets(Offset &off0, Offset &off1) const {
|
||||
Offset cell_off0 = _t->int_to_off(pos->first->offset(pos->second));
|
||||
Offset cell_off1 = _t->int_to_off(pos->first->offset(pos->third));
|
||||
Offset diff_off((cell_off0.x()==1 && cell_off1.x()==1)?-1:0,
|
||||
(cell_off0.y()==1 && cell_off1.y()==1)?-1:0,
|
||||
(cell_off0.z()==1 && cell_off1.z()==1)?-1:0);
|
||||
off0 = _t->combine_offsets(_t->get_offset(pos->first,pos->second),
|
||||
diff_off);
|
||||
off1 = _t->combine_offsets(_t->get_offset(pos->first,pos->third),
|
||||
diff_off);
|
||||
}
|
||||
|
||||
// return an integer that encodes the translations which have to be
|
||||
// applied to the edge *pos
|
||||
int get_drawing_offsets() {
|
||||
|
|
@ -839,7 +674,7 @@ private:
|
|||
// internally stored inside the cell telling us that this cell
|
||||
// wraps around the domain.
|
||||
if (_it == T::UNIQUE_COVER_DOMAIN)
|
||||
get_edge_offsets(off0,off1);
|
||||
_t->get_offsets(*pos, off0, off1);
|
||||
else {
|
||||
CGAL_assertion(_it == T::STORED_COVER_DOMAIN);
|
||||
off0 = _t->int_to_off(pos->first->offset(pos->second));
|
||||
|
|
@ -859,7 +694,7 @@ private:
|
|||
Periodic_segment construct_periodic_segment() const {
|
||||
CGAL_assertion(pos->first != typename T::Cell_handle());
|
||||
Offset off0, off1;
|
||||
get_edge_offsets(off0, off1);
|
||||
_t->get_offsets(*pos, off0, off1);
|
||||
Offset transl_off = Offset((((_off>>2)&1)==1 ? -1:0),
|
||||
(((_off>>1)&1)==1 ? -1:0),
|
||||
(( _off &1)==1 ? -1:0));
|
||||
|
|
@ -918,7 +753,7 @@ public:
|
|||
Iterator_type it = T::STORED)
|
||||
: _t(t), pos(_t->vertices_begin()), _it(it) {
|
||||
if (_it == T::UNIQUE || _it == T::UNIQUE_COVER_DOMAIN) {
|
||||
while (pos != _t->vertices_end() && !is_canonical() )
|
||||
while (pos != _t->vertices_end() && !_t->is_canonical(pos) )
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
|
@ -936,7 +771,7 @@ public:
|
|||
break;
|
||||
case T::UNIQUE:
|
||||
case T::UNIQUE_COVER_DOMAIN:
|
||||
do { ++pos; } while (pos != _t->vertices_end() && !is_canonical());
|
||||
do { ++pos; } while (pos != _t->vertices_end() && !_t->is_canonical(pos));
|
||||
break;
|
||||
default:
|
||||
CGAL_assertion(false);
|
||||
|
|
@ -952,7 +787,7 @@ public:
|
|||
break;
|
||||
case T::UNIQUE:
|
||||
case T::UNIQUE_COVER_DOMAIN:
|
||||
do { --pos; } while (pos != _t->vertices_begin() && !is_canonical());
|
||||
do { --pos; } while (pos != _t->vertices_begin() && !_t->is_canonical(pos));
|
||||
break;
|
||||
default:
|
||||
CGAL_assertion(false);
|
||||
|
|
@ -1009,13 +844,6 @@ private:
|
|||
mutable Periodic_point periodic_point; // current point.
|
||||
|
||||
private:
|
||||
// check whether pos points onto a vertex inside the original
|
||||
// domain. If we are computing in 1-sheeted covering this should
|
||||
// always be true.
|
||||
bool is_canonical() {
|
||||
return (_t->get_offset(pos) == Offset(0,0,0));
|
||||
}
|
||||
|
||||
Periodic_point construct_periodic_point() const {
|
||||
CGAL_assertion(pos != typename T::Vertex_handle());
|
||||
Offset off = _t->get_offset(pos);
|
||||
|
|
@ -1031,9 +859,54 @@ public:
|
|||
Domain_tester() {}
|
||||
Domain_tester(const T *tr) : t(tr) {}
|
||||
|
||||
bool operator()(const typename T::Vertex_iterator & v) const {
|
||||
return (t->get_offset(v) != typename T::Offset(0,0,0));
|
||||
bool operator()(const typename T::Cell_iterator c) const
|
||||
{
|
||||
return !t->is_canonical(c);
|
||||
}
|
||||
|
||||
bool operator()(const typename T::Facet_iterator f) const
|
||||
{
|
||||
return !t->is_canonical(*f);
|
||||
}
|
||||
|
||||
bool operator()(const typename T::Edge_iterator e) const
|
||||
{
|
||||
return !t->is_canonical(*e);
|
||||
}
|
||||
|
||||
bool operator()(const typename T::Vertex_iterator v) const
|
||||
{
|
||||
return !t->is_canonical(v);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Iterates over the canonical cells in a periodic triangulation.
|
||||
// Derives from Filter_iterator in order to add a conversion to handle
|
||||
//
|
||||
// Comments:
|
||||
// When computing in 1-sheeted covering, there will be no difference
|
||||
// between a normal Cell_iterator and this iterator
|
||||
template <class T>
|
||||
class Periodic_3_triangulation_unique_cell_iterator_3
|
||||
: public Filter_iterator<typename T::Cell_iterator, Domain_tester<T> >
|
||||
{
|
||||
typedef typename T::Cell_handle Cell_handle;
|
||||
typedef typename T::Cell_iterator Cell_iterator;
|
||||
|
||||
typedef Filter_iterator<Cell_iterator, Domain_tester<T> > Base;
|
||||
typedef Periodic_3_triangulation_unique_cell_iterator_3 Self;
|
||||
|
||||
public:
|
||||
Periodic_3_triangulation_unique_cell_iterator_3() : Base() {}
|
||||
Periodic_3_triangulation_unique_cell_iterator_3(const Base &b) : Base(b) {}
|
||||
|
||||
Self & operator++() { Base::operator++(); return *this; }
|
||||
Self & operator--() { Base::operator--(); return *this; }
|
||||
Self operator++(int) { Self tmp(*this); ++(*this); return tmp; }
|
||||
Self operator--(int) { Self tmp(*this); --(*this); return tmp; }
|
||||
|
||||
operator Cell_handle() const { return Base::base(); }
|
||||
};
|
||||
|
||||
// Iterates over the vertices in a periodic triangulation that are
|
||||
|
|
@ -1065,6 +938,62 @@ public:
|
|||
operator Vertex_handle() const { return Base::base(); }
|
||||
};
|
||||
|
||||
// Iterates over the canonical edges in a periodic triangulation.
|
||||
// Derives from Filter_iterator in order to add a conversion to handle
|
||||
//
|
||||
// Comments:
|
||||
// When computing in 1-sheeted covering, there will be no difference
|
||||
// between a normal Edge_iterator and this iterator
|
||||
template <class T>
|
||||
class Periodic_3_triangulation_unique_edge_iterator_3
|
||||
: public Filter_iterator<typename T::Edge_iterator, Domain_tester<T> >
|
||||
{
|
||||
typedef typename T::Edge Edge;
|
||||
typedef typename T::Edge_iterator Edge_iterator;
|
||||
|
||||
typedef Filter_iterator<Edge_iterator, Domain_tester<T> > Base;
|
||||
typedef Periodic_3_triangulation_unique_edge_iterator_3 Self;
|
||||
|
||||
public:
|
||||
Periodic_3_triangulation_unique_edge_iterator_3() : Base() {}
|
||||
Periodic_3_triangulation_unique_edge_iterator_3(const Base &b) : Base(b) {}
|
||||
|
||||
Self & operator++() { Base::operator++(); return *this; }
|
||||
Self & operator--() { Base::operator--(); return *this; }
|
||||
Self operator++(int) { Self tmp(*this); ++(*this); return tmp; }
|
||||
Self operator--(int) { Self tmp(*this); --(*this); return tmp; }
|
||||
|
||||
operator Edge() const { return Base::base(); }
|
||||
};
|
||||
|
||||
// Iterates over the canonical facets in a periodic triangulation.
|
||||
// Derives from Filter_iterator in order to add a conversion to handle
|
||||
//
|
||||
// Comments:
|
||||
// When computing in 1-sheeted covering, there will be no difference
|
||||
// between a normal Facet_iterator and this iterator
|
||||
template <class T>
|
||||
class Periodic_3_triangulation_unique_facet_iterator_3
|
||||
: public Filter_iterator<typename T::Facet_iterator, Domain_tester<T> >
|
||||
{
|
||||
typedef typename T::Facet Facet;
|
||||
typedef typename T::Facet_iterator Facet_iterator;
|
||||
|
||||
typedef Filter_iterator<Facet_iterator, Domain_tester<T> > Base;
|
||||
typedef Periodic_3_triangulation_unique_facet_iterator_3 Self;
|
||||
public:
|
||||
|
||||
Periodic_3_triangulation_unique_facet_iterator_3() : Base() {}
|
||||
Periodic_3_triangulation_unique_facet_iterator_3(const Base &b) : Base(b) {}
|
||||
|
||||
Self & operator++() { Base::operator++(); return *this; }
|
||||
Self & operator--() { Base::operator--(); return *this; }
|
||||
Self operator++(int) { Self tmp(*this); ++(*this); return tmp; }
|
||||
Self operator--(int) { Self tmp(*this); --(*this); return tmp; }
|
||||
|
||||
operator Facet() const { return Base::base(); }
|
||||
};
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_PERIODIC_3_TRIANGULATION_ITERATORS_3_H
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ _test_unique_vertex_iterator( const Triangulation &T )
|
|||
ovit != T.unique_vertices_end(); ++ovit)
|
||||
{
|
||||
Vertex_handle vh = ovit; // Test the conversion.
|
||||
n++;
|
||||
++n;
|
||||
const Vertex & v = *ovit; // Test operator*;
|
||||
Cell_handle c = ovit->cell(); // Test operator->;
|
||||
(void) vh;
|
||||
|
|
@ -105,13 +105,139 @@ _test_unique_vertex_iterator( const Triangulation &T )
|
|||
{
|
||||
Vertex_handle vh = ovit; // Test the conversion.
|
||||
(void) vh;
|
||||
n++;
|
||||
++n;
|
||||
}
|
||||
assert( n == T.number_of_vertices() );
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
template < class Triangulation >
|
||||
typename Triangulation::size_type
|
||||
_test_unique_edge_iterator( const Triangulation &T )
|
||||
{
|
||||
typedef typename Triangulation::size_type size_type;
|
||||
typedef typename Triangulation::Edge Edge;
|
||||
typedef typename Triangulation::Cell_handle Cell_handle;
|
||||
typedef typename Triangulation::Unique_edge_iterator
|
||||
Unique_edge_iterator;
|
||||
|
||||
size_type n = 0;
|
||||
|
||||
for (Unique_edge_iterator oeit = T.unique_edges_begin();
|
||||
oeit != T.unique_edges_end(); ++oeit)
|
||||
{
|
||||
++n;
|
||||
const Edge& e = *oeit; // Test operator*;
|
||||
Cell_handle c = oeit->first; // Test operator->;
|
||||
assert(c != Cell_handle());
|
||||
(void) e;
|
||||
(void) c;
|
||||
}
|
||||
assert( n == T.number_of_edges() );
|
||||
|
||||
// Test Backward-ness of the iterators.
|
||||
n = 0;
|
||||
for (Unique_edge_iterator oeit = T.unique_edges_end();
|
||||
oeit != T.unique_edges_begin(); --oeit)
|
||||
{
|
||||
++n;
|
||||
}
|
||||
assert( n == T.number_of_edges() );
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
template < class Triangulation >
|
||||
typename Triangulation::size_type
|
||||
_test_unique_facet_iterator( const Triangulation &T )
|
||||
{
|
||||
typedef typename Triangulation::size_type size_type;
|
||||
typedef typename Triangulation::Facet Facet;
|
||||
typedef typename Triangulation::Cell_handle Cell_handle;
|
||||
typedef typename Triangulation::Unique_facet_iterator
|
||||
Unique_facet_iterator;
|
||||
|
||||
size_type n = 0;
|
||||
|
||||
for (Unique_facet_iterator ofit = T.unique_facets_begin();
|
||||
ofit != T.unique_facets_end(); ++ofit)
|
||||
{
|
||||
++n;
|
||||
const Facet& f = *ofit; // Test operator*;
|
||||
Cell_handle c = ofit->first; // Test operator->;
|
||||
assert(c != Cell_handle());
|
||||
(void) f;
|
||||
(void) c;
|
||||
}
|
||||
assert( n == T.number_of_facets() );
|
||||
|
||||
// Test Backward-ness of the iterators.
|
||||
n = 0;
|
||||
for (Unique_facet_iterator ofit = T.unique_facets_end();
|
||||
ofit != T.unique_facets_begin(); --ofit)
|
||||
{
|
||||
++n;
|
||||
}
|
||||
assert( n == T.number_of_facets() );
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
template < class Triangulation >
|
||||
typename Triangulation::size_type
|
||||
_test_unique_cell_iterator( const Triangulation &T )
|
||||
{
|
||||
typedef typename Triangulation::size_type size_type;
|
||||
typedef typename Triangulation::Cell Cell;
|
||||
typedef typename Triangulation::Vertex_handle Vertex_handle;
|
||||
typedef typename Triangulation::Cell_handle Cell_handle;
|
||||
typedef typename Triangulation::Unique_cell_iterator
|
||||
Unique_cell_iterator;
|
||||
|
||||
size_type n = 0;
|
||||
|
||||
for (Unique_cell_iterator ocit = T.unique_cells_begin();
|
||||
ocit != T.unique_cells_end(); ++ocit)
|
||||
{
|
||||
Cell_handle ch = ocit; // Test the conversion.
|
||||
n++;
|
||||
const Cell& c = *ocit; // Test operator*;
|
||||
Vertex_handle vh = ocit->vertex(0); // Test operator->;
|
||||
(void) ch;
|
||||
(void) c;
|
||||
(void) vh;
|
||||
}
|
||||
assert( n == T.number_of_cells() );
|
||||
|
||||
// Test Backward-ness of the iterators.
|
||||
n=0;
|
||||
for (Unique_cell_iterator ocit = T.unique_cells_end();
|
||||
ocit != T.unique_cells_begin(); --ocit)
|
||||
{
|
||||
Cell_handle ch = ocit; // Test the conversion.
|
||||
(void) ch;
|
||||
++n;
|
||||
}
|
||||
assert( n == T.number_of_cells() );
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
template < class Triangulation >
|
||||
typename Triangulation::size_type
|
||||
_test_triangulation_unique_iterator( const Triangulation &T )
|
||||
{
|
||||
typedef typename Triangulation::size_type size_type;
|
||||
const size_type nc = _test_unique_cell_iterator(T);
|
||||
const size_type nf = _test_unique_facet_iterator(T);
|
||||
const size_type ne = _test_unique_edge_iterator(T);
|
||||
const size_type nv = _test_unique_vertex_iterator(T);
|
||||
assert((nv-ne+nf-nc) == 0);
|
||||
return nv-ne+nf-nc;
|
||||
}
|
||||
|
||||
template < class Triangulation >
|
||||
typename Triangulation::size_type
|
||||
_test_triangulation_iterator( const Triangulation &T )
|
||||
|
|
|
|||
|
|
@ -479,10 +479,10 @@ _test_cls_periodic_3_triangulation_3(const PeriodicTriangulation &,
|
|||
_test_vertex_iterator(PT3_deg);
|
||||
_test_vertex_iterator(PT1_deg);
|
||||
|
||||
_test_unique_vertex_iterator(PT3);
|
||||
_test_unique_vertex_iterator(PT1);
|
||||
_test_unique_vertex_iterator(PT3_deg);
|
||||
_test_unique_vertex_iterator(PT1_deg);
|
||||
_test_triangulation_unique_iterator(PT3);
|
||||
_test_triangulation_unique_iterator(PT1);
|
||||
_test_triangulation_unique_iterator(PT3_deg);
|
||||
_test_triangulation_unique_iterator(PT1_deg);
|
||||
|
||||
_test_triangulation_iterator(PT3);
|
||||
_test_triangulation_iterator(PT1);
|
||||
|
|
|
|||
Loading…
Reference in New Issue