Developer Documentation
CirculatorsT.hh
1 /* ========================================================================= *
2  * *
3  * OpenMesh *
4  * Copyright (c) 2001-2015, 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 
56 #include <cassert>
57 #include <cstddef>
58 #include <iterator>
59 
60 //== NAMESPACES ===============================================================
61 
62 namespace OpenMesh {
63 namespace Iterators {
64 
65 template<class Mesh, class CenterEntityHandle, bool CW>
67  public:
68  static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter);
69  static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter);
70 };
71 
72 template<class Mesh>
74  public:
75  inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
76  heh = mesh->cw_rotated_halfedge_handle(heh);
77  if (heh == start) ++lap_counter;
78  }
79  inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
80  if (heh == start) --lap_counter;
81  heh = mesh->ccw_rotated_halfedge_handle(heh);
82  }
83 };
84 
85 template<class Mesh>
87  public:
88  inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
89  heh = mesh->next_halfedge_handle(heh);
90  if (heh == start) ++lap_counter;
91  }
92  inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
93  if (heh == start) --lap_counter;
94  heh = mesh->prev_halfedge_handle(heh);
95  }
96 };
97 
99 // CCW
100 
101 template<class Mesh>
103  public:
104  inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
105  heh = mesh->ccw_rotated_halfedge_handle(heh);
106  if (heh == start) ++lap_counter;
107  }
108  inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
109  if (heh == start) --lap_counter;
110  heh = mesh->cw_rotated_halfedge_handle(heh);
111  }
112 };
113 
114 template<class Mesh>
116  public:
117  inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
118  heh = mesh->prev_halfedge_handle(heh);
119  if (heh == start) ++lap_counter;
120  }
121  inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
122  if (heh == start) --lap_counter;
123  heh = mesh->next_halfedge_handle(heh);
124  }
125 };
127 
128 template<class Mesh, class CenterEntityHandle, class ValueHandle>
130  public:
131  //inline static bool isDereferenciable(const Mesh *mesh, const typename Mesh::HalfedgeHandle &heh, const typename Mesh::HalfedgeHandle &start, const int &lap_counter);
132 };
133 
134 template<class Mesh>
135 class GenericCirculator_DereferenciabilityCheckT<Mesh, typename Mesh::FaceHandle, typename Mesh::FaceHandle> {
136  public:
137  inline static bool isDereferenciable(const Mesh *mesh, const typename Mesh::HalfedgeHandle &heh) {
138  return mesh->face_handle(mesh->opposite_halfedge_handle(heh)).is_valid();
139  }
140 };
141 
142 template<class Mesh>
143 class GenericCirculator_DereferenciabilityCheckT<Mesh, typename Mesh::VertexHandle, typename Mesh::FaceHandle> {
144  public:
145  inline static bool isDereferenciable(const Mesh *mesh, const typename Mesh::HalfedgeHandle &heh) {
146  return mesh->face_handle(heh).is_valid();
147  }
148 };
149 
150 template<class Mesh, class CenterEntityHandle, class ValueHandle, bool CW = true>
152  public:
153  inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const int lap_counter) {
154  return ( heh.is_valid() && (lap_counter == 0 ) );
155  }
156  inline static void init(const Mesh*, typename Mesh::HalfedgeHandle&, typename Mesh::HalfedgeHandle&, int&) {};
157  inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
159  }
160  inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
162  }
163 };
164 
165 template<class Mesh, class CenterEntityHandle, bool CW>
166 class GenericCirculator_ValueHandleFnsT<Mesh, CenterEntityHandle, typename Mesh::FaceHandle, CW> {
167  public:
169 
170  inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const int lap_counter) {
171  return ( heh.is_valid() && (lap_counter == 0));
172  }
173  inline static void init(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
174  if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
175  increment(mesh, heh, start, lap_counter);
176  };
177  inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
178  do {
180  } while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
181  }
182  inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
183  do {
185  } while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
186  }
187 };
188 
189 template<class Mesh>
191  public:
192  typedef const Mesh* mesh_ptr;
193  typedef const Mesh& mesh_ref;
194 
195  public:
196  GenericCirculatorBaseT() : mesh_(0), lap_counter_(0) {}
197 
198  GenericCirculatorBaseT(mesh_ref mesh, typename Mesh::HalfedgeHandle heh, bool end = false) :
199  mesh_(&mesh), start_(heh), heh_(heh), lap_counter_(static_cast<int>(end && heh.is_valid())) {}
200 
202  mesh_(rhs.mesh_), start_(rhs.start_), heh_(rhs.heh_), lap_counter_(rhs.lap_counter_) {}
203 
204  inline typename Mesh::FaceHandle toFaceHandle() const {
205  return mesh_->face_handle(heh_);
206  }
207 
208  inline typename Mesh::FaceHandle toOppositeFaceHandle() const {
209  return mesh_->face_handle(toOppositeHalfedgeHandle());
210  }
211 
212  inline typename Mesh::EdgeHandle toEdgeHandle() const {
213  return mesh_->edge_handle(heh_);
214  }
215 
216  inline typename Mesh::HalfedgeHandle toHalfedgeHandle() const {
217  return heh_;
218  }
219 
220  inline typename Mesh::HalfedgeHandle toOppositeHalfedgeHandle() const {
221  return mesh_->opposite_halfedge_handle(heh_);
222  }
223 
224  inline typename Mesh::VertexHandle toVertexHandle() const {
225  return mesh_->to_vertex_handle(heh_);
226  }
227 
228  inline GenericCirculatorBaseT &operator=(const GenericCirculatorBaseT &rhs) {
229  mesh_ = rhs.mesh_;
230  start_ = rhs.start_;
231  heh_ = rhs.heh_;
232  lap_counter_ = rhs.lap_counter_;
233  return *this;
234  }
235 
236  inline bool operator==(const GenericCirculatorBaseT &rhs) const {
237  return mesh_ == rhs.mesh_ && start_ == rhs.start_ && heh_ == rhs.heh_ && lap_counter_ == rhs.lap_counter_;
238  }
239 
240  inline bool operator!=(const GenericCirculatorBaseT &rhs) const {
241  return !operator==(rhs);
242  }
243 
244  protected:
245  mesh_ptr mesh_;
246  typename Mesh::HalfedgeHandle start_, heh_;
247  int lap_counter_;
248 };
249 
250 //template<class Mesh, class CenterEntityHandle, class ValueHandle,
251 // ValueHandle (GenericCirculatorBaseT<Mesh>::*Handle2Value)() const, bool CW = true >
252 template <typename GenericCirculatorT_TraitsT, bool CW = true>
253 class GenericCirculatorT : protected GenericCirculatorBaseT<typename GenericCirculatorT_TraitsT::Mesh> {
254  public:
255  using Mesh = typename GenericCirculatorT_TraitsT::Mesh;
256  using value_type = typename GenericCirculatorT_TraitsT::ValueHandle;
257  using CenterEntityHandle = typename GenericCirculatorT_TraitsT::CenterEntityHandle;
258 
259  using smart_value_type = decltype(make_smart(std::declval<value_type>(), std::declval<Mesh>()));
260 
261  typedef std::ptrdiff_t difference_type;
262  typedef const value_type& reference;
263  typedef const smart_value_type* pointer;
264  typedef std::bidirectional_iterator_tag iterator_category;
265 
269 
270  public:
271  GenericCirculatorT() {}
272  GenericCirculatorT(mesh_ref mesh, CenterEntityHandle start, bool end = false) :
273  GenericCirculatorBaseT<Mesh>(mesh, mesh.halfedge_handle(start), end) {
274 
275  GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
276  }
277  GenericCirculatorT(mesh_ref mesh, typename Mesh::HalfedgeHandle heh, bool end = false) :
278  GenericCirculatorBaseT<Mesh>(mesh, heh, end) {
279 
280  GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
281  }
283 
284  friend class GenericCirculatorT<GenericCirculatorT_TraitsT,!CW>;
287 
288  GenericCirculatorT& operator++() {
289  assert(this->mesh_);
290  GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
291  return *this;
292  }
293  GenericCirculatorT& operator--() {
294  assert(this->mesh_);
295  GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
296  return *this;
297  }
298 
300  GenericCirculatorT operator++(int) {
301  assert(this->mesh_);
302  GenericCirculatorT cpy(*this);
303  ++(*this);
304  return cpy;
305  }
306 
308  GenericCirculatorT operator--(int) {
309  assert(this->mesh_);
310  GenericCirculatorT cpy(*this);
311  --(*this);
312  return cpy;
313  }
314 
316  smart_value_type operator*() const {
317 #ifndef NDEBUG
318  assert(this->heh_.is_valid());
319  value_type res = GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_);
320  assert(res.is_valid());
321  return make_smart(res, this->mesh_);
322 #else
323  return make_smart(GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_);
324 #endif
325  }
326 
335  pointer operator->() const {
336  pointer_deref_value = **this;
337  return &pointer_deref_value;
338  }
339 
340  GenericCirculatorT &operator=(const GenericCirculatorT &rhs) {
342  return *this;
343  };
344 
345  bool operator==(const GenericCirculatorT &rhs) const {
347  }
348 
349  bool operator!=(const GenericCirculatorT &rhs) const {
351  }
352 
353  bool is_valid() const {
354  return GenericCirculator_ValueHandleFns::is_valid(this->heh_, this->lap_counter_);
355  }
356 
357  template<typename STREAM>
358  friend STREAM &operator<< (STREAM &s, const GenericCirculatorT &self) {
359  return s << self.mesh_ << ", " << self.start_.idx() << ", " << self.heh_.idx() << ", " << self.lap_counter_;
360  }
361 
362  private:
363  mutable smart_value_type pointer_deref_value;
364 };
365 
370 // OLD CIRCULATORS
371 // deprecated circulators, will be removed soon
372 // if you remove these circulators and go to the old ones, PLEASE ENABLE FOLLOWING UNITTESTS:
373 //
374 // OpenMeshTrimeshCirculatorVertexIHalfEdge.VertexIHalfEdgeIterCheckInvalidationAtEnds
375 // OpenMeshTrimeshCirculatorVertexEdge.VertexEdgeIterCheckInvalidationAtEnds
376 // OpenMeshTrimeshCirculatorVertexVertex.VertexVertexIterCheckInvalidationAtEnds
377 // OpenMeshTrimeshCirculatorVertexOHalfEdge.VertexOHalfEdgeIterCheckInvalidationAtEnds
378 // OpenMeshTrimeshCirculatorVertexFace.VertexFaceIterCheckInvalidationAtEnds
379 // OpenMeshTrimeshCirculatorVertexFace.VertexFaceIterWithoutHolesDecrement
380 // OpenMeshTrimeshCirculatorFaceEdge.FaceEdgeIterCheckInvalidationAtEnds
381 // OpenMeshTrimeshCirculatorFaceFace.FaceFaceIterCheckInvalidationAtEnds
382 // OpenMeshTrimeshCirculatorFaceHalfEdge.FaceHalfedgeIterWithoutHolesIncrement
383 // OpenMeshTrimeshCirculatorFaceVertex.FaceVertexIterCheckInvalidationAtEnds
384 // OpenMeshTrimeshCirculatorFaceHalfEdge.FaceHalfedgeIterCheckInvalidationAtEnds
385 //
386 
387 template<class Mesh, class CenterEntityHandle, class ValueHandle>
389  public:
390  inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh,const typename Mesh::HalfedgeHandle &start, const int lap_counter) {
391  return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 )) );
392  }
393  inline static void init(const Mesh*, typename Mesh::HalfedgeHandle&, typename Mesh::HalfedgeHandle&, int&) {};
394  inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
396  }
397  inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
399  }
400 };
401 
402 template<class Mesh, class CenterEntityHandle>
403 class GenericCirculator_ValueHandleFnsT_DEPRECATED<Mesh, CenterEntityHandle, typename Mesh::FaceHandle> {
404  public:
406 
407  inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const typename Mesh::HalfedgeHandle &start, const int lap_counter) {
408  return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 )));
409  }
410  inline static void init(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
411  if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
412  increment(mesh, heh, start, lap_counter);
413  };
414  inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
415  do {
417  } while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
418  }
419  inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
420  do {
422  } while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
423  }
424 };
425 
426 template <typename GenericCirculatorT_DEPRECATED_TraitsT>
427 class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<typename GenericCirculatorT_DEPRECATED_TraitsT::Mesh> {
428  public:
429  using Mesh = typename GenericCirculatorT_DEPRECATED_TraitsT::Mesh;
430  using CenterEntityHandle = typename GenericCirculatorT_DEPRECATED_TraitsT::CenterEntityHandle;
431  using value_type = typename GenericCirculatorT_DEPRECATED_TraitsT::ValueHandle;
432  using smart_value_type = decltype (make_smart(std::declval<value_type>(), std::declval<Mesh>()));
433 
434  typedef std::ptrdiff_t difference_type;
435  typedef const value_type& reference;
436  typedef const smart_value_type* pointer;
437  typedef std::bidirectional_iterator_tag iterator_category;
438 
442 
443  public:
445  GenericCirculatorT_DEPRECATED(mesh_ref mesh, CenterEntityHandle start, bool end = false) :
446  GenericCirculatorBaseT<Mesh>(mesh, mesh.halfedge_handle(start), end) {
447 
448  GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
449  }
450  GenericCirculatorT_DEPRECATED(mesh_ref mesh, typename Mesh::HalfedgeHandle heh, bool end = false) :
451  GenericCirculatorBaseT<Mesh>(mesh, heh, end) {
452 
453  GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
454  }
456 
457  GenericCirculatorT_DEPRECATED& operator++() {
458  assert(this->mesh_);
459  GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
460  return *this;
461  }
462 #ifndef NO_DECREMENT_DEPRECATED_WARNINGS
463 #define DECREMENT_DEPRECATED_WARNINGS_TEXT "The current decrement operator has the unintended behavior that it stays\
464  valid when iterating below the start and will visit the first entity\
465  twice before getting invalid. Furthermore it gets valid again, if you\
466  increment at the end.\
467  When you are sure that you don't iterate below the start anywhere in\
468  your code or rely on this behaviour, you can disable this warning by\
469  setting the define NO_DECREMENT_DEPRECATED_WARNINGS at the command line (or enable it via the\
470  cmake flags).\
471  To be save, you can use the CW/CCW circulator definitions, which behave\
472  the same as the original ones, without the previously mentioned issues."
473 
474  OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
475 #endif // NO_DECREMENT_DEPRECATED_WARNINGS
476  GenericCirculatorT_DEPRECATED& operator--() {
477  assert(this->mesh_);
478  GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
479  return *this;
480  }
481 
484  assert(this->mesh_);
486  ++(*this);
487  return cpy;
488  }
489 
491 #ifndef NO_DECREMENT_DEPRECATED_WARNINGS
492  OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
493 #undef DECREMENT_DEPRECATED_WARNINGS_TEXT
494 #endif //NO_DECREMENT_DEPRECATED_WARNINGS
496  assert(this->mesh_);
498  --(*this);
499  return cpy;
500  }
501 
503  smart_value_type operator*() const {
504 #ifndef NDEBUG
505  assert(this->heh_.is_valid());
506  value_type res = (GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_));
507  assert(res.is_valid());
508  return make_smart(res, this->mesh_);
509 #else
510  return make_smart(GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_);
511 #endif
512  }
513 
522  pointer operator->() const {
523  pointer_deref_value = **this;
524  return &pointer_deref_value;
525  }
526 
529  return *this;
530  };
531 
532  bool operator==(const GenericCirculatorT_DEPRECATED &rhs) const {
534  }
535 
536  bool operator!=(const GenericCirculatorT_DEPRECATED &rhs) const {
538  }
539 
540  bool is_valid() const {
541  return GenericCirculator_ValueHandleFns::is_valid(this->heh_,this->start_, this->lap_counter_);
542  }
543 
544  OM_DEPRECATED("current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.")
550  const typename Mesh::HalfedgeHandle &current_halfedge_handle() const {
551  return this->heh_;
552  }
553 
554  OM_DEPRECATED("Do not use this error prone implicit cast. Compare to end-iterator or use is_valid(), instead.")
560  operator bool() const {
561  return is_valid();
562  }
563 
569  OM_DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.")
570  smart_value_type handle() const {
571  return **this;
572  }
573 
580  OM_DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
581  operator value_type() const {
582  return **this;
583  }
584 
585  template<typename STREAM>
586  friend STREAM &operator<< (STREAM &s, const GenericCirculatorT_DEPRECATED &self) {
587  return s << self.mesh_ << ", " << self.start_.idx() << ", " << self.heh_.idx() << ", " << self.lap_counter_;
588  }
589 
590  private:
591  mutable smart_value_type pointer_deref_value;
592 };
593 
594 } // namespace Iterators
595 } // namespace OpenMesh
596 
Handle for a face entity.
Definition: Handles.hh:141
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
Definition: VectorT.hh:647
Handle for a halfedge entity.
Definition: Handles.hh:127
pointer operator->() const
Pointer dereferentiation.
GenericCirculatorT_DEPRECATED operator--(int)
Post-decrement.
smart_value_type operator*() const
Standard dereferencing operator.
Handle for a vertex entity.
Definition: Handles.hh:120
SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity *_mesh)
Creats a SmartVertexHandle from a VertexHandle and a Mesh.
#define OM_DEPRECATED(msg)
define OM_SUPPRESS_DEPRECATED to suppress deprecated code warnings
Definition: config.h:102
GenericCirculatorT operator++(int)
Post-increment.
smart_value_type operator*() const
Standard dereferencing operator.
pointer operator->() const
Pointer dereferentiation.
GenericCirculatorT_DEPRECATED operator++(int)
Post-increment.
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:136
GenericCirculatorT operator--(int)
Post-decrement.