diff --git a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_Delaunay_triangulation_2.h b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_Delaunay_triangulation_2.h index bd100faf0157..279f21dec869 100644 --- a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_Delaunay_triangulation_2.h +++ b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_Delaunay_triangulation_2.h @@ -198,7 +198,7 @@ class Periodic_2_Delaunay_triangulation_2 : public Periodic_2_triangulation_2(c) Any cell has its vertices ordered according to positive +(c) Any face has its vertices ordered according to positive orientation. See \cgalFigureRef{P2Triangulation2figorient}. \section P2T2_Delaunay Delaunay Triangulation @@ -264,7 +264,7 @@ to support periodicity: the vertex and face must be models of `Periodic_2TriangulationVertexBase_2` and `Periodic_2TriangulationFaceBase_2`. A model of such concept is `CGAL::Triangulation_data_structure_2`. It is parameterized by a vertex base class and a face base class, which gives the -possibility to customize the vertices and cells used by the triangulation data +possibility to customize the vertices and faces used by the triangulation data structure, and hence by the geometric triangulation using it. Basic models of the vertex and face concepts are provided: `CGAL::Periodic_2_triangulation_vertex_base_2` and `CGAL::Periodic_2_triangulation_face_base_2`. @@ -272,7 +272,7 @@ and `CGAL::Periodic_2_triangulation_face_base_2`. A default value for the triangulation data structure parameter is provided in all the triangulation classes, so it does not need to be specified by the user unless he wants to use a different triangulation data -structure or a different vertex or cell base class. +structure or a different vertex or face base class. \subsection P2T2FlexDesign Flexibility of the Design diff --git a/Periodic_2_triangulation_2/examples/Periodic_2_triangulation_2/p2t2_find_conflicts.cpp b/Periodic_2_triangulation_2/examples/Periodic_2_triangulation_2/p2t2_find_conflicts.cpp index 0491e319a8c8..b3bc862f3088 100644 --- a/Periodic_2_triangulation_2/examples/Periodic_2_triangulation_2/p2t2_find_conflicts.cpp +++ b/Periodic_2_triangulation_2/examples/Periodic_2_triangulation_2/p2t2_find_conflicts.cpp @@ -27,24 +27,21 @@ int main() // Gets the conflict region of 100 random points // in the Delaunay tetrahedralization for (int i = 0; i != 100; ++i) - { - Point p = (*rnd++); - - // Locate the point - Delaunay::Locate_type lt; - int li; - Face_handle f = T.locate(p, lt, li); - if (lt == Delaunay::VERTEX) - continue; // Point already exists - - // Get the cells that conflict with p in a vector V, - // and a facet on the boundary of this hole in f. - std::vector V; - - T.get_conflicts(p, - std::back_inserter(V), // Conflict cells in V - f); - } + { + Point p = (*rnd++); + + // Locate the point + Delaunay::Locate_type lt; + int li; + Face_handle f = T.locate(p, lt, li); + if (lt == Delaunay::VERTEX) + continue; // Point already exists + + // Get the faces that conflict with p in a vector V. + std::vector V; + + T.get_conflicts(p, std::back_inserter(V), f); + } std::cout << "Final triangulation has " << T.number_of_vertices() << " vertices." << std::endl; diff --git a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2.h b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2.h index a4ca4e36a30c..2d2e3878f82a 100644 --- a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2.h +++ b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2.h @@ -119,12 +119,21 @@ class Periodic_2_triangulation_2 /// Unique_vertex_iterator iterates over exactly one representative. typedef Periodic_2_triangulation_unique_vertex_iterator_2 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 + 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 + Unique_face_iterator; /// \name For compatibility with the Triangulation_2 class // \{ typedef Face_iterator Finite_faces_iterator; typedef Edge_iterator Finite_edges_iterator; typedef Vertex_iterator Finite_vertices_iterator; + typedef Vertex_iterator All_vertices_iterator; typedef Face_iterator All_faces_iterator; // \} @@ -381,10 +390,11 @@ class Periodic_2_triangulation_2 /// Checks whether the triangulation is a valid simplicial complex in the one cover. bool is_triangulation_in_1_sheet() const; - /// Convert a 9 sheeted cover (used for sparse triangulations) to a single sheeted cover. + /// Converts a 9 sheeted cover (used for sparse triangulations) to a single sheeted cover. /// \pre !is_1_cover(); void convert_to_1_sheeted_covering(); - /// Convert a single sheeted cover (used for dense triangulations) to a 9 sheeted cover. + + /// Converts a single sheeted cover (used for dense triangulations) to a 9 sheeted cover. /// \pre is_1_cover(); void convert_to_9_sheeted_covering(); // \} @@ -676,6 +686,32 @@ class Periodic_2_triangulation_2 Periodic_2_triangulation_2_internal::Domain_tester(this)); } + Unique_edge_iterator unique_edges_begin() const + { + return CGAL::filter_iterator(edges_end(), + Periodic_2_triangulation_2_internal::Domain_tester(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(this)); + } + + Unique_face_iterator unique_faces_begin() const + { + return CGAL::filter_iterator(faces_end(), + Periodic_2_triangulation_2_internal::Domain_tester(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(this)); + } + // \} /// \name Geometric iterators //\{ @@ -972,6 +1008,32 @@ class Periodic_2_triangulation_2 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 +1048,12 @@ class Periodic_2_triangulation_2 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 +1068,6 @@ class Periodic_2_triangulation_2 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& periodic_copies(const Vertex_handle v) const { CGAL_precondition(number_of_sheets() != make_array(1, 1) ); @@ -1024,6 +1076,77 @@ class Periodic_2_triangulation_2 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 Stream& draw_triangulation(Stream& os) const { diff --git a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_iterators_2.h b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_iterators_2.h index afa1a55fce52..c3e7fb1164a4 100644 --- a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_iterators_2.h +++ b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_iterators_2.h @@ -14,13 +14,11 @@ #include - #include #include #include -namespace CGAL -{ +namespace CGAL { template < class T > class Periodic_2_triangulation_triangle_iterator_2 @@ -66,7 +64,7 @@ class Periodic_2_triangulation_triangle_iterator_2 { 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 +86,7 @@ class Periodic_2_triangulation_triangle_iterator_2 { ++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 +110,7 @@ class Periodic_2_triangulation_triangle_iterator_2 { --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 +170,6 @@ class Periodic_2_triangulation_triangle_iterator_2 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 +184,7 @@ class Periodic_2_triangulation_triangle_iterator_2 ++pos; } while (_it == T::UNIQUE_COVER_DOMAIN - && pos != _t->faces_end() && !is_canonical()); + && pos != _t->faces_end() && !_t->is_canonical(pos)); } else { @@ -241,7 +208,7 @@ class Periodic_2_triangulation_triangle_iterator_2 { --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 +223,6 @@ class Periodic_2_triangulation_triangle_iterator_2 } } - // 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() @@ -284,10 +232,10 @@ class Periodic_2_triangulation_triangle_iterator_2 // intersect the boundary of the periodic domain. In UNIQUE mode // this means that the offset with respect to drawing should // differ in some entries. Otherwise we consider the offsets - // internally stored inside the cell telling us that this cell + // internally stored inside the face telling us that this face // 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 +267,7 @@ class Periodic_2_triangulation_triangle_iterator_2 { 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 +333,7 @@ class Periodic_2_triangulation_segment_iterator_2 { 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 +355,7 @@ class Periodic_2_triangulation_segment_iterator_2 { ++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 +379,7 @@ class Periodic_2_triangulation_segment_iterator_2 { --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 +438,6 @@ class Periodic_2_triangulation_segment_iterator_2 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 +452,7 @@ class Periodic_2_triangulation_segment_iterator_2 ++pos; } while (_it == T::UNIQUE_COVER_DOMAIN - && pos != _t->edges_end() && !is_canonical()); + && pos != _t->edges_end() && !_t->is_canonical(*pos)); } else { @@ -557,7 +476,7 @@ class Periodic_2_triangulation_segment_iterator_2 { --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 +491,6 @@ class Periodic_2_triangulation_segment_iterator_2 } } - // 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() @@ -595,10 +500,10 @@ class Periodic_2_triangulation_segment_iterator_2 // intersect the boundary of the periodic domain. In UNIQUE mode // this means that the offset with respect to drawing should // differ in some entries. Otherwise we consider the offsets - // internally stored inside the cell telling us that this cell + // internally stored inside the face telling us that this face // 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 +523,7 @@ class Periodic_2_triangulation_segment_iterator_2 { 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 +586,7 @@ class Periodic_2_triangulation_point_iterator_2 { 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 +610,7 @@ class Periodic_2_triangulation_point_iterator_2 { ++pos; } - while (pos != _t->vertices_end() && !is_canonical()); + while (pos != _t->vertices_end() && !_t->is_canonical(pos)); break; default: CGAL_assertion(false); @@ -727,7 +632,7 @@ class Periodic_2_triangulation_point_iterator_2 { --pos; } - while (pos != _t->vertices_begin() && !is_canonical()); + while (pos != _t->vertices_begin() && !_t->is_canonical(pos)); break; default: CGAL_assertion(false); @@ -785,14 +690,6 @@ class Periodic_2_triangulation_point_iterator_2 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 +698,91 @@ class Periodic_2_triangulation_point_iterator_2 } }; -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 Domain_tester { - const T *t; + 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 + { + 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))); - public: - Domain_tester() {} - Domain_tester(const T *tr) : t(tr) {} + 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); - bool operator()(const typename T::Vertex_iterator & v) const + if (t->number_of_sheets() != make_array(1, 1)) { - return (t->get_offset(v) != typename T::Offset(0, 0)); + // 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. @@ -830,7 +795,6 @@ template class Periodic_2_triangulation_unique_vertex_iterator_2 : public Filter_iterator > { - typedef typename T::Vertex_handle Vertex_handle; typedef typename T::Vertex_iterator Vertex_iterator; @@ -838,8 +802,8 @@ class Periodic_2_triangulation_unique_vertex_iterator_2 typedef Filter_iterator Base; typedef Periodic_2_triangulation_unique_vertex_iterator_2 Self; -public: +public: Periodic_2_triangulation_unique_vertex_iterator_2() : Base() {} Periodic_2_triangulation_unique_vertex_iterator_2(const Base &b) : Base(b) {} @@ -872,6 +836,108 @@ class Periodic_2_triangulation_unique_vertex_iterator_2 } }; -} //namespace CGAL +// 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 Periodic_2_triangulation_unique_edge_iterator_2 + : public Filter_iterator > +{ + typedef typename T::Edge Edge; + typedef typename T::Edge_iterator Edge_iterator; + + typedef typename Periodic_2_triangulation_2_internal::Domain_tester Tester; + + typedef Filter_iterator 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 Periodic_2_triangulation_unique_face_iterator_2 + : public Filter_iterator > +{ + typedef typename T::Face_handle Face_handle; + typedef typename T::Face_iterator Face_iterator; + + typedef typename Periodic_2_triangulation_2_internal::Domain_tester Tester; + + typedef Filter_iterator 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 diff --git a/Periodic_2_triangulation_2/test/Periodic_2_triangulation_2/include/interface_test.h b/Periodic_2_triangulation_2/test/Periodic_2_triangulation_2/include/interface_test.h index efbd3cf0be47..c69f2858ef99 100644 --- a/Periodic_2_triangulation_2/test/Periodic_2_triangulation_2/include/interface_test.h +++ b/Periodic_2_triangulation_2/test/Periodic_2_triangulation_2/include/interface_test.h @@ -208,6 +208,8 @@ void test_iterators() Vertex_handle vh2 = t.insert(Point(0.7, 0.7)); CGAL_USE(vh2); + std::cout << "Cover = " << t.number_of_sheets()[0] << " " << t.number_of_sheets()[1] << std::endl; + // vertices size_t size = 0; for (typename T::Vertex_iterator vit = t_const.vertices_begin(); @@ -217,19 +219,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) + 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_vertices()); + assert(size == t_const.number_of_stored_vertices()); size = 0; - for (typename T::Vertex_iterator vit = t_const.all_vertices_begin(); - vit != t_const.all_vertices_end(); ++vit) + 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_stored_vertices()); + assert(size == t_const.number_of_vertices()); // edges size = 0; @@ -246,6 +248,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 +271,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(); diff --git a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3.h b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3.h index c6399eeaa0fc..c1001de10c5c 100644 --- a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3.h +++ b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3.h @@ -169,6 +169,13 @@ class Periodic_3_triangulation_3 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 + Unique_cell_iterator; + typedef Periodic_3_triangulation_unique_facet_iterator_3 + Unique_facet_iterator; + typedef Periodic_3_triangulation_unique_edge_iterator_3 + Unique_edge_iterator; typedef Periodic_3_triangulation_unique_vertex_iterator_3 Unique_vertex_iterator; @@ -397,26 +404,14 @@ class Periodic_3_triangulation_3 } const Covering_sheets& number_of_sheets() const { return _cover; } - const std::pair 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& 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 @@ class Periodic_3_triangulation_3 _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 @@ class Periodic_3_triangulation_3 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 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& 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 @@ class Periodic_3_triangulation_3 // 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 @@ class Periodic_3_triangulation_3 std::vector insert_generic_dummy_points(); protected: + template + Offset get_location_offset(const Conflict_tester& tester, + Cell_handle c) const; + + template + Offset get_location_offset(const Conflict_tester& tester, + Cell_handle c, bool& found) const; + // this is needed for compatibility reasons template @@ -1474,6 +1703,8 @@ class Periodic_3_triangulation_3 return _tds.facets_end(); } + // Finite iterators (= all iterators, for periodic triangulations) + Cell_iterator finite_cells_begin() const { return _tds.cells_begin(); } @@ -1502,6 +1733,8 @@ class Periodic_3_triangulation_3 return _tds.facets_end(); } + // All iterators (= finite, for periodic triangulations) + All_cells_iterator all_cells_begin() const { return _tds.cells_begin(); } @@ -1530,6 +1763,16 @@ class Periodic_3_triangulation_3 return _tds.facets_end(); } + // Unique iterators + + Unique_cell_iterator unique_cells_begin() const { + return CGAL::filter_iterator(cells_end(), Domain_tester(this), + cells_begin()); + } + Unique_cell_iterator unique_cells_end() const { + return CGAL::filter_iterator(cells_end(), Domain_tester(this)); + } + Unique_vertex_iterator unique_vertices_begin() const { return CGAL::filter_iterator(vertices_end(), Domain_tester(this), vertices_begin()); @@ -1538,6 +1781,22 @@ class Periodic_3_triangulation_3 return CGAL::filter_iterator(vertices_end(), Domain_tester(this)); } + Unique_edge_iterator unique_edges_begin() const { + return CGAL::filter_iterator(edges_end(), Domain_tester(this), + edges_begin()); + } + Unique_edge_iterator unique_edges_end() const { + return CGAL::filter_iterator(edges_end(), Domain_tester(this)); + } + + Unique_facet_iterator unique_facets_begin() const { + return CGAL::filter_iterator(facets_end(), Domain_tester(this), + facets_begin()); + } + Unique_facet_iterator unique_facets_end() const { + return CGAL::filter_iterator(facets_end(), Domain_tester(this)); + } + // Geometric iterators Periodic_tetrahedron_iterator periodic_tetrahedra_begin( Iterator_type it = STORED) const { @@ -1576,6 +1835,7 @@ class Periodic_3_triangulation_3 } // Circulators + Cell_circulator incident_cells(const Edge& e) const { return _tds.incident_cells(e); } @@ -1695,75 +1955,6 @@ class Periodic_3_triangulation_3 } }; -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 - Offset get_location_offset(const Conflict_tester& tester, - Cell_handle c) const; - - template - 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 +1979,6 @@ class Periodic_3_triangulation_3 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 bool canonical_dual_segment(Cell_handle c, int i, Periodic_segment_3& ps, @@ -3310,7 +3456,7 @@ periodic_remove(Vertex_handle v, nr_vec.push_back(boost::make_tuple(o_ch,o_i,new_ch)); nr_vec.push_back(boost::make_tuple(new_ch,i_i,o_ch)); - // for the other faces check, if they can also be glued + // for the other facets check, if they can also be glued for(unsigned int i = 0; i < 4; i++) { if(i != i_i) { Facet f = std::pair(new_ch,i); @@ -3322,7 +3468,7 @@ periodic_remove(Vertex_handle v, std::swap(vt.second,vt.third); outer_map[vt]= f; } else { - // glue the faces + // glue the facets typename Vertex_triple_Facet_map::value_type o_vt_f_pair2 = *oit2; Cell_handle o_ch2 = o_vt_f_pair2.second.first; int o_i2 = o_vt_f_pair2.second.second; diff --git a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_triangulation_iterators_3.h b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_triangulation_iterators_3.h index 947b8b553e52..67cacfe10841 100644 --- a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_triangulation_iterators_3.h +++ b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_triangulation_iterators_3.h @@ -63,7 +63,7 @@ class Periodic_3_triangulation_tetrahedron_iterator_3 { 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 @@ class Periodic_3_triangulation_tetrahedron_iterator_3 { ++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 @@ class Periodic_3_triangulation_tetrahedron_iterator_3 { --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 @@ class Periodic_3_triangulation_tetrahedron_iterator_3 { 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 @@ class Periodic_3_triangulation_tetrahedron_iterator_3 { 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 @@ class Periodic_3_triangulation_tetrahedron_iterator_3 { 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 @@ class Periodic_3_triangulation_tetrahedron_iterator_3 { } } - // 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 @@ class Periodic_3_triangulation_tetrahedron_iterator_3 { // 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 @@ class Periodic_3_triangulation_tetrahedron_iterator_3 { 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 @@ class Periodic_3_triangulation_triangle_iterator_3 { 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 @@ class Periodic_3_triangulation_triangle_iterator_3 { ++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 @@ class Periodic_3_triangulation_triangle_iterator_3 { --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 @@ class Periodic_3_triangulation_triangle_iterator_3 { 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 @@ class Periodic_3_triangulation_triangle_iterator_3 { 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 @@ class Periodic_3_triangulation_triangle_iterator_3 { 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 @@ class Periodic_3_triangulation_triangle_iterator_3 { } } - // 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 @@ class Periodic_3_triangulation_triangle_iterator_3 { // 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 @@ class Periodic_3_triangulation_triangle_iterator_3 { 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 @@ class Periodic_3_triangulation_segment_iterator_3 { 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 @@ class Periodic_3_triangulation_segment_iterator_3 { ++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 @@ class Periodic_3_triangulation_segment_iterator_3 { --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 @@ class Periodic_3_triangulation_segment_iterator_3 { 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 @@ class Periodic_3_triangulation_segment_iterator_3 { 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 @@ class Periodic_3_triangulation_segment_iterator_3 { 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 @@ class Periodic_3_triangulation_segment_iterator_3 { } } - // 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 @@ class Periodic_3_triangulation_segment_iterator_3 { // 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 @@ class Periodic_3_triangulation_segment_iterator_3 { 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 @@ class Periodic_3_triangulation_point_iterator_3 { 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 @@ class Periodic_3_triangulation_point_iterator_3 { 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 @@ class Periodic_3_triangulation_point_iterator_3 { 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 @@ class Periodic_3_triangulation_point_iterator_3 { 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 @@ class Domain_tester { 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 Periodic_3_triangulation_unique_cell_iterator_3 + : public Filter_iterator > +{ + typedef typename T::Cell_handle Cell_handle; + typedef typename T::Cell_iterator Cell_iterator; + + typedef Filter_iterator > 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 @@ -1045,15 +918,15 @@ class Domain_tester { // between a normal Vertex_iterator and this iterator template class Periodic_3_triangulation_unique_vertex_iterator_3 - : public Filter_iterator > { - + : public Filter_iterator > +{ typedef typename T::Vertex_handle Vertex_handle; typedef typename T::Vertex_iterator Vertex_iterator; typedef Filter_iterator > Base; typedef Periodic_3_triangulation_unique_vertex_iterator_3 Self; -public: +public: Periodic_3_triangulation_unique_vertex_iterator_3() : Base() {} Periodic_3_triangulation_unique_vertex_iterator_3(const Base &b) : Base(b) {} @@ -1065,6 +938,62 @@ class Periodic_3_triangulation_unique_vertex_iterator_3 operator Vertex_handle() const { return Base::base(); } }; -} //namespace CGAL +// 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 Periodic_3_triangulation_unique_edge_iterator_3 + : public Filter_iterator > +{ + typedef typename T::Edge Edge; + typedef typename T::Edge_iterator Edge_iterator; + + typedef Filter_iterator > 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 Periodic_3_triangulation_unique_facet_iterator_3 + : public Filter_iterator > +{ + typedef typename T::Facet Facet; + typedef typename T::Facet_iterator Facet_iterator; + + typedef Filter_iterator > 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 diff --git a/Periodic_3_triangulation_3/test/Periodic_3_triangulation_3/include/CGAL/_test_cls_periodic_3_iterator.h b/Periodic_3_triangulation_3/test/Periodic_3_triangulation_3/include/CGAL/_test_cls_periodic_3_iterator.h index a77afb5fbc07..49bdfff51cd5 100644 --- a/Periodic_3_triangulation_3/test/Periodic_3_triangulation_3/include/CGAL/_test_cls_periodic_3_iterator.h +++ b/Periodic_3_triangulation_3/test/Periodic_3_triangulation_3/include/CGAL/_test_cls_periodic_3_iterator.h @@ -86,32 +86,158 @@ _test_unique_vertex_iterator( const Triangulation &T ) size_type n = 0; for (Unique_vertex_iterator ovit = T.unique_vertices_begin(); - ovit != T.unique_vertices_end(); ++ovit) - { - Vertex_handle vh = ovit; // Test the conversion. - n++; - const Vertex & v = *ovit; // Test operator*; - Cell_handle c = ovit->cell(); // Test operator->; - (void) vh; - (void) v; - (void) c; - } + ovit != T.unique_vertices_end(); ++ovit) + { + Vertex_handle vh = ovit; // Test the conversion. + ++n; + const Vertex & v = *ovit; // Test operator*; + Cell_handle c = ovit->cell(); // Test operator->; + (void) vh; + (void) v; + (void) c; + } assert( n == T.number_of_vertices() ); // Test Backward-ness of the iterators. - n=0; + n = 0; for (Unique_vertex_iterator ovit = T.unique_vertices_end(); - ovit != T.unique_vertices_begin(); --ovit) - { - Vertex_handle vh = ovit; // Test the conversion. - (void) vh; - n++; - } + ovit != T.unique_vertices_begin(); --ovit) + { + Vertex_handle vh = ovit; // Test the conversion. + (void) vh; + ++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 ) diff --git a/Periodic_3_triangulation_3/test/Periodic_3_triangulation_3/include/CGAL/_test_cls_periodic_3_triangulation_3.h b/Periodic_3_triangulation_3/test/Periodic_3_triangulation_3/include/CGAL/_test_cls_periodic_3_triangulation_3.h index 0cb56c38824f..b5d08b90ec6a 100644 --- a/Periodic_3_triangulation_3/test/Periodic_3_triangulation_3/include/CGAL/_test_cls_periodic_3_triangulation_3.h +++ b/Periodic_3_triangulation_3/test/Periodic_3_triangulation_3/include/CGAL/_test_cls_periodic_3_triangulation_3.h @@ -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);