OpenMesh
OpenMesh/Core/Mesh/IteratorsT.hh
00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                               OpenMesh                                    *
00004  *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openmesh.org                                *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------* 
00008  *  This file is part of OpenMesh.                                           *
00009  *                                                                           *
00010  *  OpenMesh is free software: you can redistribute it and/or modify         * 
00011  *  it under the terms of the GNU Lesser General Public License as           *
00012  *  published by the Free Software Foundation, either version 3 of           *
00013  *  the License, or (at your option) any later version with the              *
00014  *  following exceptions:                                                    *
00015  *                                                                           *
00016  *  If other files instantiate templates or use macros                       *
00017  *  or inline functions from this file, or you compile this file and         *
00018  *  link it with other files to produce an executable, this file does        *
00019  *  not by itself cause the resulting executable to be covered by the        *
00020  *  GNU Lesser General Public License. This exception does not however       *
00021  *  invalidate any other reasons why the executable file might be            *
00022  *  covered by the GNU Lesser General Public License.                        *
00023  *                                                                           *
00024  *  OpenMesh is distributed in the hope that it will be useful,              *
00025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
00027  *  GNU Lesser General Public License for more details.                      *
00028  *                                                                           *
00029  *  You should have received a copy of the GNU LesserGeneral Public          *
00030  *  License along with OpenMesh.  If not,                                    *
00031  *  see <http://www.gnu.org/licenses/>.                                      *
00032  *                                                                           *
00033 \*===========================================================================*/ 
00034 
00035 /*===========================================================================*\
00036  *                                                                           *             
00037  *   $Revision: 362 $                                                         *
00038  *   $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 2011) $                   *
00039  *                                                                           *
00040 \*===========================================================================*/
00041 
00042 #ifndef OPENMESH_ITERATORS_HH
00043 #define OPENMESH_ITERATORS_HH
00044 
00045 //=============================================================================
00046 //
00047 //  Iterators for PolyMesh/TriMesh
00048 //
00049 //=============================================================================
00050 
00051 
00052 
00053 //== INCLUDES =================================================================
00054 
00055 #include <OpenMesh/Core/System/config.h>
00056 #include <OpenMesh/Core/Mesh/Status.hh>
00057 #include <assert.h>
00058 #include <cstddef>
00059 
00060 
00061 //== NAMESPACES ===============================================================
00062 
00063 namespace OpenMesh {
00064 namespace Iterators {
00065 
00066 
00067 //== FORWARD DECLARATIONS =====================================================
00068 
00069 
00070 template <class Mesh> class VertexIterT;
00071 template <class Mesh> class ConstVertexIterT;
00072 template <class Mesh> class HalfedgeIterT;
00073 template <class Mesh> class ConstHalfedgeIterT;
00074 template <class Mesh> class EdgeIterT;
00075 template <class Mesh> class ConstEdgeIterT;
00076 template <class Mesh> class FaceIterT;
00077 template <class Mesh> class ConstFaceIterT;
00078 
00079 
00080 
00081 
00082 //== CLASS DEFINITION =========================================================
00083 
00084               
00089 template <class Mesh>
00090 class VertexIterT
00091 {
00092 public:
00093   
00094 
00095   //--- Typedefs ---
00096 
00097   typedef typename Mesh::Vertex           value_type;
00098   typedef typename Mesh::VertexHandle     value_handle;
00099 
00100 #if 0
00101   typedef std::bidirectional_iterator_tag iterator_category;
00102   typedef std::ptrdiff_t                  difference_type;
00103   typedef const value_type&               reference;
00104   typedef const value_type*               pointer;
00105   typedef const Mesh*                     mesh_ptr;
00106   typedef const Mesh&                     mesh_ref;
00107 #else
00108   typedef std::bidirectional_iterator_tag iterator_category;
00109   typedef std::ptrdiff_t                  difference_type;
00110   typedef value_type&                     reference;
00111   typedef value_type*                     pointer;
00112   typedef Mesh*                           mesh_ptr;
00113   typedef Mesh&                           mesh_ref;
00114 #endif
00115 
00116 
00118   VertexIterT() 
00119     : mesh_(0), skip_bits_(0) 
00120   {}
00121 
00122 
00124   VertexIterT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) 
00125     : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) 
00126   {
00127     if (_skip) enable_skipping();
00128     
00129     // Set vertex handle invalid if the mesh contains no vertex
00130     if(_mesh.n_vertices() == 0) hnd_ = value_handle(-1);
00131   }
00132 
00133 
00135   VertexIterT(const VertexIterT& _rhs) 
00136     : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_)
00137   {}
00138   
00139 
00141   VertexIterT& operator=(const VertexIterT<Mesh>& _rhs) 
00142   {
00143     mesh_      = _rhs.mesh_;
00144     hnd_       = _rhs.hnd_;
00145     skip_bits_ = _rhs.skip_bits_;
00146     return *this;
00147   }
00148 
00149 
00150 #if 0
00151 
00153   VertexIterT(const VertexIterT<Mesh>& _rhs) 
00154     : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) 
00155   {}
00156   
00157 
00159   VertexIterT& operator=(const VertexIterT<Mesh>& _rhs) 
00160   {
00161     mesh_      = _rhs.mesh_;
00162     hnd_       = _rhs.hnd_;
00163     skip_bits_ = _rhs.skip_bits_;
00164     return *this;
00165   }
00166 
00167 #else
00168   friend class ConstVertexIterT<Mesh>;
00169 #endif
00170 
00171 
00173   reference operator*()  const { return mesh_->deref(hnd_); }
00174   
00176   pointer   operator->() const { return &(mesh_->deref(hnd_)); }
00177   
00179   value_handle handle() const { return hnd_; }
00180 
00182   operator value_handle() const { return hnd_; }
00183 
00185   bool operator==(const VertexIterT& _rhs) const 
00186   { return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); }
00187 
00189   bool operator!=(const VertexIterT& _rhs) const 
00190   { return !operator==(_rhs); }
00191   
00193   VertexIterT& operator++() 
00194   { hnd_.__increment(); if (skip_bits_) skip_fwd(); return *this; }
00195 
00197   VertexIterT& operator--() 
00198   { hnd_.__decrement(); if (skip_bits_) skip_bwd(); return *this; }
00199   
00200 
00202   void enable_skipping()
00203   {
00204     if (mesh_ && mesh_->has_vertex_status())
00205     {
00206       Attributes::StatusInfo status;
00207       status.set_deleted(true);
00208       status.set_hidden(true);
00209       skip_bits_ = status.bits();
00210       skip_fwd();
00211     }
00212     else skip_bits_ = 0;
00213   }
00214 
00215 
00217   void disable_skipping() { skip_bits_ = 0; }
00218 
00219 
00220 
00221 private:
00222 
00223   void skip_fwd() 
00224   {
00225     assert(mesh_ && skip_bits_);
00226     while ((hnd_.idx() < (signed) mesh_->n_vertices()) && 
00227            (mesh_->status(hnd_).bits() & skip_bits_))
00228       hnd_.__increment();
00229   }
00230 
00231 
00232   void skip_bwd() 
00233   {
00234     assert(mesh_ && skip_bits_);
00235     while ((hnd_.idx() >= 0) && 
00236            (mesh_->status(hnd_).bits() & skip_bits_))
00237       hnd_.__decrement();
00238   }
00239 
00240 
00241 
00242 private:
00243   mesh_ptr      mesh_;
00244   value_handle  hnd_;
00245   unsigned int  skip_bits_;
00246 };
00247 
00248 
00249 //== CLASS DEFINITION =========================================================
00250 
00251               
00256 template <class Mesh>
00257 class ConstVertexIterT
00258 {
00259 public:
00260   
00261 
00262   //--- Typedefs ---
00263 
00264   typedef typename Mesh::Vertex           value_type;
00265   typedef typename Mesh::VertexHandle     value_handle;
00266 
00267 #if 1
00268   typedef std::bidirectional_iterator_tag iterator_category;
00269   typedef std::ptrdiff_t                  difference_type;
00270   typedef const value_type&               reference;
00271   typedef const value_type*               pointer;
00272   typedef const Mesh*                     mesh_ptr;
00273   typedef const Mesh&                     mesh_ref;
00274 #else
00275   typedef std::bidirectional_iterator_tag iterator_category;
00276   typedef std::ptrdiff_t                  difference_type;
00277   typedef value_type&                     reference;
00278   typedef value_type*                     pointer;
00279   typedef Mesh*                           mesh_ptr;
00280   typedef Mesh&                           mesh_ref;
00281 #endif
00282 
00283 
00284 
00285 
00287   ConstVertexIterT() 
00288     : mesh_(0), skip_bits_(0) 
00289   {}
00290 
00291 
00293   ConstVertexIterT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) 
00294     : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) 
00295   {
00296     if (_skip) enable_skipping();
00297     
00298     // Set vertex handle invalid if the mesh contains no vertex
00299     if(_mesh.n_vertices() == 0) hnd_ = value_handle(-1);
00300   }
00301 
00302 
00304   ConstVertexIterT(const ConstVertexIterT& _rhs) 
00305     : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_)
00306   {}
00307   
00308 
00310   ConstVertexIterT& operator=(const ConstVertexIterT<Mesh>& _rhs) 
00311   {
00312     mesh_      = _rhs.mesh_;
00313     hnd_       = _rhs.hnd_;
00314     skip_bits_ = _rhs.skip_bits_;
00315     return *this;
00316   }
00317 
00318 
00319 #if 1
00320 
00322   ConstVertexIterT(const VertexIterT<Mesh>& _rhs) 
00323     : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) 
00324   {}
00325   
00326 
00328   ConstVertexIterT& operator=(const VertexIterT<Mesh>& _rhs) 
00329   {
00330     mesh_      = _rhs.mesh_;
00331     hnd_       = _rhs.hnd_;
00332     skip_bits_ = _rhs.skip_bits_;
00333     return *this;
00334   }
00335 
00336 #else
00337   friend class ConstVertexIterT<Mesh>;
00338 #endif
00339 
00340 
00342   reference operator*()  const { return mesh_->deref(hnd_); }
00343   
00345   pointer   operator->() const { return &(mesh_->deref(hnd_)); }
00346   
00348   value_handle handle() const { return hnd_; }
00349 
00351   operator value_handle() const { return hnd_; }
00352 
00354   bool operator==(const ConstVertexIterT& _rhs) const 
00355   { return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); }
00356 
00358   bool operator!=(const ConstVertexIterT& _rhs) const 
00359   { return !operator==(_rhs); }
00360   
00362   ConstVertexIterT& operator++() 
00363   { hnd_.__increment(); if (skip_bits_) skip_fwd(); return *this; }
00364 
00366   ConstVertexIterT& operator--() 
00367   { hnd_.__decrement(); if (skip_bits_) skip_bwd(); return *this; }
00368   
00369 
00371   void enable_skipping()
00372   {
00373     if (mesh_ && mesh_->has_vertex_status())
00374     {
00375       Attributes::StatusInfo status;
00376       status.set_deleted(true);
00377       status.set_hidden(true);
00378       skip_bits_ = status.bits();
00379       skip_fwd();
00380     }
00381     else skip_bits_ = 0;
00382   }
00383 
00384 
00386   void disable_skipping() { skip_bits_ = 0; }
00387 
00388 
00389 
00390 private:
00391 
00392   void skip_fwd() 
00393   {
00394     assert(mesh_ && skip_bits_);
00395     while ((hnd_.idx() < (signed) mesh_->n_vertices()) && 
00396            (mesh_->status(hnd_).bits() & skip_bits_))
00397       hnd_.__increment();
00398   }
00399 
00400 
00401   void skip_bwd() 
00402   {
00403     assert(mesh_ && skip_bits_);
00404     while ((hnd_.idx() >= 0) && 
00405            (mesh_->status(hnd_).bits() & skip_bits_))
00406       hnd_.__decrement();
00407   }
00408 
00409 
00410 
00411 private:
00412   mesh_ptr      mesh_;
00413   value_handle  hnd_;
00414   unsigned int  skip_bits_;
00415 };
00416 
00417 
00418 //== CLASS DEFINITION =========================================================
00419 
00420               
00425 template <class Mesh>
00426 class HalfedgeIterT
00427 {
00428 public:
00429   
00430 
00431   //--- Typedefs ---
00432 
00433   typedef typename Mesh::Halfedge         value_type;
00434   typedef typename Mesh::HalfedgeHandle   value_handle;
00435 
00436 #if 0
00437   typedef std::bidirectional_iterator_tag iterator_category;
00438   typedef std::ptrdiff_t                  difference_type;
00439   typedef const value_type&               reference;
00440   typedef const value_type*               pointer;
00441   typedef const Mesh*                     mesh_ptr;
00442   typedef const Mesh&                     mesh_ref;
00443 #else
00444   typedef std::bidirectional_iterator_tag iterator_category;
00445   typedef std::ptrdiff_t                  difference_type;
00446   typedef value_type&                     reference;
00447   typedef value_type*                     pointer;
00448   typedef Mesh*                           mesh_ptr;
00449   typedef Mesh&                           mesh_ref;
00450 #endif
00451 
00452 
00453 
00454 
00456   HalfedgeIterT() 
00457     : mesh_(0), skip_bits_(0) 
00458   {}
00459 
00460 
00462   HalfedgeIterT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) 
00463     : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) 
00464   {
00465     if (_skip) enable_skipping();
00466     
00467     // Set halfedge handle invalid if the mesh contains no edge
00468     if(_mesh.n_edges() == 0) hnd_ = value_handle(-1);
00469   }
00470 
00471 
00473   HalfedgeIterT(const HalfedgeIterT& _rhs) 
00474     : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_)
00475   {}
00476   
00477 
00479   HalfedgeIterT& operator=(const HalfedgeIterT<Mesh>& _rhs) 
00480   {
00481     mesh_      = _rhs.mesh_;
00482     hnd_       = _rhs.hnd_;
00483     skip_bits_ = _rhs.skip_bits_;
00484     return *this;
00485   }
00486 
00487 
00488 #if 0
00489 
00491   HalfedgeIterT(const HalfedgeIterT<Mesh>& _rhs) 
00492     : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) 
00493   {}
00494   
00495 
00497   HalfedgeIterT& operator=(const HalfedgeIterT<Mesh>& _rhs) 
00498   {
00499     mesh_      = _rhs.mesh_;
00500     hnd_       = _rhs.hnd_;
00501     skip_bits_ = _rhs.skip_bits_;
00502     return *this;
00503   }
00504 
00505 #else
00506   friend class ConstHalfedgeIterT<Mesh>;
00507 #endif
00508 
00509 
00511   reference operator*()  const { return mesh_->deref(hnd_); }
00512   
00514   pointer   operator->() const { return &(mesh_->deref(hnd_)); }
00515   
00517   value_handle handle() const { return hnd_; }
00518 
00520   operator value_handle() const { return hnd_; }
00521 
00523   bool operator==(const HalfedgeIterT& _rhs) const 
00524   { return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); }
00525 
00527   bool operator!=(const HalfedgeIterT& _rhs) const 
00528   { return !operator==(_rhs); }
00529   
00531   HalfedgeIterT& operator++() 
00532   { hnd_.__increment(); if (skip_bits_) skip_fwd(); return *this; }
00533 
00535   HalfedgeIterT& operator--() 
00536   { hnd_.__decrement(); if (skip_bits_) skip_bwd(); return *this; }
00537   
00538 
00540   void enable_skipping()
00541   {
00542     if (mesh_ && mesh_->has_halfedge_status())
00543     {
00544       Attributes::StatusInfo status;
00545       status.set_deleted(true);
00546       status.set_hidden(true);
00547       skip_bits_ = status.bits();
00548       skip_fwd();
00549     }
00550     else skip_bits_ = 0;
00551   }
00552 
00553 
00555   void disable_skipping() { skip_bits_ = 0; }
00556 
00557 
00558 
00559 private:
00560 
00561   void skip_fwd() 
00562   {
00563     assert(mesh_ && skip_bits_);
00564     while ((hnd_.idx() < (signed) mesh_->n_halfedges()) && 
00565            (mesh_->status(hnd_).bits() & skip_bits_))
00566       hnd_.__increment();
00567   }
00568 
00569 
00570   void skip_bwd() 
00571   {
00572     assert(mesh_ && skip_bits_);
00573     while ((hnd_.idx() >= 0) && 
00574            (mesh_->status(hnd_).bits() & skip_bits_))
00575       hnd_.__decrement();
00576   }
00577 
00578 
00579 
00580 private:
00581   mesh_ptr      mesh_;
00582   value_handle  hnd_;
00583   unsigned int  skip_bits_;
00584 };
00585 
00586 
00587 //== CLASS DEFINITION =========================================================
00588 
00589               
00594 template <class Mesh>
00595 class ConstHalfedgeIterT
00596 {
00597 public:
00598   
00599 
00600   //--- Typedefs ---
00601 
00602   typedef typename Mesh::Halfedge         value_type;
00603   typedef typename Mesh::HalfedgeHandle   value_handle;
00604 
00605 #if 1
00606   typedef std::bidirectional_iterator_tag iterator_category;
00607   typedef std::ptrdiff_t                  difference_type;
00608   typedef const value_type&               reference;
00609   typedef const value_type*               pointer;
00610   typedef const Mesh*                     mesh_ptr;
00611   typedef const Mesh&                     mesh_ref;
00612 #else
00613   typedef std::bidirectional_iterator_tag iterator_category;
00614   typedef std::ptrdiff_t                  difference_type;
00615   typedef value_type&                     reference;
00616   typedef value_type*                     pointer;
00617   typedef Mesh*                           mesh_ptr;
00618   typedef Mesh&                           mesh_ref;
00619 #endif
00620 
00621 
00622 
00623 
00625   ConstHalfedgeIterT() 
00626     : mesh_(0), skip_bits_(0) 
00627   {}
00628 
00629 
00631   ConstHalfedgeIterT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) 
00632     : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) 
00633   {
00634     if (_skip) enable_skipping();
00635     
00636     // Set halfedge handle invalid if the mesh contains no edge
00637     if(_mesh.n_edges() == 0) hnd_ = value_handle(-1);
00638   }
00639 
00640 
00642   ConstHalfedgeIterT(const ConstHalfedgeIterT& _rhs) 
00643     : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_)
00644   {}
00645   
00646 
00648   ConstHalfedgeIterT& operator=(const ConstHalfedgeIterT<Mesh>& _rhs) 
00649   {
00650     mesh_      = _rhs.mesh_;
00651     hnd_       = _rhs.hnd_;
00652     skip_bits_ = _rhs.skip_bits_;
00653     return *this;
00654   }
00655 
00656 
00657 #if 1
00658 
00660   ConstHalfedgeIterT(const HalfedgeIterT<Mesh>& _rhs) 
00661     : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) 
00662   {}
00663   
00664 
00666   ConstHalfedgeIterT& operator=(const HalfedgeIterT<Mesh>& _rhs) 
00667   {
00668     mesh_      = _rhs.mesh_;
00669     hnd_       = _rhs.hnd_;
00670     skip_bits_ = _rhs.skip_bits_;
00671     return *this;
00672   }
00673 
00674 #else
00675   friend class ConstHalfedgeIterT<Mesh>;
00676 #endif
00677 
00678 
00680   reference operator*()  const { return mesh_->deref(hnd_); }
00681   
00683   pointer   operator->() const { return &(mesh_->deref(hnd_)); }
00684   
00686   value_handle handle() const { return hnd_; }
00687 
00689   operator value_handle() const { return hnd_; }
00690 
00692   bool operator==(const ConstHalfedgeIterT& _rhs) const 
00693   { return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); }
00694 
00696   bool operator!=(const ConstHalfedgeIterT& _rhs) const 
00697   { return !operator==(_rhs); }
00698   
00700   ConstHalfedgeIterT& operator++() 
00701   { hnd_.__increment(); if (skip_bits_) skip_fwd(); return *this; }
00702 
00704   ConstHalfedgeIterT& operator--() 
00705   { hnd_.__decrement(); if (skip_bits_) skip_bwd(); return *this; }
00706   
00707 
00709   void enable_skipping()
00710   {
00711     if (mesh_ && mesh_->has_halfedge_status())
00712     {
00713       Attributes::StatusInfo status;
00714       status.set_deleted(true);
00715       status.set_hidden(true);
00716       skip_bits_ = status.bits();
00717       skip_fwd();
00718     }
00719     else skip_bits_ = 0;
00720   }
00721 
00722 
00724   void disable_skipping() { skip_bits_ = 0; }
00725 
00726 
00727 
00728 private:
00729 
00730   void skip_fwd() 
00731   {
00732     assert(mesh_ && skip_bits_);
00733     while ((hnd_.idx() < (signed) mesh_->n_halfedges()) && 
00734            (mesh_->status(hnd_).bits() & skip_bits_))
00735       hnd_.__increment();
00736   }
00737 
00738 
00739   void skip_bwd() 
00740   {
00741     assert(mesh_ && skip_bits_);
00742     while ((hnd_.idx() >= 0) && 
00743            (mesh_->status(hnd_).bits() & skip_bits_))
00744       hnd_.__decrement();
00745   }
00746 
00747 
00748 
00749 private:
00750   mesh_ptr      mesh_;
00751   value_handle  hnd_;
00752   unsigned int  skip_bits_;
00753 };
00754 
00755 
00756 //== CLASS DEFINITION =========================================================
00757 
00758               
00763 template <class Mesh>
00764 class EdgeIterT
00765 {
00766 public:
00767   
00768 
00769   //--- Typedefs ---
00770 
00771   typedef typename Mesh::Edge             value_type;
00772   typedef typename Mesh::EdgeHandle       value_handle;
00773 
00774 #if 0
00775   typedef std::bidirectional_iterator_tag iterator_category;
00776   typedef std::ptrdiff_t                  difference_type;
00777   typedef const value_type&               reference;
00778   typedef const value_type*               pointer;
00779   typedef const Mesh*                     mesh_ptr;
00780   typedef const Mesh&                     mesh_ref;
00781 #else
00782   typedef std::bidirectional_iterator_tag iterator_category;
00783   typedef std::ptrdiff_t                  difference_type;
00784   typedef value_type&                     reference;
00785   typedef value_type*                     pointer;
00786   typedef Mesh*                           mesh_ptr;
00787   typedef Mesh&                           mesh_ref;
00788 #endif
00789 
00790 
00791 
00792 
00794   EdgeIterT() 
00795     : mesh_(0), skip_bits_(0) 
00796   {}
00797 
00798 
00800   EdgeIterT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) 
00801     : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) 
00802   {
00803     if (_skip) enable_skipping();
00804     
00805     // Set halfedge handle invalid if the mesh contains no edge
00806     if(_mesh.n_edges() == 0) hnd_ = value_handle(-1);
00807   }
00808 
00809 
00811   EdgeIterT(const EdgeIterT& _rhs) 
00812     : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_)
00813   {}
00814   
00815 
00817   EdgeIterT& operator=(const EdgeIterT<Mesh>& _rhs) 
00818   {
00819     mesh_      = _rhs.mesh_;
00820     hnd_       = _rhs.hnd_;
00821     skip_bits_ = _rhs.skip_bits_;
00822     return *this;
00823   }
00824 
00825 
00826 #if 0
00827 
00829   EdgeIterT(const EdgeIterT<Mesh>& _rhs) 
00830     : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) 
00831   {}
00832   
00833 
00835   EdgeIterT& operator=(const EdgeIterT<Mesh>& _rhs) 
00836   {
00837     mesh_      = _rhs.mesh_;
00838     hnd_       = _rhs.hnd_;
00839     skip_bits_ = _rhs.skip_bits_;
00840     return *this;
00841   }
00842 
00843 #else
00844   friend class ConstEdgeIterT<Mesh>;
00845 #endif
00846 
00847 
00849   reference operator*()  const { return mesh_->deref(hnd_); }
00850   
00852   pointer   operator->() const { return &(mesh_->deref(hnd_)); }
00853   
00855   value_handle handle() const { return hnd_; }
00856 
00858   operator value_handle() const { return hnd_; }
00859 
00861   bool operator==(const EdgeIterT& _rhs) const 
00862   { return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); }
00863 
00865   bool operator!=(const EdgeIterT& _rhs) const 
00866   { return !operator==(_rhs); }
00867   
00869   EdgeIterT& operator++() 
00870   { hnd_.__increment(); if (skip_bits_) skip_fwd(); return *this; }
00871 
00873   EdgeIterT& operator--() 
00874   { hnd_.__decrement(); if (skip_bits_) skip_bwd(); return *this; }
00875   
00876 
00878   void enable_skipping()
00879   {
00880     if (mesh_ && mesh_->has_edge_status())
00881     {
00882       Attributes::StatusInfo status;
00883       status.set_deleted(true);
00884       status.set_hidden(true);
00885       skip_bits_ = status.bits();
00886       skip_fwd();
00887     }
00888     else skip_bits_ = 0;
00889   }
00890 
00891 
00893   void disable_skipping() { skip_bits_ = 0; }
00894 
00895 
00896 
00897 private:
00898 
00899   void skip_fwd() 
00900   {
00901     assert(mesh_ && skip_bits_);
00902     while ((hnd_.idx() < (signed) mesh_->n_edges()) && 
00903            (mesh_->status(hnd_).bits() & skip_bits_))
00904       hnd_.__increment();
00905   }
00906 
00907 
00908   void skip_bwd() 
00909   {
00910     assert(mesh_ && skip_bits_);
00911     while ((hnd_.idx() >= 0) && 
00912            (mesh_->status(hnd_).bits() & skip_bits_))
00913       hnd_.__decrement();
00914   }
00915 
00916 
00917 
00918 private:
00919   mesh_ptr      mesh_;
00920   value_handle  hnd_;
00921   unsigned int  skip_bits_;
00922 };
00923 
00924 
00925 //== CLASS DEFINITION =========================================================
00926 
00927               
00932 template <class Mesh>
00933 class ConstEdgeIterT
00934 {
00935 public:
00936   
00937 
00938   //--- Typedefs ---
00939 
00940   typedef typename Mesh::Edge             value_type;
00941   typedef typename Mesh::EdgeHandle       value_handle;
00942 
00943 #if 1
00944   typedef std::bidirectional_iterator_tag iterator_category;
00945   typedef std::ptrdiff_t                  difference_type;
00946   typedef const value_type&               reference;
00947   typedef const value_type*               pointer;
00948   typedef const Mesh*                     mesh_ptr;
00949   typedef const Mesh&                     mesh_ref;
00950 #else
00951   typedef std::bidirectional_iterator_tag iterator_category;
00952   typedef std::ptrdiff_t                  difference_type;
00953   typedef value_type&                     reference;
00954   typedef value_type*                     pointer;
00955   typedef Mesh*                           mesh_ptr;
00956   typedef Mesh&                           mesh_ref;
00957 #endif
00958 
00959 
00960 
00961 
00963   ConstEdgeIterT() 
00964     : mesh_(0), skip_bits_(0) 
00965   {}
00966 
00967 
00969   ConstEdgeIterT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) 
00970     : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) 
00971   {
00972     if (_skip) enable_skipping();
00973     
00974     // Set halfedge handle invalid if the mesh contains no edge
00975     if(_mesh.n_edges() == 0) hnd_ = value_handle(-1);
00976   }
00977 
00978 
00980   ConstEdgeIterT(const ConstEdgeIterT& _rhs) 
00981     : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_)
00982   {}
00983   
00984 
00986   ConstEdgeIterT& operator=(const ConstEdgeIterT<Mesh>& _rhs) 
00987   {
00988     mesh_      = _rhs.mesh_;
00989     hnd_       = _rhs.hnd_;
00990     skip_bits_ = _rhs.skip_bits_;
00991     return *this;
00992   }
00993 
00994 
00995 #if 1
00996 
00998   ConstEdgeIterT(const EdgeIterT<Mesh>& _rhs) 
00999     : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) 
01000   {}
01001   
01002 
01004   ConstEdgeIterT& operator=(const EdgeIterT<Mesh>& _rhs) 
01005   {
01006     mesh_      = _rhs.mesh_;
01007     hnd_       = _rhs.hnd_;
01008     skip_bits_ = _rhs.skip_bits_;
01009     return *this;
01010   }
01011 
01012 #else
01013   friend class ConstEdgeIterT<Mesh>;
01014 #endif
01015 
01016 
01018   reference operator*()  const { return mesh_->deref(hnd_); }
01019   
01021   pointer   operator->() const { return &(mesh_->deref(hnd_)); }
01022   
01024   value_handle handle() const { return hnd_; }
01025 
01027   operator value_handle() const { return hnd_; }
01028 
01030   bool operator==(const ConstEdgeIterT& _rhs) const 
01031   { return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); }
01032 
01034   bool operator!=(const ConstEdgeIterT& _rhs) const 
01035   { return !operator==(_rhs); }
01036   
01038   ConstEdgeIterT& operator++() 
01039   { hnd_.__increment(); if (skip_bits_) skip_fwd(); return *this; }
01040 
01042   ConstEdgeIterT& operator--() 
01043   { hnd_.__decrement(); if (skip_bits_) skip_bwd(); return *this; }
01044   
01045 
01047   void enable_skipping()
01048   {
01049     if (mesh_ && mesh_->has_edge_status())
01050     {
01051       Attributes::StatusInfo status;
01052       status.set_deleted(true);
01053       status.set_hidden(true);
01054       skip_bits_ = status.bits();
01055       skip_fwd();
01056     }
01057     else skip_bits_ = 0;
01058   }
01059 
01060 
01062   void disable_skipping() { skip_bits_ = 0; }
01063 
01064 
01065 
01066 private:
01067 
01068   void skip_fwd() 
01069   {
01070     assert(mesh_ && skip_bits_);
01071     while ((hnd_.idx() < (signed) mesh_->n_edges()) && 
01072            (mesh_->status(hnd_).bits() & skip_bits_))
01073       hnd_.__increment();
01074   }
01075 
01076 
01077   void skip_bwd() 
01078   {
01079     assert(mesh_ && skip_bits_);
01080     while ((hnd_.idx() >= 0) && 
01081            (mesh_->status(hnd_).bits() & skip_bits_))
01082       hnd_.__decrement();
01083   }
01084 
01085 
01086 
01087 private:
01088   mesh_ptr      mesh_;
01089   value_handle  hnd_;
01090   unsigned int  skip_bits_;
01091 };
01092 
01093 
01094 //== CLASS DEFINITION =========================================================
01095 
01096               
01101 template <class Mesh>
01102 class FaceIterT
01103 {
01104 public:
01105   
01106 
01107   //--- Typedefs ---
01108 
01109   typedef typename Mesh::Face             value_type;
01110   typedef typename Mesh::FaceHandle       value_handle;
01111 
01112 #if 0
01113   typedef std::bidirectional_iterator_tag iterator_category;
01114   typedef std::ptrdiff_t                  difference_type;
01115   typedef const value_type&               reference;
01116   typedef const value_type*               pointer;
01117   typedef const Mesh*                     mesh_ptr;
01118   typedef const Mesh&                     mesh_ref;
01119 #else
01120   typedef std::bidirectional_iterator_tag iterator_category;
01121   typedef std::ptrdiff_t                  difference_type;
01122   typedef value_type&                     reference;
01123   typedef value_type*                     pointer;
01124   typedef Mesh*                           mesh_ptr;
01125   typedef Mesh&                           mesh_ref;
01126 #endif
01127 
01128 
01129 
01130 
01132   FaceIterT() 
01133     : mesh_(0), skip_bits_(0) 
01134   {}
01135 
01136 
01138   FaceIterT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) 
01139     : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) 
01140   {
01141     if (_skip) enable_skipping();
01142     
01143     // Set face handle invalid if the mesh contains no faces
01144     if(_mesh.n_faces() == 0) hnd_ = value_handle(-1);
01145   }
01146 
01147 
01149   FaceIterT(const FaceIterT& _rhs) 
01150     : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_)
01151   {}
01152   
01153 
01155   FaceIterT& operator=(const FaceIterT<Mesh>& _rhs) 
01156   {
01157     mesh_      = _rhs.mesh_;
01158     hnd_       = _rhs.hnd_;
01159     skip_bits_ = _rhs.skip_bits_;
01160     return *this;
01161   }
01162 
01163 
01164 #if 0
01165 
01167   FaceIterT(const FaceIterT<Mesh>& _rhs) 
01168     : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) 
01169   {}
01170   
01171 
01173   FaceIterT& operator=(const FaceIterT<Mesh>& _rhs) 
01174   {
01175     mesh_      = _rhs.mesh_;
01176     hnd_       = _rhs.hnd_;
01177     skip_bits_ = _rhs.skip_bits_;
01178     return *this;
01179   }
01180 
01181 #else
01182   friend class ConstFaceIterT<Mesh>;
01183 #endif
01184 
01185 
01187   reference operator*()  const { return mesh_->deref(hnd_); }
01188   
01190   pointer   operator->() const { return &(mesh_->deref(hnd_)); }
01191   
01193   value_handle handle() const { return hnd_; }
01194 
01196   operator value_handle() const { return hnd_; }
01197 
01199   bool operator==(const FaceIterT& _rhs) const 
01200   { return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); }
01201 
01203   bool operator!=(const FaceIterT& _rhs) const 
01204   { return !operator==(_rhs); }
01205   
01207   FaceIterT& operator++() 
01208   { hnd_.__increment(); if (skip_bits_) skip_fwd(); return *this; }
01209 
01211   FaceIterT& operator--() 
01212   { hnd_.__decrement(); if (skip_bits_) skip_bwd(); return *this; }
01213   
01214 
01216   void enable_skipping()
01217   {
01218     if (mesh_ && mesh_->has_face_status())
01219     {
01220       Attributes::StatusInfo status;
01221       status.set_deleted(true);
01222       status.set_hidden(true);
01223       skip_bits_ = status.bits();
01224       skip_fwd();
01225     }
01226     else skip_bits_ = 0;
01227   }
01228 
01229 
01231   void disable_skipping() { skip_bits_ = 0; }
01232 
01233 
01234 
01235 private:
01236 
01237   void skip_fwd() 
01238   {
01239     assert(mesh_ && skip_bits_);
01240     while ((hnd_.idx() < (signed) mesh_->n_faces()) && 
01241            (mesh_->status(hnd_).bits() & skip_bits_))
01242       hnd_.__increment();
01243   }
01244 
01245 
01246   void skip_bwd() 
01247   {
01248     assert(mesh_ && skip_bits_);
01249     while ((hnd_.idx() >= 0) && 
01250            (mesh_->status(hnd_).bits() & skip_bits_))
01251       hnd_.__decrement();
01252   }
01253 
01254 
01255 
01256 private:
01257   mesh_ptr      mesh_;
01258   value_handle  hnd_;
01259   unsigned int  skip_bits_;
01260 };
01261 
01262 
01263 //== CLASS DEFINITION =========================================================
01264 
01265               
01270 template <class Mesh>
01271 class ConstFaceIterT
01272 {
01273 public:
01274   
01275 
01276   //--- Typedefs ---
01277 
01278   typedef typename Mesh::Face             value_type;
01279   typedef typename Mesh::FaceHandle       value_handle;
01280 
01281 #if 1
01282   typedef std::bidirectional_iterator_tag iterator_category;
01283   typedef std::ptrdiff_t                  difference_type;
01284   typedef const value_type&               reference;
01285   typedef const value_type*               pointer;
01286   typedef const Mesh*                     mesh_ptr;
01287   typedef const Mesh&                     mesh_ref;
01288 #else
01289   typedef std::bidirectional_iterator_tag iterator_category;
01290   typedef std::ptrdiff_t                  difference_type;
01291   typedef value_type&                     reference;
01292   typedef value_type*                     pointer;
01293   typedef Mesh*                           mesh_ptr;
01294   typedef Mesh&                           mesh_ref;
01295 #endif
01296 
01297 
01298 
01299 
01301   ConstFaceIterT() 
01302     : mesh_(0), skip_bits_(0) 
01303   {}
01304 
01305 
01307   ConstFaceIterT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) 
01308     : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) 
01309   {
01310     if (_skip) enable_skipping();
01311     
01312     // Set face handle invalid if the mesh contains no faces
01313     if(_mesh.n_faces() == 0) hnd_ = value_handle(-1);
01314   }
01315 
01316 
01318   ConstFaceIterT(const ConstFaceIterT& _rhs) 
01319     : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_)
01320   {}
01321   
01322 
01324   ConstFaceIterT& operator=(const ConstFaceIterT<Mesh>& _rhs) 
01325   {
01326     mesh_      = _rhs.mesh_;
01327     hnd_       = _rhs.hnd_;
01328     skip_bits_ = _rhs.skip_bits_;
01329     return *this;
01330   }
01331 
01332 
01333 #if 1
01334 
01336   ConstFaceIterT(const FaceIterT<Mesh>& _rhs) 
01337     : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) 
01338   {}
01339   
01340 
01342   ConstFaceIterT& operator=(const FaceIterT<Mesh>& _rhs) 
01343   {
01344     mesh_      = _rhs.mesh_;
01345     hnd_       = _rhs.hnd_;
01346     skip_bits_ = _rhs.skip_bits_;
01347     return *this;
01348   }
01349 
01350 #else
01351   friend class ConstFaceIterT<Mesh>;
01352 #endif
01353 
01354 
01356   reference operator*()  const { return mesh_->deref(hnd_); }
01357   
01359   pointer   operator->() const { return &(mesh_->deref(hnd_)); }
01360   
01362   value_handle handle() const { return hnd_; }
01363 
01365   operator value_handle() const { return hnd_; }
01366 
01368   bool operator==(const ConstFaceIterT& _rhs) const 
01369   { return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); }
01370 
01372   bool operator!=(const ConstFaceIterT& _rhs) const 
01373   { return !operator==(_rhs); }
01374   
01376   ConstFaceIterT& operator++() 
01377   { hnd_.__increment(); if (skip_bits_) skip_fwd(); return *this; }
01378 
01380   ConstFaceIterT& operator--() 
01381   { hnd_.__decrement(); if (skip_bits_) skip_bwd(); return *this; }
01382   
01383 
01385   void enable_skipping()
01386   {
01387     if (mesh_ && mesh_->has_face_status())
01388     {
01389       Attributes::StatusInfo status;
01390       status.set_deleted(true);
01391       status.set_hidden(true);
01392       skip_bits_ = status.bits();
01393       skip_fwd();
01394     }
01395     else skip_bits_ = 0;
01396   }
01397 
01398 
01400   void disable_skipping() { skip_bits_ = 0; }
01401 
01402 
01403 
01404 private:
01405 
01406   void skip_fwd() 
01407   {
01408     assert(mesh_ && skip_bits_);
01409     while ((hnd_.idx() < (signed) mesh_->n_faces()) && 
01410            (mesh_->status(hnd_).bits() & skip_bits_))
01411       hnd_.__increment();
01412   }
01413 
01414 
01415   void skip_bwd() 
01416   {
01417     assert(mesh_ && skip_bits_);
01418     while ((hnd_.idx() >= 0) && 
01419            (mesh_->status(hnd_).bits() & skip_bits_))
01420       hnd_.__decrement();
01421   }
01422 
01423 
01424 
01425 private:
01426   mesh_ptr      mesh_;
01427   value_handle  hnd_;
01428   unsigned int  skip_bits_;
01429 };
01430 
01431 
01432 //=============================================================================
01433 } // namespace Iterators
01434 } // namespace OpenMesh
01435 //=============================================================================
01436 #endif 
01437 //=============================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines