OpenMesh
CirculatorsT.hh
1 /* ========================================================================= *
2  * *
3  * OpenMesh *
4  * Copyright (c) 2001-2022, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openmesh.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenMesh. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40  * ========================================================================= */
41 
42 
43 #pragma once
44 
45 //=============================================================================
46 //
47 // Vertex and Face circulators for PolyMesh/TriMesh
48 //
49 //=============================================================================
50 
51 
52 
53 //== INCLUDES =================================================================
54 
55 #include <OpenMesh/Core/System/config.h>
56 #include <cassert>
57 #include <cstddef>
58 #include <iterator>
59 
60 //== NAMESPACES ===============================================================
61 
62 namespace OpenMesh {
63 
64 template <typename> class CirculatorRange;
65 
66 namespace Iterators {
67 
68 template<class Mesh, class CenterEntityHandle, bool CW>
70  public:
71  static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter);
72  static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter);
73 };
74 
75 template<class Mesh>
77  public:
78  inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
79  heh = mesh->cw_rotated_halfedge_handle(heh);
80  if (heh == start) ++lap_counter;
81  }
82  inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
83  if (heh == start) --lap_counter;
84  heh = mesh->ccw_rotated_halfedge_handle(heh);
85  }
86 };
87 
88 template<class Mesh>
90  public:
91  inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
92  heh = mesh->next_halfedge_handle(heh);
93  if (heh == start) ++lap_counter;
94  }
95  inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
96  if (heh == start) --lap_counter;
97  heh = mesh->prev_halfedge_handle(heh);
98  }
99 };
100 
102 // CCW
103 
104 template<class Mesh>
106  public:
107  inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
108  heh = mesh->ccw_rotated_halfedge_handle(heh);
109  if (heh == start) ++lap_counter;
110  }
111  inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
112  if (heh == start) --lap_counter;
113  heh = mesh->cw_rotated_halfedge_handle(heh);
114  }
115 };
116 
117 template<class Mesh>
119  public:
120  inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
121  heh = mesh->prev_halfedge_handle(heh);
122  if (heh == start) ++lap_counter;
123  }
124  inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
125  if (heh == start) --lap_counter;
126  heh = mesh->next_halfedge_handle(heh);
127  }
128 };
130 
131 template<class Mesh, class CenterEntityHandle, class ValueHandle>
133  public:
134  //inline static bool isDereferenciable(const Mesh *mesh, const typename Mesh::HalfedgeHandle &heh, const typename Mesh::HalfedgeHandle &start, const int &lap_counter);
135 };
136 
137 template<class Mesh>
139  public:
140  inline static bool isDereferenciable(const Mesh *mesh, const typename Mesh::HalfedgeHandle &heh) {
141  return mesh->face_handle(mesh->opposite_halfedge_handle(heh)).is_valid();
142  }
143 };
144 
145 template<class Mesh>
147  public:
148  inline static bool isDereferenciable(const Mesh *mesh, const typename Mesh::HalfedgeHandle &heh) {
149  return mesh->face_handle(heh).is_valid();
150  }
151 };
152 
153 template<class Mesh, class CenterEntityHandle, class ValueHandle, bool CW = true>
155  public:
156  inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const int lap_counter) {
157  return ( heh.is_valid() && (lap_counter == 0 ) );
158  }
159  inline static void init(const Mesh* mesh, typename Mesh::HalfedgeHandle& heh, typename Mesh::HalfedgeHandle& start, int& lap_counter, bool adjust_for_ccw)
160  {
161  if (!CW) // TODO: constexpr if
162  {
163  if (adjust_for_ccw)
164  {
165  // increment current heh and start so that cw and ccw version dont start with the same element but ranges are actually reversed
166  int lc = lap_counter;
167  increment(mesh, heh, start, lap_counter);
168  start = heh;
169  lap_counter = lc;
170  }
171  }
172  }
173 
174  inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
176  }
177  inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
179  }
180 };
181 
182 template<class Mesh, class CenterEntityHandle, bool CW>
183 class GenericCirculator_ValueHandleFnsT<Mesh, CenterEntityHandle, typename Mesh::FaceHandle, CW> {
184  public:
186 
187  inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const int lap_counter) {
188  return ( heh.is_valid() && (lap_counter == 0));
189  }
190  inline static void init(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter, bool adjust_for_ccw)
191  {
192  if (!CW) // TODO: constexpr if
193  {
194  if (adjust_for_ccw)
195  {
196  // increment current heh and start so that cw and ccw version dont start with the same element but ranges are actually reversed
197  int lc = lap_counter;
198  increment(mesh, heh, start, lap_counter);
199  start = heh;
200  lap_counter = lc;
201  }
202  }
203  if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
204  increment(mesh, heh, start, lap_counter);
205  };
206  inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
207  do {
209  } while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
210  }
211  inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
212  do {
214  } while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
215  }
216 };
217 
218 template<class Mesh>
220  public:
221  typedef const Mesh* mesh_ptr;
222  typedef const Mesh& mesh_ref;
223 
224  template <typename> friend class OpenMesh::CirculatorRange;
225 
226  public:
227  GenericCirculatorBaseT() : mesh_(0), lap_counter_(0) {}
228 
229  GenericCirculatorBaseT(mesh_ref mesh, typename Mesh::HalfedgeHandle heh, bool end = false) :
230  mesh_(&mesh), start_(heh), heh_(heh), lap_counter_(static_cast<int>(end && heh.is_valid())) {}
231 
233  mesh_(rhs.mesh_), start_(rhs.start_), heh_(rhs.heh_), lap_counter_(rhs.lap_counter_) {}
234 
235  inline typename Mesh::FaceHandle toFaceHandle() const {
236  return mesh_->face_handle(heh_);
237  }
238 
239  inline typename Mesh::FaceHandle toOppositeFaceHandle() const {
240  return mesh_->face_handle(toOppositeHalfedgeHandle());
241  }
242 
243  inline typename Mesh::EdgeHandle toEdgeHandle() const {
244  return mesh_->edge_handle(heh_);
245  }
246 
247  inline typename Mesh::HalfedgeHandle toHalfedgeHandle() const {
248  return heh_;
249  }
250 
251  inline typename Mesh::HalfedgeHandle toOppositeHalfedgeHandle() const {
252  return mesh_->opposite_halfedge_handle(heh_);
253  }
254 
255  inline typename Mesh::VertexHandle toVertexHandle() const {
256  return mesh_->to_vertex_handle(heh_);
257  }
258 
259  inline GenericCirculatorBaseT &operator=(const GenericCirculatorBaseT &rhs) {
260  mesh_ = rhs.mesh_;
261  start_ = rhs.start_;
262  heh_ = rhs.heh_;
263  lap_counter_ = rhs.lap_counter_;
264  return *this;
265  }
266 
267  inline bool operator==(const GenericCirculatorBaseT &rhs) const {
268  return mesh_ == rhs.mesh_ && start_ == rhs.start_ && heh_ == rhs.heh_ && lap_counter_ == rhs.lap_counter_;
269  }
270 
271  inline bool operator!=(const GenericCirculatorBaseT &rhs) const {
272  return !operator==(rhs);
273  }
274 
275  protected:
276  mesh_ptr mesh_;
277  typename Mesh::HalfedgeHandle start_, heh_;
278  int lap_counter_;
279 };
280 
281 //template<class Mesh, class CenterEntityHandle, class ValueHandle,
282 // ValueHandle (GenericCirculatorBaseT<Mesh>::*Handle2Value)() const, bool CW = true >
283 template <typename GenericCirculatorT_TraitsT, bool CW = true>
284 class GenericCirculatorT : protected GenericCirculatorBaseT<typename GenericCirculatorT_TraitsT::Mesh> {
285  public:
286  using Mesh = typename GenericCirculatorT_TraitsT::Mesh;
287  using value_type = typename GenericCirculatorT_TraitsT::ValueHandle;
288  using CenterEntityHandle = typename GenericCirculatorT_TraitsT::CenterEntityHandle;
289 
290  using smart_value_type = decltype(make_smart(std::declval<value_type>(), std::declval<Mesh>()));
291 
292  typedef std::ptrdiff_t difference_type;
293  typedef const value_type& reference;
294  typedef const smart_value_type* pointer;
295  typedef std::bidirectional_iterator_tag iterator_category;
296 
300 
301  template <typename> friend class OpenMesh::CirculatorRange;
302 
303  public:
304  GenericCirculatorT() {}
305  GenericCirculatorT(mesh_ref mesh, CenterEntityHandle start, bool end = false) :
306  GenericCirculatorBaseT<Mesh>(mesh, mesh.halfedge_handle(start), end)
307  {
308  bool adjust_for_ccw = true;
309  GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_, adjust_for_ccw);
310  }
311  GenericCirculatorT(mesh_ref mesh, typename Mesh::HalfedgeHandle heh, bool end = false) :
312  GenericCirculatorBaseT<Mesh>(mesh, heh, end)
313  {
314  bool adjust_for_ccw = false; // if iterator is initialized with specific heh, we want to start there
315  GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_, adjust_for_ccw);
316  }
318 
319  friend class GenericCirculatorT<GenericCirculatorT_TraitsT,!CW>;
322 
323  GenericCirculatorT& operator++() {
324  assert(this->mesh_);
325  GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
326  return *this;
327  }
328  GenericCirculatorT& operator--() {
329  assert(this->mesh_);
330  GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
331  return *this;
332  }
333 
336  assert(this->mesh_);
337  GenericCirculatorT cpy(*this);
338  ++(*this);
339  return cpy;
340  }
341 
344  assert(this->mesh_);
345  GenericCirculatorT cpy(*this);
346  --(*this);
347  return cpy;
348  }
349 
351  smart_value_type operator*() const {
352 #ifndef NDEBUG
353  assert(this->heh_.is_valid());
354  value_type res = GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_);
355  assert(res.is_valid());
356  return make_smart(res, this->mesh_);
357 #else
358  return make_smart(GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_);
359 #endif
360  }
361 
370  pointer operator->() const {
371  pointer_deref_value = **this;
372  return &pointer_deref_value;
373  }
374 
375  GenericCirculatorT &operator=(const GenericCirculatorT &rhs) {
377  return *this;
378  };
379 
380  bool operator==(const GenericCirculatorT &rhs) const {
381  return GenericCirculatorBaseT<Mesh>::operator==(rhs);
382  }
383 
384  bool operator!=(const GenericCirculatorT &rhs) const {
385  return GenericCirculatorBaseT<Mesh>::operator!=(rhs);
386  }
387 
388  bool is_valid() const {
389  return GenericCirculator_ValueHandleFns::is_valid(this->heh_, this->lap_counter_);
390  }
391 
392  template<typename STREAM>
393  friend STREAM &operator<< (STREAM &s, const GenericCirculatorT &self) {
394  return s << self.mesh_ << ", " << self.start_.idx() << ", " << self.heh_.idx() << ", " << self.lap_counter_;
395  }
396 
397  private:
398  mutable smart_value_type pointer_deref_value;
399 };
400 
405 // OLD CIRCULATORS
406 // deprecated circulators, will be removed soon
407 // if you remove these circulators and go to the old ones, PLEASE ENABLE FOLLOWING UNITTESTS:
408 //
409 // OpenMeshTrimeshCirculatorVertexIHalfEdge.VertexIHalfEdgeIterCheckInvalidationAtEnds
410 // OpenMeshTrimeshCirculatorVertexEdge.VertexEdgeIterCheckInvalidationAtEnds
411 // OpenMeshTrimeshCirculatorVertexVertex.VertexVertexIterCheckInvalidationAtEnds
412 // OpenMeshTrimeshCirculatorVertexOHalfEdge.VertexOHalfEdgeIterCheckInvalidationAtEnds
413 // OpenMeshTrimeshCirculatorVertexFace.VertexFaceIterCheckInvalidationAtEnds
414 // OpenMeshTrimeshCirculatorVertexFace.VertexFaceIterWithoutHolesDecrement
415 // OpenMeshTrimeshCirculatorFaceEdge.FaceEdgeIterCheckInvalidationAtEnds
416 // OpenMeshTrimeshCirculatorFaceFace.FaceFaceIterCheckInvalidationAtEnds
417 // OpenMeshTrimeshCirculatorFaceHalfEdge.FaceHalfedgeIterWithoutHolesIncrement
418 // OpenMeshTrimeshCirculatorFaceVertex.FaceVertexIterCheckInvalidationAtEnds
419 // OpenMeshTrimeshCirculatorFaceHalfEdge.FaceHalfedgeIterCheckInvalidationAtEnds
420 //
421 
422 template<class Mesh, class CenterEntityHandle, class ValueHandle>
424  public:
425  inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh,const typename Mesh::HalfedgeHandle &start, const int lap_counter) {
426  return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 )) );
427  }
428  inline static void init(const Mesh*, typename Mesh::HalfedgeHandle&, typename Mesh::HalfedgeHandle&, int&) {};
429  inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
431  }
432  inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
434  }
435 };
436 
437 template<class Mesh, class CenterEntityHandle>
438 class GenericCirculator_ValueHandleFnsT_DEPRECATED<Mesh, CenterEntityHandle, typename Mesh::FaceHandle> {
439  public:
441 
442  inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const typename Mesh::HalfedgeHandle &start, const int lap_counter) {
443  return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 )));
444  }
445  inline static void init(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
446  if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
447  increment(mesh, heh, start, lap_counter);
448  };
449  inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
450  do {
452  } while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
453  }
454  inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
455  do {
457  } while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
458  }
459 };
460 
461 template <typename GenericCirculatorT_DEPRECATED_TraitsT>
462 class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<typename GenericCirculatorT_DEPRECATED_TraitsT::Mesh> {
463  public:
464  using Mesh = typename GenericCirculatorT_DEPRECATED_TraitsT::Mesh;
465  using CenterEntityHandle = typename GenericCirculatorT_DEPRECATED_TraitsT::CenterEntityHandle;
466  using value_type = typename GenericCirculatorT_DEPRECATED_TraitsT::ValueHandle;
467  using smart_value_type = decltype (make_smart(std::declval<value_type>(), std::declval<Mesh>()));
468 
469  typedef std::ptrdiff_t difference_type;
470  typedef const value_type& reference;
471  typedef const smart_value_type* pointer;
472  typedef std::bidirectional_iterator_tag iterator_category;
473 
477 
478  template <typename> friend class OpenMesh::CirculatorRange;
479 
480  public:
482  GenericCirculatorT_DEPRECATED(mesh_ref mesh, CenterEntityHandle start, bool end = false) :
483  GenericCirculatorBaseT<Mesh>(mesh, mesh.halfedge_handle(start), end) {
484 
485  GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
486  }
487  GenericCirculatorT_DEPRECATED(mesh_ref mesh, typename Mesh::HalfedgeHandle heh, bool end = false) :
488  GenericCirculatorBaseT<Mesh>(mesh, heh, end) {
489 
490  GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
491  }
493 
494  GenericCirculatorT_DEPRECATED& operator++() {
495  assert(this->mesh_);
496  GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
497  return *this;
498  }
499 #ifndef NO_DECREMENT_DEPRECATED_WARNINGS
500 #define DECREMENT_DEPRECATED_WARNINGS_TEXT "The current decrement operator has the unintended behavior that it stays\
501  valid when iterating below the start and will visit the first entity\
502  twice before getting invalid. Furthermore it gets valid again, if you\
503  increment at the end.\
504  When you are sure that you don't iterate below the start anywhere in\
505  your code or rely on this behaviour, you can disable this warning by\
506  setting the define NO_DECREMENT_DEPRECATED_WARNINGS at the command line (or enable it via the\
507  cmake flags).\
508  To be save, you can use the CW/CCW circulator definitions, which behave\
509  the same as the original ones, without the previously mentioned issues."
510 
511  OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
512 #endif // NO_DECREMENT_DEPRECATED_WARNINGS
513  GenericCirculatorT_DEPRECATED& operator--() {
514  assert(this->mesh_);
515  GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
516  return *this;
517  }
518 
521  assert(this->mesh_);
523  ++(*this);
524  return cpy;
525  }
526 
528 #ifndef NO_DECREMENT_DEPRECATED_WARNINGS
529  OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
530 #undef DECREMENT_DEPRECATED_WARNINGS_TEXT
531 #endif //NO_DECREMENT_DEPRECATED_WARNINGS
533  assert(this->mesh_);
535  --(*this);
536  return cpy;
537  }
538 
540  smart_value_type operator*() const {
541 #ifndef NDEBUG
542  assert(this->heh_.is_valid());
543  value_type res = (GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_));
544  assert(res.is_valid());
545  return make_smart(res, this->mesh_);
546 #else
547  return make_smart(GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_);
548 #endif
549  }
550 
559  pointer operator->() const {
560  pointer_deref_value = **this;
561  return &pointer_deref_value;
562  }
563 
566  return *this;
567  };
568 
569  bool operator==(const GenericCirculatorT_DEPRECATED &rhs) const {
570  return GenericCirculatorBaseT<Mesh>::operator==(rhs);
571  }
572 
573  bool operator!=(const GenericCirculatorT_DEPRECATED &rhs) const {
574  return GenericCirculatorBaseT<Mesh>::operator!=(rhs);
575  }
576 
577  bool is_valid() const {
578  return GenericCirculator_ValueHandleFns::is_valid(this->heh_,this->start_, this->lap_counter_);
579  }
580 
581  OM_DEPRECATED("current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.")
587  const typename Mesh::HalfedgeHandle &current_halfedge_handle() const {
588  return this->heh_;
589  }
590 
591  OM_DEPRECATED("Do not use this error prone implicit cast. Compare to end-iterator or use is_valid(), instead.")
597  operator bool() const {
598  return is_valid();
599  }
600 
606  OM_DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.")
607  smart_value_type handle() const {
608  return **this;
609  }
610 
617  OM_DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
618  operator value_type() const {
619  return **this;
620  }
621 
622  template<typename STREAM>
623  friend STREAM &operator<< (STREAM &s, const GenericCirculatorT_DEPRECATED &self) {
624  return s << self.mesh_ << ", " << self.start_.idx() << ", " << self.heh_.idx() << ", " << self.lap_counter_;
625  }
626 
627  private:
628  mutable smart_value_type pointer_deref_value;
629 };
630 
631 } // namespace Iterators
632 } // namespace OpenMesh
633 
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:59
SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity *_mesh)
Creats a SmartVertexHandle from a VertexHandle and a Mesh.
Definition: SmartHandles.hh:256
auto operator<<(std::ostream &os, const VectorT< Scalar, DIM > &_vec) -> typename std::enable_if< sizeof(decltype(os<< _vec[0])) >=0
output a vector by printing its space-separated compontens
Generic class for iterator ranges.
Definition: PolyConnectivity_inline_impl.hh:92
Definition: CirculatorsT.hh:219
Definition: CirculatorsT.hh:284
smart_value_type operator*() const
Standard dereferencing operator.
Definition: CirculatorsT.hh:351
GenericCirculatorT operator++(int)
Post-increment.
Definition: CirculatorsT.hh:335
GenericCirculatorT operator--(int)
Post-decrement.
Definition: CirculatorsT.hh:343
pointer operator->() const
Pointer dereferentiation.
Definition: CirculatorsT.hh:370
const Mesh::HalfedgeHandle & current_halfedge_handle() const
Definition: CirculatorsT.hh:587
GenericCirculatorT_DEPRECATED operator++(int)
Post-increment.
Definition: CirculatorsT.hh:520
pointer operator->() const
Pointer dereferentiation.
Definition: CirculatorsT.hh:559
GenericCirculatorT_DEPRECATED operator--(int)
Post-decrement.
Definition: CirculatorsT.hh:532
smart_value_type operator*() const
Standard dereferencing operator.
Definition: CirculatorsT.hh:540
smart_value_type handle() const
Return the handle of the current target.
Definition: CirculatorsT.hh:607
Handle for a vertex entity.
Definition: Handles.hh:121
Handle for a halfedge entity.
Definition: Handles.hh:128
Handle for a face entity.
Definition: Handles.hh:142
Polygonal mesh based on the ArrayKernel.
Definition: PolyMesh_ArrayKernelT.hh:96
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:136
Kernel::EdgeHandle EdgeHandle
Scalar type.
Definition: PolyMeshT.hh:138
Kernel::FaceHandle FaceHandle
Scalar type.
Definition: PolyMeshT.hh:139
Kernel::HalfedgeHandle HalfedgeHandle
Scalar type.
Definition: PolyMeshT.hh:137

Project OpenMesh, ©  Visual Computing Institute, RWTH Aachen. Documentation generated using doxygen .