OpenMesh
|
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 //=============================================================================