OpenMesh
Loading...
Searching...
No Matches
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
62namespace OpenMesh {
63
64template <typename> class CirculatorRange;
65
66namespace Iterators {
67
68template<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
75template<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
88template<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
104template<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
117template<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
131template<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
137template<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
145template<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
153template<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
182template<class Mesh, class CenterEntityHandle, bool CW>
183class 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
218template<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 >
283template <typename GenericCirculatorT_TraitsT, bool CW = true>
284class 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:
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
422template<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
437template<class Mesh, class CenterEntityHandle>
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
461template <typename GenericCirculatorT_DEPRECATED_TraitsT>
462class 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
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
GenericCirculatorT_DEPRECATED operator++(int)
Post-increment.
Definition CirculatorsT.hh:520
const Mesh::HalfedgeHandle & current_halfedge_handle() const
Definition CirculatorsT.hh:587
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 .