// Copyright (c) 1999 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org); you may redistribute it under // the terms of the Q Public License version 1.0. // See the file LICENSE.QPL distributed with CGAL. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // // Author(s) : Monique Teillaud #ifndef CGAL_TRIANGULATION_DS_CIRCULATORS_3_H #define CGAL_TRIANGULATION_DS_CIRCULATORS_3_H #include #include #include CGAL_BEGIN_NAMESPACE template < class Tds_ > class Triangulation_ds_cell_circulator_3 : public Bidirectional_circulator_base { // circulates on cells around a given edge typedef Tds_ Tds; typedef typename Tds::Cell Cell; typedef typename Tds::Edge Edge; typedef typename Tds::Vertex_handle Vertex_handle; typedef typename Tds::Cell_handle Cell_handle; typedef Triangulation_ds_cell_circulator_3 Cell_circulator; public: Triangulation_ds_cell_circulator_3() : _s(), _t(), pos() {} Triangulation_ds_cell_circulator_3(Cell_handle c, int s, int t) : _s(c->vertex(s)), _t(c->vertex(t)), pos(c) { CGAL_triangulation_precondition( c != Cell_handle() && s >= 0 && s < 4 && t >= 0 && t < 4 ); } Triangulation_ds_cell_circulator_3(const Edge & e) : _s(e.first->vertex(e.second)), _t(e.first->vertex(e.third)), pos(e.first) { CGAL_triangulation_precondition( e.first != Cell_handle() && e.second >=0 && e.second < 4 && e.third >=0 && e.third < 4); } Triangulation_ds_cell_circulator_3(Cell_handle c, int s, int t, Cell_handle start) : _s(c->vertex(s)), _t(c->vertex(t)), pos(start) { CGAL_triangulation_precondition( c != Cell_handle() && s >= 0 && s < 4 && t >= 0 && t < 4 && start->has_vertex( _s ) && start->has_vertex( _t ) ); } Triangulation_ds_cell_circulator_3(const Edge & e, Cell_handle start) : _s(e.first->vertex(e.second)), _t(e.first->vertex(e.third)), pos(start) { CGAL_triangulation_precondition( e.first != Cell_handle() && e.second >=0 && e.second < 4 && e.third >=0 && e.third < 4 && start->has_vertex( _s ) && start->has_vertex( _t ) ); } Cell_circulator & operator++() { CGAL_triangulation_precondition( pos != Cell_handle() ); //then dimension() cannot be < 3 pos = pos->neighbor(next_around_edge(pos->index(_s), pos->index(_t))); return *this; } Cell_circulator operator++(int) { Cell_circulator tmp(*this); ++(*this); return tmp; } Cell_circulator & operator--() { CGAL_triangulation_precondition( pos != Cell_handle() ); pos = pos->neighbor(next_around_edge(pos->index(_t), pos->index(_s))); return *this; } Cell_circulator operator--(int) { Cell_circulator tmp(*this); --(*this); return tmp; } Cell& operator*() const { return *pos; } Cell* operator->() const { return &*pos; } bool operator==(const Cell_circulator & ccir) const { return pos == ccir.pos && _s == ccir._s && _t == ccir._t; } bool operator!=(const Cell_circulator & ccir) const { return ! (*this == ccir); } bool operator==(Cell_handle ch) const { return ch == pos; } bool operator!=(Cell_handle ch) const { return ch != pos; } bool operator==(Nullptr_t CGAL_triangulation_assertion_code(n)) const { CGAL_triangulation_assertion( n == NULL); return pos == Cell_handle(); } bool operator!=(Nullptr_t n) const { return ! (*this == n); } // For TDS's private use only. Cell_handle base() const { return pos; } operator Cell_handle() const { return pos; } private: Vertex_handle _s; // source vertex of the edge Vertex_handle _t; // target vertex of the edge Cell_handle pos; // current cell static int next_around_edge(const int i, const int j) { return Triangulation_utils_3::next_around_edge(i,j); } }; template < class Tds_ > inline bool operator==(typename Tds_::Cell_handle ch, Triangulation_ds_cell_circulator_3 cc) { return (cc==ch); } template < class Tds_ > inline bool operator!=(typename Tds_::Cell_handle ch, Triangulation_ds_cell_circulator_3 cc) { return !(cc==ch); } template < class Tds_ > class Triangulation_ds_facet_circulator_3 : public Bidirectional_circulator_base { // circulates on facets around a given edge typedef Tds_ Tds; typedef typename Tds::Cell Cell; typedef typename Tds::Cell_handle Cell_handle; typedef typename Tds::Facet Facet; typedef typename Tds::Edge Edge; typedef typename Tds::Vertex_handle Vertex_handle; typedef Triangulation_ds_facet_circulator_3 Facet_circulator; public: Triangulation_ds_facet_circulator_3() : _s(), _t(), pos() {} Triangulation_ds_facet_circulator_3(Cell_handle c, int s, int t) : _s(c->vertex(s)), _t(c->vertex(t)), pos(c) { CGAL_triangulation_precondition( c != Cell_handle() && s >= 0 && s < 4 && t >= 0 && t < 4 ); } Triangulation_ds_facet_circulator_3(const Edge & e) : _s(e.first->vertex(e.second)), _t(e.first->vertex(e.third)), pos(e.first) { CGAL_triangulation_precondition( e.first != Cell_handle() && e.second >= 0 && e.second < 4 && e.third >= 0 && e.third < 4); } Triangulation_ds_facet_circulator_3(Cell_handle c, int s, int t, Cell_handle start, int f) : _s(c->vertex(s)), _t(c->vertex(t)) { CGAL_triangulation_precondition( c != Cell_handle() && s >= 0 && s < 4 && t >= 0 && t < 4 && f >= 0 && f < 4 && start->has_vertex( _s ) && start->has_vertex( _t ) ); int i = start->index( _s ); int j = start->index( _t ); CGAL_triangulation_precondition( f!=i && f!=j ); if ( f == next_around_edge(i,j) ) pos = start; else pos = start->neighbor(f); // other cell with same facet } Triangulation_ds_facet_circulator_3(Cell_handle c, int s, int t, const Facet & start) : _s(c->vertex(s)), _t(c->vertex(t)) { CGAL_triangulation_precondition( c != Cell_handle() && s >= 0 && s < 4 && t >= 0 && t < 4 && start.first->has_vertex( _s ) && start.first->has_vertex( _t ) ); int i = start.first->index( _s ); int j = start.first->index( _t ); CGAL_triangulation_precondition( start.second !=i && start.second !=j ); if ( start.second == next_around_edge(i,j) ) pos = start.first; else pos = start.first->neighbor(start.second); // other cell with same facet } Triangulation_ds_facet_circulator_3(const Edge & e, Cell_handle start, int f) : _s(e.first->vertex(e.second)), _t(e.first->vertex(e.third)) { CGAL_triangulation_precondition( e.first != Cell_handle() && e.second >= 0 && e.second < 4 && e.third >= 0 && e.third < 4 && f >= 0 && f < 4 && start->has_vertex( _s ) && start->has_vertex( _t ) ); int i = start->index( _s ); int j = start->index( _t ); CGAL_triangulation_precondition( f!=i && f!=j ); if ( f == next_around_edge(i,j) ) pos = start; else pos = start->neighbor(f); // other cell with same facet } Triangulation_ds_facet_circulator_3(const Edge & e, const Facet & start) : _s(e.first->vertex(e.second)), _t(e.first->vertex(e.third)) { CGAL_triangulation_precondition( e.first != Cell_handle() && e.second >= 0 && e.second < 4 && e.third >= 0 && e.third < 4 && start.first->has_vertex( _s ) && start.first->has_vertex( _t ) ); int i = start.first->index( _s ); int j = start.first->index( _t ); if ( start.second == next_around_edge(i,j) ) pos = start.first; else pos = start.first->neighbor(start.second); } Facet_circulator & operator++() { CGAL_triangulation_precondition( pos != Cell_handle() ); //then dimension() cannot be < 3 pos = pos->neighbor( next_around_edge( pos->index(_s), pos->index(_t) ) ); return *this; } Facet_circulator operator++(int) { Facet_circulator tmp(*this); ++(*this); return tmp; } Facet_circulator & operator--() { CGAL_triangulation_precondition( pos != Cell_handle() ); pos = pos->neighbor( next_around_edge( pos->index(_t), pos->index(_s) ) ); return *this; } Facet_circulator operator--(int) { Facet_circulator tmp(*this); --(*this); return tmp; } Facet operator*() const { return Facet(pos, next_around_edge( pos->index(_s), pos->index(_t) ) ); } struct Proxy_Facet { Proxy_Facet(const Facet & ff) : f(ff) {} Facet f; const Facet* operator->() const { return &f; } }; Proxy_Facet operator->() const { return Proxy_Facet(* *this); } bool operator==(const Facet_circulator & ccir) const { return pos == ccir.pos && _s == ccir._s && _t == ccir._t; } bool operator!=(const Facet_circulator & ccir) const { return ! (*this == ccir); } bool operator==(Nullptr_t CGAL_triangulation_assertion_code(c)) const { CGAL_triangulation_assertion(c == NULL); return pos == Cell_handle(); } bool operator!=(Nullptr_t c) const { return ! (*this == c); } private: Vertex_handle _s; // source vertex of the edge Vertex_handle _t; // target vertex of the edge Cell_handle pos; // current cell // the current facet is the facet of pos numbered // next_around_edge( pos->index(_c->vertex(_s)), // pos->index(_c->vertex(_t)) ) static int next_around_edge(const int i, const int j) { return Triangulation_utils_3::next_around_edge(i,j); } }; template < class Tds_ > class Triangulation_ds_face_circulator_3 : public Bidirectional_circulator_base { // circulates on faces (Cell) around a given vertex, // valid in dimension 2 only. typedef Tds_ Tds; typedef typename Tds::Cell Cell; typedef typename Tds::Vertex Vertex; typedef typename Tds::Vertex_handle Vertex_handle; typedef typename Tds::Cell_handle Cell_handle; typedef Triangulation_ds_face_circulator_3 Face_circulator; public: Triangulation_ds_face_circulator_3() : _s(), pos() {} Triangulation_ds_face_circulator_3(Vertex_handle v, Cell_handle c) : _s(v), pos(c) {} Face_circulator & operator++() { CGAL_triangulation_precondition( pos != Cell_handle() ); //then dimension() cannot be < 3 pos = pos->neighbor(ccw(pos->index(_s))); return *this; } Face_circulator operator++(int) { Face_circulator tmp(*this); ++(*this); return tmp; } Face_circulator & operator--() { CGAL_triangulation_precondition( pos != Cell_handle() ); pos = pos->neighbor(cw(pos->index(_s))); return *this; } Face_circulator operator--(int) { Face_circulator tmp(*this); --(*this); return tmp; } Cell& operator*() const { return *pos; } Cell* operator->() const { return &*pos; } bool operator==(const Face_circulator & ccir) const { return pos == ccir.pos && _s == ccir._s; } bool operator!=(const Face_circulator & ccir) const { return ! (*this == ccir); } bool operator==(Nullptr_t CGAL_triangulation_assertion_code(c)) const { CGAL_triangulation_assertion(c == NULL); return pos == Cell_handle(); } bool operator!=(Nullptr_t c) const { return ! (*this == c); } // For TDS's private use only. Cell_handle base() const { return pos; } operator Cell_handle() const { return pos; } private: Vertex_handle _s; // source vertex Cell_handle pos; // current cell static int cw(int i) { return Triangulation_utils_3::cw(i); } static int ccw(int i) { return Triangulation_utils_3::ccw(i); } }; CGAL_END_NAMESPACE #endif // CGAL_TRIANGULATION_DS_CIRCULATORS_3_H