55#include <OpenMesh/Core/System/config.h>
68template<
class Mesh,
class CenterEntityHandle,
bool CW>
79 heh = mesh->cw_rotated_halfedge_handle(heh);
80 if (heh == start) ++lap_counter;
83 if (heh == start) --lap_counter;
84 heh = mesh->ccw_rotated_halfedge_handle(heh);
92 heh = mesh->next_halfedge_handle(heh);
93 if (heh == start) ++lap_counter;
96 if (heh == start) --lap_counter;
97 heh = mesh->prev_halfedge_handle(heh);
101template<
class Mesh,
bool CW>
105 heh = mesh->opposite_halfedge_handle(heh);
106 if (heh == start) ++lap_counter;
109 if (heh == start) --lap_counter;
110 heh = mesh->opposite_halfedge_handle(heh);
121 heh = mesh->ccw_rotated_halfedge_handle(heh);
122 if (heh == start) ++lap_counter;
125 if (heh == start) --lap_counter;
126 heh = mesh->cw_rotated_halfedge_handle(heh);
134 heh = mesh->prev_halfedge_handle(heh);
135 if (heh == start) ++lap_counter;
138 if (heh == start) --lap_counter;
139 heh = mesh->next_halfedge_handle(heh);
144template<
class Mesh,
class CenterEntityHandle,
class ValueHandle>
153 inline static bool isDereferenciable(
const Mesh *mesh,
const typename Mesh::HalfedgeHandle &heh) {
154 return mesh->face_handle(mesh->opposite_halfedge_handle(heh)).is_valid();
161 inline static bool isDereferenciable(
const Mesh *mesh,
const typename Mesh::HalfedgeHandle &heh) {
162 return mesh->face_handle(heh).is_valid();
169 inline static bool isDereferenciable(
const Mesh *mesh,
const typename Mesh::HalfedgeHandle &heh) {
170 return mesh->face_handle(heh).is_valid();
174template<
class Mesh,
class CenterEntityHandle,
class ValueHandle,
bool CW = true>
178 return ( heh.is_valid() && (lap_counter == 0 ) );
187 int lc = lap_counter;
188 increment(mesh, heh, start, lap_counter);
196 GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, CW>::increment(mesh, heh, start, lap_counter);
199 GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, CW>::decrement(mesh, heh, start, lap_counter);
203template<
class Mesh,
class CenterEntityHandle,
bool CW>
209 return ( heh.is_valid() && (lap_counter == 0));
218 int lc = lap_counter;
219 increment(mesh, heh, start, lap_counter);
224 if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
225 increment(mesh, heh, start, lap_counter);
229 GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, CW>::increment(mesh, heh, start, lap_counter);
230 }
while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
234 GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, CW>::decrement(mesh, heh, start, lap_counter);
235 }
while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
240class GenericCirculatorBaseT {
242 typedef const Mesh* mesh_ptr;
243 typedef const Mesh& mesh_ref;
248 GenericCirculatorBaseT() : mesh_(0), lap_counter_(0) {}
251 mesh_(&mesh), start_(heh), heh_(heh), lap_counter_(
static_cast<int>(end && heh.is_valid())) {}
253 GenericCirculatorBaseT(
const GenericCirculatorBaseT &rhs) :
254 mesh_(rhs.mesh_), start_(rhs.start_), heh_(rhs.heh_), lap_counter_(rhs.lap_counter_) {}
257 return mesh_->face_handle(heh_);
261 return mesh_->face_handle(toOppositeHalfedgeHandle());
265 return mesh_->edge_handle(heh_);
273 return mesh_->opposite_halfedge_handle(heh_);
277 return mesh_->to_vertex_handle(heh_);
280 inline GenericCirculatorBaseT &operator=(
const GenericCirculatorBaseT &rhs) {
284 lap_counter_ = rhs.lap_counter_;
288 inline bool operator==(
const GenericCirculatorBaseT &rhs)
const {
289 return mesh_ == rhs.mesh_ && start_ == rhs.start_ && heh_ == rhs.heh_ && lap_counter_ == rhs.lap_counter_;
292 inline bool operator!=(
const GenericCirculatorBaseT &rhs)
const {
293 return !operator==(rhs);
304template <
typename GenericCirculatorT_TraitsT,
bool CW = true>
305class GenericCirculatorT :
protected GenericCirculatorBaseT<typename GenericCirculatorT_TraitsT::Mesh> {
307 using Mesh =
typename GenericCirculatorT_TraitsT::Mesh;
308 using value_type =
typename GenericCirculatorT_TraitsT::ValueHandle;
309 using CenterEntityHandle =
typename GenericCirculatorT_TraitsT::CenterEntityHandle;
311 using smart_value_type =
decltype(
make_smart(std::declval<value_type>(), std::declval<Mesh>()));
313 typedef std::ptrdiff_t difference_type;
314 typedef const value_type& reference;
315 typedef const smart_value_type* pointer;
316 typedef std::bidirectional_iterator_tag iterator_category;
318 typedef typename GenericCirculatorBaseT<Mesh>::mesh_ptr mesh_ptr;
319 typedef typename GenericCirculatorBaseT<Mesh>::mesh_ref mesh_ref;
325 GenericCirculatorT() {}
326 GenericCirculatorT(mesh_ref mesh, CenterEntityHandle start,
bool end =
false) :
327 GenericCirculatorBaseT<Mesh>(mesh, mesh.halfedge_handle(start), end)
329 bool adjust_for_ccw =
true;
330 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_, adjust_for_ccw);
333 GenericCirculatorBaseT<Mesh>(mesh, heh, end)
335 bool adjust_for_ccw =
false;
336 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_, adjust_for_ccw);
338 GenericCirculatorT(
const GenericCirculatorT &rhs) : GenericCirculatorBaseT<Mesh>(rhs) {}
340 friend class GenericCirculatorT<GenericCirculatorT_TraitsT,!CW>;
341 explicit GenericCirculatorT(
const GenericCirculatorT<GenericCirculatorT_TraitsT,!CW>& rhs )
342 :GenericCirculatorBaseT<Mesh>(rhs){}
344 GenericCirculatorT& operator++() {
346 GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
349 GenericCirculatorT& operator--() {
351 GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
358 GenericCirculatorT cpy(*
this);
366 GenericCirculatorT cpy(*
this);
374 assert(this->heh_.is_valid());
375 value_type res = GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_);
376 assert(res.is_valid());
379 return make_smart(GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_);
392 pointer_deref_value = **
this;
393 return &pointer_deref_value;
397 GenericCirculatorBaseT<Mesh>::operator=(rhs);
401 bool operator==(
const GenericCirculatorT &rhs)
const {
402 return GenericCirculatorBaseT<Mesh>::operator==(rhs);
405 bool operator!=(
const GenericCirculatorT &rhs)
const {
406 return GenericCirculatorBaseT<Mesh>::operator!=(rhs);
409 bool is_valid()
const {
410 return GenericCirculator_ValueHandleFns::is_valid(this->heh_, this->lap_counter_);
413 template<
typename STREAM>
414 friend STREAM &operator<< (STREAM &s,
const GenericCirculatorT &self) {
415 return s << self.mesh_ <<
", " << self.start_.idx() <<
", " << self.heh_.idx() <<
", " << self.lap_counter_;
419 mutable smart_value_type pointer_deref_value;
443template<
class Mesh,
class CenterEntityHandle,
class ValueHandle>
447 return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 )) );
451 GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, true>::increment(mesh, heh, start, lap_counter);
454 GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, true>::decrement(mesh, heh, start, lap_counter);
458template<
class Mesh,
class CenterEntityHandle>
464 return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 )));
467 if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
468 increment(mesh, heh, start, lap_counter);
472 GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, true>::increment(mesh, heh, start, lap_counter);
473 }
while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
477 GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, true>::decrement(mesh, heh, start, lap_counter);
478 }
while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
482template <
typename GenericCirculatorT_DEPRECATED_TraitsT>
483class GenericCirculatorT_DEPRECATED :
protected GenericCirculatorBaseT<typename GenericCirculatorT_DEPRECATED_TraitsT::Mesh> {
485 using Mesh =
typename GenericCirculatorT_DEPRECATED_TraitsT::Mesh;
486 using CenterEntityHandle =
typename GenericCirculatorT_DEPRECATED_TraitsT::CenterEntityHandle;
487 using value_type =
typename GenericCirculatorT_DEPRECATED_TraitsT::ValueHandle;
488 using smart_value_type =
decltype (
make_smart(std::declval<value_type>(), std::declval<Mesh>()));
490 typedef std::ptrdiff_t difference_type;
491 typedef const value_type& reference;
492 typedef const smart_value_type* pointer;
493 typedef std::bidirectional_iterator_tag iterator_category;
495 typedef typename GenericCirculatorBaseT<Mesh>::mesh_ptr mesh_ptr;
496 typedef typename GenericCirculatorBaseT<Mesh>::mesh_ref mesh_ref;
502 GenericCirculatorT_DEPRECATED() {}
503 GenericCirculatorT_DEPRECATED(mesh_ref mesh, CenterEntityHandle start,
bool end =
false) :
504 GenericCirculatorBaseT<Mesh>(mesh, mesh.halfedge_handle(start), end) {
506 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
508 GenericCirculatorT_DEPRECATED(mesh_ref mesh,
typename Mesh::HalfedgeHandle heh,
bool end =
false) :
509 GenericCirculatorBaseT<Mesh>(mesh, heh, end) {
511 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
513 GenericCirculatorT_DEPRECATED(
const GenericCirculatorT_DEPRECATED &rhs) : GenericCirculatorBaseT<Mesh>(rhs) {}
515 GenericCirculatorT_DEPRECATED& operator++() {
517 GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
520#ifndef NO_DECREMENT_DEPRECATED_WARNINGS
521#define DECREMENT_DEPRECATED_WARNINGS_TEXT "The current decrement operator has the unintended behavior that it stays\
522 valid when iterating below the start and will visit the first entity\
523 twice before getting invalid. Furthermore it gets valid again, if you\
524 increment at the end.\
525 When you are sure that you don't iterate below the start anywhere in\
526 your code or rely on this behaviour, you can disable this warning by\
527 setting the define NO_DECREMENT_DEPRECATED_WARNINGS at the command line (or enable it via the\
529 To be save, you can use the CW/CCW circulator definitions, which behave\
530 the same as the original ones, without the previously mentioned issues."
532 OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
534 GenericCirculatorT_DEPRECATED& operator--() {
536 GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
543 GenericCirculatorT_DEPRECATED cpy(*
this);
549#ifndef NO_DECREMENT_DEPRECATED_WARNINGS
550 OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
551#undef DECREMENT_DEPRECATED_WARNINGS_TEXT
555 GenericCirculatorT_DEPRECATED cpy(*
this);
563 assert(this->heh_.is_valid());
564 value_type res = (GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_));
565 assert(res.is_valid());
568 return make_smart(GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_);
581 pointer_deref_value = **
this;
582 return &pointer_deref_value;
586 GenericCirculatorBaseT<Mesh>::operator=(rhs);
590 bool operator==(
const GenericCirculatorT_DEPRECATED &rhs)
const {
591 return GenericCirculatorBaseT<Mesh>::operator==(rhs);
594 bool operator!=(
const GenericCirculatorT_DEPRECATED &rhs)
const {
595 return GenericCirculatorBaseT<Mesh>::operator!=(rhs);
598 bool is_valid()
const {
599 return GenericCirculator_ValueHandleFns::is_valid(this->heh_,this->start_, this->lap_counter_);
602 OM_DEPRECATED(
"current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.")
612 OM_DEPRECATED(
"Do not use this error prone implicit cast. Compare to end-iterator or use is_valid(), instead.")
618 operator
bool()
const {
627 OM_DEPRECATED(
"This function clutters your code. Use dereferencing operators -> and * instead.")
638 OM_DEPRECATED(
"Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
639 operator value_type()
const {
643 template<
typename STREAM>
645 return s << self.mesh_ <<
", " << self.start_.idx() <<
", " << self.heh_.idx() <<
", " << self.lap_counter_;
649 mutable smart_value_type pointer_deref_value;
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:265
Contains all mesh iterators and circulators.
Generic class for iterator ranges.
Definition PolyConnectivity_inline_impl.hh:92
Definition CirculatorsT.hh:69
Definition CirculatorsT.hh:145
Definition CirculatorsT.hh:175
Definition CirculatorsT.hh:305
smart_value_type operator*() const
Standard dereferencing operator.
Definition CirculatorsT.hh:372
GenericCirculatorT operator++(int)
Post-increment.
Definition CirculatorsT.hh:356
GenericCirculatorT operator--(int)
Post-decrement.
Definition CirculatorsT.hh:364
pointer operator->() const
Pointer dereferentiation.
Definition CirculatorsT.hh:391
Definition CirculatorsT.hh:444
Definition CirculatorsT.hh:483
GenericCirculatorT_DEPRECATED operator++(int)
Post-increment.
Definition CirculatorsT.hh:541
const Mesh::HalfedgeHandle & current_halfedge_handle() const
Definition CirculatorsT.hh:608
pointer operator->() const
Pointer dereferentiation.
Definition CirculatorsT.hh:580
GenericCirculatorT_DEPRECATED operator--(int)
Post-decrement.
Definition CirculatorsT.hh:553
smart_value_type operator*() const
Standard dereferencing operator.
Definition CirculatorsT.hh:561
smart_value_type handle() const
Definition CirculatorsT.hh:628
Handle for a vertex entity.
Definition Handles.hh:121
Handle for a halfedge entity.
Definition Handles.hh:128
Handle for a edge entity.
Definition Handles.hh:135
Handle for a face entity.
Definition Handles.hh:142
AttribKernel::VertexHandle VertexHandle
Definition PolyMeshT.hh:136
AttribKernel::EdgeHandle EdgeHandle
Definition PolyMeshT.hh:138
AttribKernel::FaceHandle FaceHandle
Definition PolyMeshT.hh:139
AttribKernel::HalfedgeHandle HalfedgeHandle
Definition PolyMeshT.hh:137