55#include <OpenMesh/Core/System/config.h>
64template <
typename>
class CirculatorRange;
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>
154 return mesh->face_handle(mesh->opposite_halfedge_handle(heh)).is_valid();
162 return mesh->face_handle(heh).is_valid();
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);
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);
230 }
while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
235 }
while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
251 mesh_(&mesh), start_(heh), heh_(heh), lap_counter_(
static_cast<int>(end && heh.is_valid())) {}
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_);
284 lap_counter_ = rhs.lap_counter_;
289 return mesh_ == rhs.mesh_ && start_ == rhs.start_ && heh_ == rhs.heh_ && lap_counter_ == rhs.lap_counter_;
293 return !operator==(rhs);
304template <
typename GenericCirculatorT_TraitsT,
bool CW = true>
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;
329 bool adjust_for_ccw =
true;
330 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_, adjust_for_ccw);
335 bool adjust_for_ccw =
false;
336 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_, adjust_for_ccw);
346 GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
351 GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
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;
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 )) );
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);
473 }
while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
478 }
while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
482template <
typename GenericCirculatorT_DEPRECATED_TraitsT>
485 using ValueHandle =
typename GenericCirculatorT_DEPRECATED_TraitsT::ValueHandle;
486 using Mesh =
typename GenericCirculatorT_DEPRECATED_TraitsT::Mesh;
487 using CenterEntityHandle =
typename GenericCirculatorT_DEPRECATED_TraitsT::CenterEntityHandle;
488 using smart_value_type =
decltype (
make_smart(std::declval<ValueHandle>(), std::declval<Mesh>()));
489 using value_type = smart_value_type;
491 typedef std::ptrdiff_t difference_type;
492 typedef const value_type& reference;
493 typedef const smart_value_type* pointer;
494 typedef std::bidirectional_iterator_tag iterator_category;
507 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
512 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
518 GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
521#ifndef NO_DECREMENT_DEPRECATED_WARNINGS
522#define DECREMENT_DEPRECATED_WARNINGS_TEXT "The current decrement operator has the unintended behavior that it stays\
523 valid when iterating below the start and will visit the first entity\
524 twice before getting invalid. Furthermore it gets valid again, if you\
525 increment at the end.\
526 When you are sure that you don't iterate below the start anywhere in\
527 your code or rely on this behaviour, you can disable this warning by\
528 setting the define NO_DECREMENT_DEPRECATED_WARNINGS at the command line (or enable it via the\
530 To be save, you can use the CW/CCW circulator definitions, which behave\
531 the same as the original ones, without the previously mentioned issues."
533 OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
537 GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
550#ifndef NO_DECREMENT_DEPRECATED_WARNINGS
551 OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
552#undef DECREMENT_DEPRECATED_WARNINGS_TEXT
564 assert(this->heh_.is_valid());
565 ValueHandle res = (GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_));
566 assert(res.is_valid());
569 return make_smart(GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_);
582 pointer_deref_value = **
this;
583 return &pointer_deref_value;
591 bool operator==(
const GenericCirculatorT_DEPRECATED &rhs)
const {
592 return GenericCirculatorBaseT<Mesh>::operator==(rhs);
595 bool operator!=(
const GenericCirculatorT_DEPRECATED &rhs)
const {
596 return GenericCirculatorBaseT<Mesh>::operator!=(rhs);
599 bool is_valid()
const {
600 return GenericCirculator_ValueHandleFns::is_valid(this->heh_,this->start_, this->lap_counter_);
603 OM_DEPRECATED(
"current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.")
613 OM_DEPRECATED(
"Do not use this error prone implicit cast. Compare to end-iterator or use is_valid(), instead.")
619 operator
bool()
const {
628 OM_DEPRECATED(
"This function clutters your code. Use dereferencing operators -> and * instead.")
639 OM_DEPRECATED(
"Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
640 operator ValueHandle()
const {
644 template<
typename STREAM>
646 return s << self.mesh_ <<
", " << self.start_.idx() <<
", " << self.heh_.idx() <<
", " << self.lap_counter_;
650 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
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:240
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:542
const Mesh::HalfedgeHandle & current_halfedge_handle() const
Definition CirculatorsT.hh:609
pointer operator->() const
Pointer dereferentiation.
Definition CirculatorsT.hh:581
GenericCirculatorT_DEPRECATED operator--(int)
Post-decrement.
Definition CirculatorsT.hh:554
smart_value_type operator*() const
Standard dereferencing operator.
Definition CirculatorsT.hh:562
smart_value_type handle() const
Return the handle of the current target.
Definition CirculatorsT.hh:629
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
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