| OpenMesh

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 * *
44 * $Revision: 1258 $ *
45 * $Date: 2015-04-28 15:07:46 +0200 (Di, 28 Apr 2015) $ *
46 * *
47 \*===========================================================================*/
48
49 #ifndef OPENMESH_CIRCULATORS_HH
50 #define OPENMESH_CIRCULATORS_HH
51 //=============================================================================
52 //
53 // Vertex and Face circulators for PolyMesh/TriMesh
54 //
55 //=============================================================================
56
57
58
59 //== INCLUDES =================================================================
60
61 #include <OpenMesh/Core/System/config.h>
62 #include <cassert>
63 #include <cstddef>
64 #include <iterator>
65
66 //== NAMESPACES ===============================================================
67
68 namespace OpenMesh {
69 namespace Iterators {
70
71 template<class Mesh, class CenterEntityHandle, bool CW>
72 class GenericCirculator_CenterEntityFnsT {
73 public:
74 static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter);
75 static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter);
76 };
77
78 template<class Mesh>
79 class GenericCirculator_CenterEntityFnsT<Mesh, typename Mesh::VertexHandle, true> {
80 public:
81 inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
82 heh = mesh->cw_rotated_halfedge_handle(heh);
83 if (heh == start) ++lap_counter;
84 }
85 inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
86 if (heh == start) --lap_counter;
87 heh = mesh->ccw_rotated_halfedge_handle(heh);
88 }
89 };
90
91 template<class Mesh>
92 class GenericCirculator_CenterEntityFnsT<Mesh, typename Mesh::FaceHandle, true> {
93 public:
94 inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
95 heh = mesh->next_halfedge_handle(heh);
96 if (heh == start) ++lap_counter;
97 }
98 inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
99 if (heh == start) --lap_counter;
100 heh = mesh->prev_halfedge_handle(heh);
101 }
102 };
103
105 // CCW
106
107 template<class Mesh>
108 class GenericCirculator_CenterEntityFnsT<Mesh, typename Mesh::VertexHandle, false> {
109 public:
110 inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
111 heh = mesh->ccw_rotated_halfedge_handle(heh);
112 if (heh == start) ++lap_counter;
113 }
114 inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
115 if (heh == start) --lap_counter;
116 heh = mesh->cw_rotated_halfedge_handle(heh);
117 }
118 };
119
120 template<class Mesh>
121 class GenericCirculator_CenterEntityFnsT<Mesh, typename Mesh::FaceHandle, false> {
122 public:
123 inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
124 heh = mesh->prev_halfedge_handle(heh);
125 if (heh == start) ++lap_counter;
126 }
127 inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
128 if (heh == start) --lap_counter;
129 heh = mesh->next_halfedge_handle(heh);
130 }
131 };
133
134 template<class Mesh, class CenterEntityHandle, class ValueHandle>
135 class GenericCirculator_DereferenciabilityCheckT {
136 public:
137 //inline static bool isDereferenciable(const Mesh *mesh, const typename Mesh::HalfedgeHandle &heh, const typename Mesh::HalfedgeHandle &start, const int &lap_counter);
138 };
139
140 template<class Mesh>
141 class GenericCirculator_DereferenciabilityCheckT<Mesh, typename Mesh::FaceHandle, typename Mesh::FaceHandle> {
142 public:
143 inline static bool isDereferenciable(const Mesh *mesh, const typename Mesh::HalfedgeHandle &heh) {
144 return mesh->face_handle(mesh->opposite_halfedge_handle(heh)).is_valid();
145 }
146 };
147
148 template<class Mesh>
149 class GenericCirculator_DereferenciabilityCheckT<Mesh, typename Mesh::VertexHandle, typename Mesh::FaceHandle> {
150 public:
151 inline static bool isDereferenciable(const Mesh *mesh, const typename Mesh::HalfedgeHandle &heh) {
152 return mesh->face_handle(heh).is_valid();
153 }
154 };
155
156 template<class Mesh, class CenterEntityHandle, class ValueHandle, bool CW = true>
157 class GenericCirculator_ValueHandleFnsT {
158 public:
159 inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const int lap_counter) {
160 return ( heh.is_valid() && (lap_counter == 0 ) );
161 }
162 inline static void init(const Mesh*, typename Mesh::HalfedgeHandle&, typename Mesh::HalfedgeHandle&, int&) {};
163 inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
164 GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, CW>::increment(mesh, heh, start, lap_counter);
165 }
166 inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
167 GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, CW>::decrement(mesh, heh, start, lap_counter);
168 }
169 };
170
171 template<class Mesh, class CenterEntityHandle, bool CW>
172 class GenericCirculator_ValueHandleFnsT<Mesh, CenterEntityHandle, typename Mesh::FaceHandle, CW> {
173 public:
174 typedef GenericCirculator_DereferenciabilityCheckT<Mesh, CenterEntityHandle, typename Mesh::FaceHandle> GenericCirculator_DereferenciabilityCheck;
175
176 inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const int lap_counter) {
177 return ( heh.is_valid() && (lap_counter == 0));
178 }
179 inline static void init(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
180 if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
181 increment(mesh, heh, start, lap_counter);
182 };
183 inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
184 do {
185 GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, CW>::increment(mesh, heh, start, lap_counter);
186 } while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
187 }
188 inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
189 do {
190 GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, CW>::decrement(mesh, heh, start, lap_counter);
191 } while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
192 }
193 };
194
195 template<class Mesh>
196 class GenericCirculatorBaseT {
197 public:
198 typedef const Mesh* mesh_ptr;
199 typedef const Mesh& mesh_ref;
200
201 public:
202 GenericCirculatorBaseT() : mesh_(0), lap_counter_(0) {}
203
204 GenericCirculatorBaseT(mesh_ref mesh, HalfedgeHandle heh, bool end = false) :
205 mesh_(&mesh), start_(heh), heh_(heh), lap_counter_(static_cast<int>(end)) {}
206
207 GenericCirculatorBaseT(const GenericCirculatorBaseT &rhs) :
208 mesh_(rhs.mesh_), start_(rhs.start_), heh_(rhs.heh_), lap_counter_(rhs.lap_counter_) {}
209
210 inline typename Mesh::FaceHandle toFaceHandle() const {
211 return mesh_->face_handle(heh_);
212 }
213
214 inline typename Mesh::FaceHandle toOppositeFaceHandle() const {
215 return mesh_->face_handle(toOppositeHalfedgeHandle());
216 }
217
218 inline typename Mesh::EdgeHandle toEdgeHandle() const {
219 return mesh_->edge_handle(heh_);
220 }
221
222 inline typename Mesh::HalfedgeHandle toHalfedgeHandle() const {
223 return heh_;
224 }
225
226 inline typename Mesh::HalfedgeHandle toOppositeHalfedgeHandle() const {
227 return mesh_->opposite_halfedge_handle(heh_);
228 }
229
230 inline typename Mesh::VertexHandle toVertexHandle() const {
231 return mesh_->to_vertex_handle(heh_);
232 }
233
234 inline GenericCirculatorBaseT &operator=(const GenericCirculatorBaseT &rhs) {
235 mesh_ = rhs.mesh_;
236 start_ = rhs.start_;
237 heh_ = rhs.heh_;
238 lap_counter_ = rhs.lap_counter_;
239 return *this;
240 }
241
242 inline bool operator==(const GenericCirculatorBaseT &rhs) const {
243 return mesh_ == rhs.mesh_ && start_ == rhs.start_ && heh_ == rhs.heh_ && lap_counter_ == rhs.lap_counter_;
244 }
245
246 inline bool operator!=(const GenericCirculatorBaseT &rhs) const {
247 return !operator==(rhs);
248 }
249
250 protected:
251 mesh_ptr mesh_;
252 typename Mesh::HalfedgeHandle start_, heh_;
253 int lap_counter_;
254 };
255
256 template<class Mesh, class CenterEntityHandle, class ValueHandle,
257 ValueHandle (GenericCirculatorBaseT<Mesh>::*Handle2Value)() const, bool CW = true >
258 class GenericCirculatorT : protected GenericCirculatorBaseT<Mesh> {
259 public:
260 typedef std::ptrdiff_t difference_type;
261 typedef ValueHandle value_type;
262 typedef const value_type& reference;
263 typedef const value_type* pointer;
264 typedef std::bidirectional_iterator_tag iterator_category;
265
266 typedef typename GenericCirculatorBaseT<Mesh>::mesh_ptr mesh_ptr;
267 typedef typename GenericCirculatorBaseT<Mesh>::mesh_ref mesh_ref;
268 typedef GenericCirculator_ValueHandleFnsT<Mesh, CenterEntityHandle, ValueHandle, CW> GenericCirculator_ValueHandleFns;
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, 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 }
282 GenericCirculatorT(const GenericCirculatorT &rhs) : GenericCirculatorBaseT<Mesh>(rhs) {}
283
284 friend class GenericCirculatorT<Mesh,CenterEntityHandle,ValueHandle,Handle2Value,!CW>;
285 explicit GenericCirculatorT( const GenericCirculatorT<Mesh,CenterEntityHandle,ValueHandle,Handle2Value,!CW>& rhs )
286 :GenericCirculatorBaseT<Mesh>(rhs){}
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 value_type operator*() const {
317 #ifndef NDEBUG
318 assert(this->heh_.is_valid());
319 value_type res = (this->*Handle2Value)();
320 assert(res.is_valid());
321 return res;
322 #else
323 return (this->*Handle2Value)();
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) {
341 GenericCirculatorBaseT<Mesh>::operator=(rhs);
342 return *this;
343 };
344
345 bool operator==(const GenericCirculatorT &rhs) const {
346 return GenericCirculatorBaseT<Mesh>::operator==(rhs);
347 }
348
349 bool operator!=(const GenericCirculatorT &rhs) const {
350 return GenericCirculatorBaseT<Mesh>::operator!=(rhs);
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 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>
388 class GenericCirculator_ValueHandleFnsT_DEPRECATED {
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) {
395 GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, true>::increment(mesh, heh, start, lap_counter);
396 }
397 inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
398 GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, true>::decrement(mesh, heh, start, lap_counter);
399 }
400 };
401
402 template<class Mesh, class CenterEntityHandle>
403 class GenericCirculator_ValueHandleFnsT_DEPRECATED<Mesh, CenterEntityHandle, typename Mesh::FaceHandle> {
404 public:
405 typedef GenericCirculator_DereferenciabilityCheckT<Mesh, CenterEntityHandle, typename Mesh::FaceHandle> GenericCirculator_DereferenciabilityCheck;
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 {
416 GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, true>::increment(mesh, heh, start, lap_counter);
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 {
421 GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, true>::decrement(mesh, heh, start, lap_counter);
422 } while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
423 }
424 };
425
426 template<class Mesh, class CenterEntityHandle, class ValueHandle,
427 ValueHandle (GenericCirculatorBaseT<Mesh>::*Handle2Value)() const>
428 class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
429 public:
430 typedef std::ptrdiff_t difference_type;
431 typedef ValueHandle value_type;
432 typedef const value_type& reference;
433 typedef const value_type* pointer;
434 typedef std::bidirectional_iterator_tag iterator_category;
435
436 typedef typename GenericCirculatorBaseT<Mesh>::mesh_ptr mesh_ptr;
437 typedef typename GenericCirculatorBaseT<Mesh>::mesh_ref mesh_ref;
438 typedef GenericCirculator_ValueHandleFnsT_DEPRECATED<Mesh, CenterEntityHandle, ValueHandle> GenericCirculator_ValueHandleFns;
439
440 public:
441 GenericCirculatorT_DEPRECATED() {}
442 GenericCirculatorT_DEPRECATED(mesh_ref mesh, CenterEntityHandle start, bool end = false) :
443 GenericCirculatorBaseT<Mesh>(mesh, mesh.halfedge_handle(start), end) {
444
445 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
446 }
447 GenericCirculatorT_DEPRECATED(mesh_ref mesh, HalfedgeHandle heh, bool end = false) :
448 GenericCirculatorBaseT<Mesh>(mesh, heh, end) {
449
450 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
451 }
452 GenericCirculatorT_DEPRECATED(const GenericCirculatorT_DEPRECATED &rhs) : GenericCirculatorBaseT<Mesh>(rhs) {}
453
454 GenericCirculatorT_DEPRECATED& operator++() {
455 assert(this->mesh_);
456 GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
457 return *this;
458 }
459 #ifndef NO_DECREMENT_DEPRECATED_WARNINGS
460 #define DECREMENT_DEPRECATED_WARNINGS_TEXT "The current decrement operator has the unintended behavior that it stays\
461 valid when iterating below the start and will visit the first entity\
462 twice before getting invalid. Furthermore it gets valid again, if you\
463 increment at the end.\
464 When you are sure that you don't iterate below the start anywhere in\
465 your code or rely on this behaviour, you can disable this warning by\
466 setting the define NO_DECREMENT_DEPRECATED_WARNINGS at the command line (or enable it via the\
467 cmake flags).\
468 To be save, you can use the CW/CCW circulator definitions, which behave\
469 the same as the original ones, without the previously mentioned issues."
470
471 DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
472 #endif // NO_DECREMENT_DEPRECATED_WARNINGS
473 GenericCirculatorT_DEPRECATED& operator--() {
474 assert(this->mesh_);
475 GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
476 return *this;
477 }
478
480 GenericCirculatorT_DEPRECATED operator++(int) {
481 assert(this->mesh_);
482 GenericCirculatorT_DEPRECATED cpy(*this);
483 ++(*this);
484 return cpy;
485 }
486
488 #ifndef NO_DECREMENT_DEPRECATED_WARNINGS
489 DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
490 #undef DECREMENT_DEPRECATED_WARNINGS_TEXT
491 #endif //NO_DECREMENT_DEPRECATED_WARNINGS
492 GenericCirculatorT_DEPRECATED operator--(int) {
493 assert(this->mesh_);
494 GenericCirculatorT_DEPRECATED cpy(*this);
495 --(*this);
496 return cpy;
497 }
498
500 value_type operator*() const {
501 #ifndef NDEBUG
502 assert(this->heh_.is_valid());
503 value_type res = (this->*Handle2Value)();
504 assert(res.is_valid());
505 return res;
506 #else
507 return (this->*Handle2Value)();
508 #endif
509 }
510
519 pointer operator->() const {
520 pointer_deref_value = **this;
521 return &pointer_deref_value;
522 }
523
524 GenericCirculatorT_DEPRECATED &operator=(const GenericCirculatorT_DEPRECATED &rhs) {
525 GenericCirculatorBaseT<Mesh>::operator=(rhs);
526 return *this;
527 };
528
529 bool operator==(const GenericCirculatorT_DEPRECATED &rhs) const {
530 return GenericCirculatorBaseT<Mesh>::operator==(rhs);
531 }
532
533 bool operator!=(const GenericCirculatorT_DEPRECATED &rhs) const {
534 return GenericCirculatorBaseT<Mesh>::operator!=(rhs);
535 }
536
537 bool is_valid() const {
538 return GenericCirculator_ValueHandleFns::is_valid(this->heh_,this->start_, this->lap_counter_);
539 }
540
541 DEPRECATED("current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.")
547 const HalfedgeHandle &current_halfedge_handle() const {
548 return this->heh_;
549 }
550
551 DEPRECATED("Do not use this error prone implicit cast. Compare to end-iterator or use is_valid(), instead.")
557 operator bool() const {
558 return is_valid();
559 }
560
566 DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.")
567 value_type handle() const {
568 return **this;
569 }
570
577 DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
578 operator value_type() const {
579 return **this;
580 }
581
582 template<typename STREAM>
583 friend STREAM &operator<< (STREAM &s, const GenericCirculatorT_DEPRECATED &self) {
584 return s << self.mesh_ << ", " << self.start_.idx() << ", " << self.heh_.idx() << ", " << self.lap_counter_;
585 }
586
587 private:
588 mutable value_type pointer_deref_value;
589 };
590
591 } // namespace Iterators
592 } // namespace OpenMesh
593
594 #endif
OpenMesh::BaseHandle::is_valid
bool is_valid() const
The handle is valid iff the index is not equal to -1.
Definition: Handles.hh:77
OpenMesh::Iterators::GenericCirculatorT_DEPRECATED::operator++
GenericCirculatorT_DEPRECATED operator++(int)
Post-increment.
Definition: CirculatorsT.hh:480
OpenMesh::Iterators::GenericCirculatorBaseT
Definition: CirculatorsT.hh:196
OpenMesh::Iterators::GenericCirculator_CenterEntityFnsT
Definition: CirculatorsT.hh:72
OpenMesh
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:64
OpenMesh::Iterators::GenericCirculator_ValueHandleFnsT
Definition: CirculatorsT.hh:157
OpenMesh::Iterators::GenericCirculator_ValueHandleFnsT_DEPRECATED< Mesh, CenterEntityHandle, typename Mesh::FaceHandle >
Definition: CirculatorsT.hh:403
OpenMesh::Iterators::GenericCirculatorT::operator++
GenericCirculatorT operator++(int)
Post-increment.
Definition: CirculatorsT.hh:300
OpenMesh::FaceHandle
Handle for a face entity.
Definition: Handles.hh:142
OpenMesh::Iterators::GenericCirculatorT_DEPRECATED
Definition: CirculatorsT.hh:428
OpenMesh::Iterators::GenericCirculatorT::operator*
value_type operator*() const
Standard dereferencing operator.
Definition: CirculatorsT.hh:316
OpenMesh::Iterators::GenericCirculatorT::operator--
GenericCirculatorT operator--(int)
Post-decrement.
Definition: CirculatorsT.hh:308
OpenMesh::HalfedgeHandle
Handle for a halfedge entity.
Definition: Handles.hh:128
OpenMesh::Iterators::GenericCirculator_DereferenciabilityCheckT
Definition: CirculatorsT.hh:135
OpenMesh::VertexHandle
Handle for a vertex entity.
Definition: Handles.hh:121
OpenMesh::Iterators::GenericCirculatorT_DEPRECATED::operator*
value_type operator*() const
Standard dereferencing operator.
Definition: CirculatorsT.hh:500
OpenMesh::Iterators::GenericCirculator_ValueHandleFnsT_DEPRECATED
Definition: CirculatorsT.hh:388
OpenMesh::operator<<
std::ostream & operator<<(std::ostream &_os, const BaseHandle &_hnd)
Write handle _hnd to stream _os.
Definition: Handles.hh:111
OpenMesh::Iterators::GenericCirculatorT
Definition: CirculatorsT.hh:258
OpenMesh::Iterators::GenericCirculatorT_DEPRECATED::operator--
GenericCirculatorT_DEPRECATED operator--(int)
Post-decrement.
Definition: CirculatorsT.hh:492
OpenMesh::Iterators::GenericCirculatorT_DEPRECATED::operator->
pointer operator->() const
Pointer dereferentiation.
Definition: CirculatorsT.hh:519
OpenMesh::Iterators::GenericCirculatorT::operator->
pointer operator->() const
Pointer dereferentiation.
Definition: CirculatorsT.hh:335