55 #include <OpenMesh/Core/System/config.h>
56 #include <OpenMesh/Core/Mesh/SmartHandles.hh>
66 template<
class Mesh,
class CenterEntityHandle,
bool CW>
77 heh = mesh->cw_rotated_halfedge_handle(heh);
78 if (heh == start) ++lap_counter;
81 if (heh == start) --lap_counter;
82 heh = mesh->ccw_rotated_halfedge_handle(heh);
90 heh = mesh->next_halfedge_handle(heh);
91 if (heh == start) ++lap_counter;
94 if (heh == start) --lap_counter;
95 heh = mesh->prev_halfedge_handle(heh);
106 heh = mesh->ccw_rotated_halfedge_handle(heh);
107 if (heh == start) ++lap_counter;
110 if (heh == start) --lap_counter;
111 heh = mesh->cw_rotated_halfedge_handle(heh);
119 heh = mesh->prev_halfedge_handle(heh);
120 if (heh == start) ++lap_counter;
123 if (heh == start) --lap_counter;
124 heh = mesh->next_halfedge_handle(heh);
129 template<
class Mesh,
class CenterEntityHandle,
class ValueHandle>
139 return mesh->face_handle(mesh->opposite_halfedge_handle(heh)).is_valid();
147 return mesh->face_handle(heh).is_valid();
151 template<
class Mesh,
class CenterEntityHandle,
class ValueHandle,
bool CW = true>
155 return ( heh.is_valid() && (lap_counter == 0 ) );
166 template<
class Mesh,
class CenterEntityHandle,
bool CW>
172 return ( heh.is_valid() && (lap_counter == 0));
175 if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
176 increment(mesh, heh, start, lap_counter);
181 }
while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
186 }
while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
200 mesh_(&mesh), start_(heh), heh_(heh), lap_counter_(
static_cast<int>(end && heh.is_valid())) {}
203 mesh_(rhs.mesh_), start_(rhs.start_), heh_(rhs.heh_), lap_counter_(rhs.lap_counter_) {}
206 return mesh_->face_handle(heh_);
210 return mesh_->face_handle(toOppositeHalfedgeHandle());
214 return mesh_->edge_handle(heh_);
222 return mesh_->opposite_halfedge_handle(heh_);
226 return mesh_->to_vertex_handle(heh_);
233 lap_counter_ = rhs.lap_counter_;
238 return mesh_ == rhs.mesh_ && start_ == rhs.start_ && heh_ == rhs.heh_ && lap_counter_ == rhs.lap_counter_;
242 return !operator==(rhs);
253 template <
typename GenericCirculatorT_TraitsT,
bool CW = true>
256 using Mesh =
typename GenericCirculatorT_TraitsT::Mesh;
257 using value_type =
typename GenericCirculatorT_TraitsT::ValueHandle;
258 using CenterEntityHandle =
typename GenericCirculatorT_TraitsT::CenterEntityHandle;
260 using smart_value_type = decltype(
make_smart(std::declval<value_type>(), std::declval<Mesh>()));
262 typedef std::ptrdiff_t difference_type;
263 typedef const value_type& reference;
264 typedef const smart_value_type* pointer;
265 typedef std::bidirectional_iterator_tag iterator_category;
276 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
281 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
291 GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
296 GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
319 assert(this->heh_.is_valid());
320 value_type res = GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_);
321 assert(res.is_valid());
324 return make_smart(GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_);
337 pointer_deref_value = **
this;
338 return &pointer_deref_value;
346 bool operator==(
const GenericCirculatorT &rhs)
const {
347 return GenericCirculatorBaseT<Mesh>::operator==(rhs);
350 bool operator!=(
const GenericCirculatorT &rhs)
const {
351 return GenericCirculatorBaseT<Mesh>::operator!=(rhs);
354 bool is_valid()
const {
355 return GenericCirculator_ValueHandleFns::is_valid(this->heh_, this->lap_counter_);
358 template<
typename STREAM>
359 friend STREAM &operator<< (STREAM &s,
const GenericCirculatorT &
self) {
360 return s <<
self.mesh_ <<
", " <<
self.start_.idx() <<
", " <<
self.heh_.idx() <<
", " <<
self.lap_counter_;
364 mutable smart_value_type pointer_deref_value;
388 template<
class Mesh,
class CenterEntityHandle,
class ValueHandle>
392 return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 )) );
403 template<
class Mesh,
class CenterEntityHandle>
409 return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 )));
412 if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
413 increment(mesh, heh, start, lap_counter);
418 }
while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
423 }
while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
427 template <
typename GenericCirculatorT_DEPRECATED_TraitsT>
430 using Mesh =
typename GenericCirculatorT_DEPRECATED_TraitsT::Mesh;
431 using CenterEntityHandle =
typename GenericCirculatorT_DEPRECATED_TraitsT::CenterEntityHandle;
432 using value_type =
typename GenericCirculatorT_DEPRECATED_TraitsT::ValueHandle;
433 using smart_value_type = decltype (
make_smart(std::declval<value_type>(), std::declval<Mesh>()));
435 typedef std::ptrdiff_t difference_type;
436 typedef const value_type& reference;
437 typedef const smart_value_type* pointer;
438 typedef std::bidirectional_iterator_tag iterator_category;
449 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
454 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
460 GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
463 #ifndef NO_DECREMENT_DEPRECATED_WARNINGS
464 #define DECREMENT_DEPRECATED_WARNINGS_TEXT "The current decrement operator has the unintended behavior that it stays\
465 valid when iterating below the start and will visit the first entity\
466 twice before getting invalid. Furthermore it gets valid again, if you\
467 increment at the end.\
468 When you are sure that you don't iterate below the start anywhere in\
469 your code or rely on this behaviour, you can disable this warning by\
470 setting the define NO_DECREMENT_DEPRECATED_WARNINGS at the command line (or enable it via the\
472 To be save, you can use the CW/CCW circulator definitions, which behave\
473 the same as the original ones, without the previously mentioned issues."
475 OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
479 GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
492 #ifndef NO_DECREMENT_DEPRECATED_WARNINGS
493 OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
494 #undef DECREMENT_DEPRECATED_WARNINGS_TEXT
506 assert(this->heh_.is_valid());
507 value_type res = (GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_));
508 assert(res.is_valid());
511 return make_smart(GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_);
524 pointer_deref_value = **
this;
525 return &pointer_deref_value;
533 bool operator==(
const GenericCirculatorT_DEPRECATED &rhs)
const {
534 return GenericCirculatorBaseT<Mesh>::operator==(rhs);
537 bool operator!=(
const GenericCirculatorT_DEPRECATED &rhs)
const {
538 return GenericCirculatorBaseT<Mesh>::operator!=(rhs);
541 bool is_valid()
const {
542 return GenericCirculator_ValueHandleFns::is_valid(this->heh_,this->start_, this->lap_counter_);
545 OM_DEPRECATED(
"current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.")
555 OM_DEPRECATED(
"Do not use this error prone implicit cast. Compare to end-iterator or use is_valid(), instead.")
561 operator
bool()
const {
570 OM_DEPRECATED(
"This function clutters your code. Use dereferencing operators -> and * instead.")
581 OM_DEPRECATED(
"Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
582 operator value_type()
const {
586 template<
typename STREAM>
588 return s <<
self.mesh_ <<
", " <<
self.start_.idx() <<
", " <<
self.heh_.idx() <<
", " <<
self.lap_counter_;
592 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:186
Definition: CirculatorsT.hh:67
Definition: CirculatorsT.hh:130
Definition: CirculatorsT.hh:152
Definition: CirculatorsT.hh:191
Definition: CirculatorsT.hh:254
smart_value_type operator*() const
Standard dereferencing operator.
Definition: CirculatorsT.hh:317
GenericCirculatorT operator++(int)
Post-increment.
Definition: CirculatorsT.hh:301
GenericCirculatorT operator--(int)
Post-decrement.
Definition: CirculatorsT.hh:309
pointer operator->() const
Pointer dereferentiation.
Definition: CirculatorsT.hh:336
Definition: CirculatorsT.hh:389
Definition: CirculatorsT.hh:428
GenericCirculatorT_DEPRECATED operator++(int)
Post-increment.
Definition: CirculatorsT.hh:484
const HalfedgeHandle & current_halfedge_handle() const
Definition: CirculatorsT.hh:551
pointer operator->() const
Pointer dereferentiation.
Definition: CirculatorsT.hh:523
GenericCirculatorT_DEPRECATED operator--(int)
Post-decrement.
Definition: CirculatorsT.hh:496
smart_value_type operator*() const
Standard dereferencing operator.
Definition: CirculatorsT.hh:504
smart_value_type handle() const
Return the handle of the current target.
Definition: CirculatorsT.hh:571
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