/*===========================================================================*\ * * * OpenMesh * * Copyright (C) 2001-2003 by Computer Graphics Group, RWTH Aachen * * www.openmesh.org * * * *---------------------------------------------------------------------------* * * * License * * * * This library is free software; you can redistribute it and/or modify it * * under the terms of the GNU Lesser General Public License as published * * by the Free Software Foundation, version 2.1. * * * * This library is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the Free Software * * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * \*===========================================================================*/ #ifndef OPENMESH_ITERATORS_HH #define OPENMESH_ITERATORS_HH //============================================================================= // // Iterators for PolyMesh/TriMesh // //============================================================================= //== INCLUDES ================================================================= #include #include #include //== NAMESPACES =============================================================== namespace OpenMesh { namespace Iterators { //== FORWARD DECLARATIONS ===================================================== template class VertexIterT; template class ConstVertexIterT; template class HalfedgeIterT; template class ConstHalfedgeIterT; template class EdgeIterT; template class ConstEdgeIterT; template class FaceIterT; template class ConstFaceIterT; //== CLASS DEFINITION ========================================================= /** \class VertexIterT IteratorsT.hh Linear iterator. */ template class VertexIterT { public: //--- Typedefs --- typedef typename Mesh::Vertex value_type; typedef typename Mesh::VertexHandle value_handle; #if 0 typedef const value_type& reference; typedef const value_type* pointer; typedef const Mesh* mesh_ptr; typedef const Mesh& mesh_ref; #else typedef value_type& reference; typedef value_type* pointer; typedef Mesh* mesh_ptr; typedef Mesh& mesh_ref; #endif /// Default constructor. VertexIterT() : mesh_(0), skip_bits_(0) {} /// Construct with mesh and a target handle. VertexIterT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) { if (_skip) enable_skipping(); } /// Copy constructor VertexIterT(const VertexIterT& _rhs) : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) {} /// Assignment operator VertexIterT& operator=(const VertexIterT& _rhs) { mesh_ = _rhs.mesh_; hnd_ = _rhs.hnd_; skip_bits_ = _rhs.skip_bits_; return *this; } #if 0 /// Construct from a non-const iterator VertexIterT(const VertexIterT& _rhs) : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) {} /// Assignment from non-const iterator VertexIterT& operator=(const VertexIterT& _rhs) { mesh_ = _rhs.mesh_; hnd_ = _rhs.hnd_; skip_bits_ = _rhs.skip_bits_; return *this; } #else friend class ConstVertexIterT; #endif /// Standard dereferencing operator. reference operator*() const { return mesh_->deref(hnd_); } /// Standard pointer operator. pointer operator->() const { return &(mesh_->deref(hnd_)); } /// Get the handle of the item the iterator refers to. value_handle handle() const { return hnd_; } /// Cast to the handle of the item the iterator refers to. operator value_handle() const { return hnd_; } /// Are two iterators equal? Only valid if they refer to the same mesh! bool operator==(const VertexIterT& _rhs) const { return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); } /// Not equal? bool operator!=(const VertexIterT& _rhs) const { return !operator==(_rhs); } /// Standard pre-increment operator VertexIterT& operator++() { hnd_.__increment(); if (skip_bits_) skip_fwd(); return *this; } /// Standard pre-decrement operator VertexIterT& operator--() { hnd_.__decrement(); if (skip_bits_) skip_bwd(); return *this; } /// Turn on skipping: automatically skip deleted/hidden elements void enable_skipping() { if (mesh_ && mesh_->has_vertex_status()) { Attributes::StatusInfo status; status.set_deleted(true); status.set_hidden(true); skip_bits_ = status.bits(); skip_fwd(); } else skip_bits_ = 0; } /// Turn on skipping: automatically skip deleted/hidden elements void disable_skipping() { skip_bits_ = 0; } private: void skip_fwd() { assert(mesh_ && skip_bits_); while ((hnd_.idx() < (signed) mesh_->n_vertices()) && (mesh_->status(hnd_).bits() & skip_bits_)) hnd_.__increment(); } void skip_bwd() { assert(mesh_ && skip_bits_); while ((hnd_.idx() >= 0) && (mesh_->status(hnd_).bits() & skip_bits_)) hnd_.__decrement(); } private: mesh_ptr mesh_; value_handle hnd_; unsigned int skip_bits_; }; //== CLASS DEFINITION ========================================================= /** \class ConstVertexIterT IteratorsT.hh Linear iterator. */ template class ConstVertexIterT { public: //--- Typedefs --- typedef typename Mesh::Vertex value_type; typedef typename Mesh::VertexHandle value_handle; #if 1 typedef const value_type& reference; typedef const value_type* pointer; typedef const Mesh* mesh_ptr; typedef const Mesh& mesh_ref; #else typedef value_type& reference; typedef value_type* pointer; typedef Mesh* mesh_ptr; typedef Mesh& mesh_ref; #endif /// Default constructor. ConstVertexIterT() : mesh_(0), skip_bits_(0) {} /// Construct with mesh and a target handle. ConstVertexIterT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) { if (_skip) enable_skipping(); } /// Copy constructor ConstVertexIterT(const ConstVertexIterT& _rhs) : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) {} /// Assignment operator ConstVertexIterT& operator=(const ConstVertexIterT& _rhs) { mesh_ = _rhs.mesh_; hnd_ = _rhs.hnd_; skip_bits_ = _rhs.skip_bits_; return *this; } #if 1 /// Construct from a non-const iterator ConstVertexIterT(const VertexIterT& _rhs) : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) {} /// Assignment from non-const iterator ConstVertexIterT& operator=(const VertexIterT& _rhs) { mesh_ = _rhs.mesh_; hnd_ = _rhs.hnd_; skip_bits_ = _rhs.skip_bits_; return *this; } #else friend class ConstVertexIterT; #endif /// Standard dereferencing operator. reference operator*() const { return mesh_->deref(hnd_); } /// Standard pointer operator. pointer operator->() const { return &(mesh_->deref(hnd_)); } /// Get the handle of the item the iterator refers to. value_handle handle() const { return hnd_; } /// Cast to the handle of the item the iterator refers to. operator value_handle() const { return hnd_; } /// Are two iterators equal? Only valid if they refer to the same mesh! bool operator==(const ConstVertexIterT& _rhs) const { return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); } /// Not equal? bool operator!=(const ConstVertexIterT& _rhs) const { return !operator==(_rhs); } /// Standard pre-increment operator ConstVertexIterT& operator++() { hnd_.__increment(); if (skip_bits_) skip_fwd(); return *this; } /// Standard pre-decrement operator ConstVertexIterT& operator--() { hnd_.__decrement(); if (skip_bits_) skip_bwd(); return *this; } /// Turn on skipping: automatically skip deleted/hidden elements void enable_skipping() { if (mesh_ && mesh_->has_vertex_status()) { Attributes::StatusInfo status; status.set_deleted(true); status.set_hidden(true); skip_bits_ = status.bits(); skip_fwd(); } else skip_bits_ = 0; } /// Turn on skipping: automatically skip deleted/hidden elements void disable_skipping() { skip_bits_ = 0; } private: void skip_fwd() { assert(mesh_ && skip_bits_); while ((hnd_.idx() < (signed) mesh_->n_vertices()) && (mesh_->status(hnd_).bits() & skip_bits_)) hnd_.__increment(); } void skip_bwd() { assert(mesh_ && skip_bits_); while ((hnd_.idx() >= 0) && (mesh_->status(hnd_).bits() & skip_bits_)) hnd_.__decrement(); } private: mesh_ptr mesh_; value_handle hnd_; unsigned int skip_bits_; }; //== CLASS DEFINITION ========================================================= /** \class HalfedgeIterT IteratorsT.hh Linear iterator. */ template class HalfedgeIterT { public: //--- Typedefs --- typedef typename Mesh::Halfedge value_type; typedef typename Mesh::HalfedgeHandle value_handle; #if 0 typedef const value_type& reference; typedef const value_type* pointer; typedef const Mesh* mesh_ptr; typedef const Mesh& mesh_ref; #else typedef value_type& reference; typedef value_type* pointer; typedef Mesh* mesh_ptr; typedef Mesh& mesh_ref; #endif /// Default constructor. HalfedgeIterT() : mesh_(0), skip_bits_(0) {} /// Construct with mesh and a target handle. HalfedgeIterT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) { if (_skip) enable_skipping(); } /// Copy constructor HalfedgeIterT(const HalfedgeIterT& _rhs) : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) {} /// Assignment operator HalfedgeIterT& operator=(const HalfedgeIterT& _rhs) { mesh_ = _rhs.mesh_; hnd_ = _rhs.hnd_; skip_bits_ = _rhs.skip_bits_; return *this; } #if 0 /// Construct from a non-const iterator HalfedgeIterT(const HalfedgeIterT& _rhs) : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) {} /// Assignment from non-const iterator HalfedgeIterT& operator=(const HalfedgeIterT& _rhs) { mesh_ = _rhs.mesh_; hnd_ = _rhs.hnd_; skip_bits_ = _rhs.skip_bits_; return *this; } #else friend class ConstHalfedgeIterT; #endif /// Standard dereferencing operator. reference operator*() const { return mesh_->deref(hnd_); } /// Standard pointer operator. pointer operator->() const { return &(mesh_->deref(hnd_)); } /// Get the handle of the item the iterator refers to. value_handle handle() const { return hnd_; } /// Cast to the handle of the item the iterator refers to. operator value_handle() const { return hnd_; } /// Are two iterators equal? Only valid if they refer to the same mesh! bool operator==(const HalfedgeIterT& _rhs) const { return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); } /// Not equal? bool operator!=(const HalfedgeIterT& _rhs) const { return !operator==(_rhs); } /// Standard pre-increment operator HalfedgeIterT& operator++() { hnd_.__increment(); if (skip_bits_) skip_fwd(); return *this; } /// Standard pre-decrement operator HalfedgeIterT& operator--() { hnd_.__decrement(); if (skip_bits_) skip_bwd(); return *this; } /// Turn on skipping: automatically skip deleted/hidden elements void enable_skipping() { if (mesh_ && mesh_->has_halfedge_status()) { Attributes::StatusInfo status; status.set_deleted(true); status.set_hidden(true); skip_bits_ = status.bits(); skip_fwd(); } else skip_bits_ = 0; } /// Turn on skipping: automatically skip deleted/hidden elements void disable_skipping() { skip_bits_ = 0; } private: void skip_fwd() { assert(mesh_ && skip_bits_); while ((hnd_.idx() < (signed) mesh_->n_halfedges()) && (mesh_->status(hnd_).bits() & skip_bits_)) hnd_.__increment(); } void skip_bwd() { assert(mesh_ && skip_bits_); while ((hnd_.idx() >= 0) && (mesh_->status(hnd_).bits() & skip_bits_)) hnd_.__decrement(); } private: mesh_ptr mesh_; value_handle hnd_; unsigned int skip_bits_; }; //== CLASS DEFINITION ========================================================= /** \class ConstHalfedgeIterT IteratorsT.hh Linear iterator. */ template class ConstHalfedgeIterT { public: //--- Typedefs --- typedef typename Mesh::Halfedge value_type; typedef typename Mesh::HalfedgeHandle value_handle; #if 1 typedef const value_type& reference; typedef const value_type* pointer; typedef const Mesh* mesh_ptr; typedef const Mesh& mesh_ref; #else typedef value_type& reference; typedef value_type* pointer; typedef Mesh* mesh_ptr; typedef Mesh& mesh_ref; #endif /// Default constructor. ConstHalfedgeIterT() : mesh_(0), skip_bits_(0) {} /// Construct with mesh and a target handle. ConstHalfedgeIterT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) { if (_skip) enable_skipping(); } /// Copy constructor ConstHalfedgeIterT(const ConstHalfedgeIterT& _rhs) : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) {} /// Assignment operator ConstHalfedgeIterT& operator=(const ConstHalfedgeIterT& _rhs) { mesh_ = _rhs.mesh_; hnd_ = _rhs.hnd_; skip_bits_ = _rhs.skip_bits_; return *this; } #if 1 /// Construct from a non-const iterator ConstHalfedgeIterT(const HalfedgeIterT& _rhs) : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) {} /// Assignment from non-const iterator ConstHalfedgeIterT& operator=(const HalfedgeIterT& _rhs) { mesh_ = _rhs.mesh_; hnd_ = _rhs.hnd_; skip_bits_ = _rhs.skip_bits_; return *this; } #else friend class ConstHalfedgeIterT; #endif /// Standard dereferencing operator. reference operator*() const { return mesh_->deref(hnd_); } /// Standard pointer operator. pointer operator->() const { return &(mesh_->deref(hnd_)); } /// Get the handle of the item the iterator refers to. value_handle handle() const { return hnd_; } /// Cast to the handle of the item the iterator refers to. operator value_handle() const { return hnd_; } /// Are two iterators equal? Only valid if they refer to the same mesh! bool operator==(const ConstHalfedgeIterT& _rhs) const { return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); } /// Not equal? bool operator!=(const ConstHalfedgeIterT& _rhs) const { return !operator==(_rhs); } /// Standard pre-increment operator ConstHalfedgeIterT& operator++() { hnd_.__increment(); if (skip_bits_) skip_fwd(); return *this; } /// Standard pre-decrement operator ConstHalfedgeIterT& operator--() { hnd_.__decrement(); if (skip_bits_) skip_bwd(); return *this; } /// Turn on skipping: automatically skip deleted/hidden elements void enable_skipping() { if (mesh_ && mesh_->has_halfedge_status()) { Attributes::StatusInfo status; status.set_deleted(true); status.set_hidden(true); skip_bits_ = status.bits(); skip_fwd(); } else skip_bits_ = 0; } /// Turn on skipping: automatically skip deleted/hidden elements void disable_skipping() { skip_bits_ = 0; } private: void skip_fwd() { assert(mesh_ && skip_bits_); while ((hnd_.idx() < (signed) mesh_->n_halfedges()) && (mesh_->status(hnd_).bits() & skip_bits_)) hnd_.__increment(); } void skip_bwd() { assert(mesh_ && skip_bits_); while ((hnd_.idx() >= 0) && (mesh_->status(hnd_).bits() & skip_bits_)) hnd_.__decrement(); } private: mesh_ptr mesh_; value_handle hnd_; unsigned int skip_bits_; }; //== CLASS DEFINITION ========================================================= /** \class EdgeIterT IteratorsT.hh Linear iterator. */ template class EdgeIterT { public: //--- Typedefs --- typedef typename Mesh::Edge value_type; typedef typename Mesh::EdgeHandle value_handle; #if 0 typedef const value_type& reference; typedef const value_type* pointer; typedef const Mesh* mesh_ptr; typedef const Mesh& mesh_ref; #else typedef value_type& reference; typedef value_type* pointer; typedef Mesh* mesh_ptr; typedef Mesh& mesh_ref; #endif /// Default constructor. EdgeIterT() : mesh_(0), skip_bits_(0) {} /// Construct with mesh and a target handle. EdgeIterT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) { if (_skip) enable_skipping(); } /// Copy constructor EdgeIterT(const EdgeIterT& _rhs) : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) {} /// Assignment operator EdgeIterT& operator=(const EdgeIterT& _rhs) { mesh_ = _rhs.mesh_; hnd_ = _rhs.hnd_; skip_bits_ = _rhs.skip_bits_; return *this; } #if 0 /// Construct from a non-const iterator EdgeIterT(const EdgeIterT& _rhs) : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) {} /// Assignment from non-const iterator EdgeIterT& operator=(const EdgeIterT& _rhs) { mesh_ = _rhs.mesh_; hnd_ = _rhs.hnd_; skip_bits_ = _rhs.skip_bits_; return *this; } #else friend class ConstEdgeIterT; #endif /// Standard dereferencing operator. reference operator*() const { return mesh_->deref(hnd_); } /// Standard pointer operator. pointer operator->() const { return &(mesh_->deref(hnd_)); } /// Get the handle of the item the iterator refers to. value_handle handle() const { return hnd_; } /// Cast to the handle of the item the iterator refers to. operator value_handle() const { return hnd_; } /// Are two iterators equal? Only valid if they refer to the same mesh! bool operator==(const EdgeIterT& _rhs) const { return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); } /// Not equal? bool operator!=(const EdgeIterT& _rhs) const { return !operator==(_rhs); } /// Standard pre-increment operator EdgeIterT& operator++() { hnd_.__increment(); if (skip_bits_) skip_fwd(); return *this; } /// Standard pre-decrement operator EdgeIterT& operator--() { hnd_.__decrement(); if (skip_bits_) skip_bwd(); return *this; } /// Turn on skipping: automatically skip deleted/hidden elements void enable_skipping() { if (mesh_ && mesh_->has_edge_status()) { Attributes::StatusInfo status; status.set_deleted(true); status.set_hidden(true); skip_bits_ = status.bits(); skip_fwd(); } else skip_bits_ = 0; } /// Turn on skipping: automatically skip deleted/hidden elements void disable_skipping() { skip_bits_ = 0; } private: void skip_fwd() { assert(mesh_ && skip_bits_); while ((hnd_.idx() < (signed) mesh_->n_edges()) && (mesh_->status(hnd_).bits() & skip_bits_)) hnd_.__increment(); } void skip_bwd() { assert(mesh_ && skip_bits_); while ((hnd_.idx() >= 0) && (mesh_->status(hnd_).bits() & skip_bits_)) hnd_.__decrement(); } private: mesh_ptr mesh_; value_handle hnd_; unsigned int skip_bits_; }; //== CLASS DEFINITION ========================================================= /** \class ConstEdgeIterT IteratorsT.hh Linear iterator. */ template class ConstEdgeIterT { public: //--- Typedefs --- typedef typename Mesh::Edge value_type; typedef typename Mesh::EdgeHandle value_handle; #if 1 typedef const value_type& reference; typedef const value_type* pointer; typedef const Mesh* mesh_ptr; typedef const Mesh& mesh_ref; #else typedef value_type& reference; typedef value_type* pointer; typedef Mesh* mesh_ptr; typedef Mesh& mesh_ref; #endif /// Default constructor. ConstEdgeIterT() : mesh_(0), skip_bits_(0) {} /// Construct with mesh and a target handle. ConstEdgeIterT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) { if (_skip) enable_skipping(); } /// Copy constructor ConstEdgeIterT(const ConstEdgeIterT& _rhs) : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) {} /// Assignment operator ConstEdgeIterT& operator=(const ConstEdgeIterT& _rhs) { mesh_ = _rhs.mesh_; hnd_ = _rhs.hnd_; skip_bits_ = _rhs.skip_bits_; return *this; } #if 1 /// Construct from a non-const iterator ConstEdgeIterT(const EdgeIterT& _rhs) : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) {} /// Assignment from non-const iterator ConstEdgeIterT& operator=(const EdgeIterT& _rhs) { mesh_ = _rhs.mesh_; hnd_ = _rhs.hnd_; skip_bits_ = _rhs.skip_bits_; return *this; } #else friend class ConstEdgeIterT; #endif /// Standard dereferencing operator. reference operator*() const { return mesh_->deref(hnd_); } /// Standard pointer operator. pointer operator->() const { return &(mesh_->deref(hnd_)); } /// Get the handle of the item the iterator refers to. value_handle handle() const { return hnd_; } /// Cast to the handle of the item the iterator refers to. operator value_handle() const { return hnd_; } /// Are two iterators equal? Only valid if they refer to the same mesh! bool operator==(const ConstEdgeIterT& _rhs) const { return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); } /// Not equal? bool operator!=(const ConstEdgeIterT& _rhs) const { return !operator==(_rhs); } /// Standard pre-increment operator ConstEdgeIterT& operator++() { hnd_.__increment(); if (skip_bits_) skip_fwd(); return *this; } /// Standard pre-decrement operator ConstEdgeIterT& operator--() { hnd_.__decrement(); if (skip_bits_) skip_bwd(); return *this; } /// Turn on skipping: automatically skip deleted/hidden elements void enable_skipping() { if (mesh_ && mesh_->has_edge_status()) { Attributes::StatusInfo status; status.set_deleted(true); status.set_hidden(true); skip_bits_ = status.bits(); skip_fwd(); } else skip_bits_ = 0; } /// Turn on skipping: automatically skip deleted/hidden elements void disable_skipping() { skip_bits_ = 0; } private: void skip_fwd() { assert(mesh_ && skip_bits_); while ((hnd_.idx() < (signed) mesh_->n_edges()) && (mesh_->status(hnd_).bits() & skip_bits_)) hnd_.__increment(); } void skip_bwd() { assert(mesh_ && skip_bits_); while ((hnd_.idx() >= 0) && (mesh_->status(hnd_).bits() & skip_bits_)) hnd_.__decrement(); } private: mesh_ptr mesh_; value_handle hnd_; unsigned int skip_bits_; }; //== CLASS DEFINITION ========================================================= /** \class FaceIterT IteratorsT.hh Linear iterator. */ template class FaceIterT { public: //--- Typedefs --- typedef typename Mesh::Face value_type; typedef typename Mesh::FaceHandle value_handle; #if 0 typedef const value_type& reference; typedef const value_type* pointer; typedef const Mesh* mesh_ptr; typedef const Mesh& mesh_ref; #else typedef value_type& reference; typedef value_type* pointer; typedef Mesh* mesh_ptr; typedef Mesh& mesh_ref; #endif /// Default constructor. FaceIterT() : mesh_(0), skip_bits_(0) {} /// Construct with mesh and a target handle. FaceIterT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) { if (_skip) enable_skipping(); } /// Copy constructor FaceIterT(const FaceIterT& _rhs) : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) {} /// Assignment operator FaceIterT& operator=(const FaceIterT& _rhs) { mesh_ = _rhs.mesh_; hnd_ = _rhs.hnd_; skip_bits_ = _rhs.skip_bits_; return *this; } #if 0 /// Construct from a non-const iterator FaceIterT(const FaceIterT& _rhs) : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) {} /// Assignment from non-const iterator FaceIterT& operator=(const FaceIterT& _rhs) { mesh_ = _rhs.mesh_; hnd_ = _rhs.hnd_; skip_bits_ = _rhs.skip_bits_; return *this; } #else friend class ConstFaceIterT; #endif /// Standard dereferencing operator. reference operator*() const { return mesh_->deref(hnd_); } /// Standard pointer operator. pointer operator->() const { return &(mesh_->deref(hnd_)); } /// Get the handle of the item the iterator refers to. value_handle handle() const { return hnd_; } /// Cast to the handle of the item the iterator refers to. operator value_handle() const { return hnd_; } /// Are two iterators equal? Only valid if they refer to the same mesh! bool operator==(const FaceIterT& _rhs) const { return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); } /// Not equal? bool operator!=(const FaceIterT& _rhs) const { return !operator==(_rhs); } /// Standard pre-increment operator FaceIterT& operator++() { hnd_.__increment(); if (skip_bits_) skip_fwd(); return *this; } /// Standard pre-decrement operator FaceIterT& operator--() { hnd_.__decrement(); if (skip_bits_) skip_bwd(); return *this; } /// Turn on skipping: automatically skip deleted/hidden elements void enable_skipping() { if (mesh_ && mesh_->has_face_status()) { Attributes::StatusInfo status; status.set_deleted(true); status.set_hidden(true); skip_bits_ = status.bits(); skip_fwd(); } else skip_bits_ = 0; } /// Turn on skipping: automatically skip deleted/hidden elements void disable_skipping() { skip_bits_ = 0; } private: void skip_fwd() { assert(mesh_ && skip_bits_); while ((hnd_.idx() < (signed) mesh_->n_faces()) && (mesh_->status(hnd_).bits() & skip_bits_)) hnd_.__increment(); } void skip_bwd() { assert(mesh_ && skip_bits_); while ((hnd_.idx() >= 0) && (mesh_->status(hnd_).bits() & skip_bits_)) hnd_.__decrement(); } private: mesh_ptr mesh_; value_handle hnd_; unsigned int skip_bits_; }; //== CLASS DEFINITION ========================================================= /** \class ConstFaceIterT IteratorsT.hh Linear iterator. */ template class ConstFaceIterT { public: //--- Typedefs --- typedef typename Mesh::Face value_type; typedef typename Mesh::FaceHandle value_handle; #if 1 typedef const value_type& reference; typedef const value_type* pointer; typedef const Mesh* mesh_ptr; typedef const Mesh& mesh_ref; #else typedef value_type& reference; typedef value_type* pointer; typedef Mesh* mesh_ptr; typedef Mesh& mesh_ref; #endif /// Default constructor. ConstFaceIterT() : mesh_(0), skip_bits_(0) {} /// Construct with mesh and a target handle. ConstFaceIterT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) { if (_skip) enable_skipping(); } /// Copy constructor ConstFaceIterT(const ConstFaceIterT& _rhs) : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) {} /// Assignment operator ConstFaceIterT& operator=(const ConstFaceIterT& _rhs) { mesh_ = _rhs.mesh_; hnd_ = _rhs.hnd_; skip_bits_ = _rhs.skip_bits_; return *this; } #if 1 /// Construct from a non-const iterator ConstFaceIterT(const FaceIterT& _rhs) : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) {} /// Assignment from non-const iterator ConstFaceIterT& operator=(const FaceIterT& _rhs) { mesh_ = _rhs.mesh_; hnd_ = _rhs.hnd_; skip_bits_ = _rhs.skip_bits_; return *this; } #else friend class ConstFaceIterT; #endif /// Standard dereferencing operator. reference operator*() const { return mesh_->deref(hnd_); } /// Standard pointer operator. pointer operator->() const { return &(mesh_->deref(hnd_)); } /// Get the handle of the item the iterator refers to. value_handle handle() const { return hnd_; } /// Cast to the handle of the item the iterator refers to. operator value_handle() const { return hnd_; } /// Are two iterators equal? Only valid if they refer to the same mesh! bool operator==(const ConstFaceIterT& _rhs) const { return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); } /// Not equal? bool operator!=(const ConstFaceIterT& _rhs) const { return !operator==(_rhs); } /// Standard pre-increment operator ConstFaceIterT& operator++() { hnd_.__increment(); if (skip_bits_) skip_fwd(); return *this; } /// Standard pre-decrement operator ConstFaceIterT& operator--() { hnd_.__decrement(); if (skip_bits_) skip_bwd(); return *this; } /// Turn on skipping: automatically skip deleted/hidden elements void enable_skipping() { if (mesh_ && mesh_->has_face_status()) { Attributes::StatusInfo status; status.set_deleted(true); status.set_hidden(true); skip_bits_ = status.bits(); skip_fwd(); } else skip_bits_ = 0; } /// Turn on skipping: automatically skip deleted/hidden elements void disable_skipping() { skip_bits_ = 0; } private: void skip_fwd() { assert(mesh_ && skip_bits_); while ((hnd_.idx() < (signed) mesh_->n_faces()) && (mesh_->status(hnd_).bits() & skip_bits_)) hnd_.__increment(); } void skip_bwd() { assert(mesh_ && skip_bits_); while ((hnd_.idx() >= 0) && (mesh_->status(hnd_).bits() & skip_bits_)) hnd_.__decrement(); } private: mesh_ptr mesh_; value_handle hnd_; unsigned int skip_bits_; }; //============================================================================= } // namespace Iterators } // namespace OpenMesh //============================================================================= #endif //=============================================================================