55 #include <OpenMesh/Core/System/config.h>
64 template <
typename>
class CirculatorRange;
68 template<
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);
108 heh = mesh->ccw_rotated_halfedge_handle(heh);
109 if (heh == start) ++lap_counter;
112 if (heh == start) --lap_counter;
113 heh = mesh->cw_rotated_halfedge_handle(heh);
121 heh = mesh->prev_halfedge_handle(heh);
122 if (heh == start) ++lap_counter;
125 if (heh == start) --lap_counter;
126 heh = mesh->next_halfedge_handle(heh);
131 template<
class Mesh,
class CenterEntityHandle,
class ValueHandle>
141 return mesh->face_handle(mesh->opposite_halfedge_handle(heh)).is_valid();
149 return mesh->face_handle(heh).is_valid();
153 template<
class Mesh,
class CenterEntityHandle,
class ValueHandle,
bool CW = true>
157 return ( heh.is_valid() && (lap_counter == 0 ) );
166 int lc = lap_counter;
167 increment(mesh, heh, start, lap_counter);
182 template<
class Mesh,
class CenterEntityHandle,
bool CW>
188 return ( heh.is_valid() && (lap_counter == 0));
197 int lc = lap_counter;
198 increment(mesh, heh, start, lap_counter);
203 if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
204 increment(mesh, heh, start, lap_counter);
209 }
while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
214 }
while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
230 mesh_(&mesh), start_(heh), heh_(heh), lap_counter_(
static_cast<int>(end && heh.is_valid())) {}
233 mesh_(rhs.mesh_), start_(rhs.start_), heh_(rhs.heh_), lap_counter_(rhs.lap_counter_) {}
236 return mesh_->face_handle(heh_);
240 return mesh_->face_handle(toOppositeHalfedgeHandle());
244 return mesh_->edge_handle(heh_);
252 return mesh_->opposite_halfedge_handle(heh_);
256 return mesh_->to_vertex_handle(heh_);
263 lap_counter_ = rhs.lap_counter_;
268 return mesh_ == rhs.mesh_ && start_ == rhs.start_ && heh_ == rhs.heh_ && lap_counter_ == rhs.lap_counter_;
272 return !operator==(rhs);
283 template <
typename GenericCirculatorT_TraitsT,
bool CW = true>
286 using Mesh =
typename GenericCirculatorT_TraitsT::Mesh;
287 using value_type =
typename GenericCirculatorT_TraitsT::ValueHandle;
288 using CenterEntityHandle =
typename GenericCirculatorT_TraitsT::CenterEntityHandle;
290 using smart_value_type = decltype(
make_smart(std::declval<value_type>(), std::declval<Mesh>()));
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;
308 bool adjust_for_ccw =
true;
309 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_, adjust_for_ccw);
314 bool adjust_for_ccw =
false;
315 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_, adjust_for_ccw);
325 GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
330 GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
353 assert(this->heh_.is_valid());
354 value_type res = GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_);
355 assert(res.is_valid());
358 return make_smart(GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_);
371 pointer_deref_value = **
this;
372 return &pointer_deref_value;
380 bool operator==(
const GenericCirculatorT &rhs)
const {
381 return GenericCirculatorBaseT<Mesh>::operator==(rhs);
384 bool operator!=(
const GenericCirculatorT &rhs)
const {
385 return GenericCirculatorBaseT<Mesh>::operator!=(rhs);
388 bool is_valid()
const {
389 return GenericCirculator_ValueHandleFns::is_valid(this->heh_, this->lap_counter_);
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_;
398 mutable smart_value_type pointer_deref_value;
422 template<
class Mesh,
class CenterEntityHandle,
class ValueHandle>
426 return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 )) );
437 template<
class Mesh,
class CenterEntityHandle>
443 return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 )));
446 if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
447 increment(mesh, heh, start, lap_counter);
452 }
while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
457 }
while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
461 template <
typename GenericCirculatorT_DEPRECATED_TraitsT>
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>()));
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;
485 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
490 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
496 GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
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\
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."
511 OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
515 GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
528 #ifndef NO_DECREMENT_DEPRECATED_WARNINGS
529 OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
530 #undef DECREMENT_DEPRECATED_WARNINGS_TEXT
542 assert(this->heh_.is_valid());
543 value_type res = (GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_));
544 assert(res.is_valid());
547 return make_smart(GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_);
560 pointer_deref_value = **
this;
561 return &pointer_deref_value;
569 bool operator==(
const GenericCirculatorT_DEPRECATED &rhs)
const {
570 return GenericCirculatorBaseT<Mesh>::operator==(rhs);
573 bool operator!=(
const GenericCirculatorT_DEPRECATED &rhs)
const {
574 return GenericCirculatorBaseT<Mesh>::operator!=(rhs);
577 bool is_valid()
const {
578 return GenericCirculator_ValueHandleFns::is_valid(this->heh_,this->start_, this->lap_counter_);
581 OM_DEPRECATED(
"current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.")
591 OM_DEPRECATED(
"Do not use this error prone implicit cast. Compare to end-iterator or use is_valid(), instead.")
597 operator
bool()
const {
606 OM_DEPRECATED(
"This function clutters your code. Use dereferencing operators -> and * instead.")
617 OM_DEPRECATED(
"Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
618 operator value_type()
const {
622 template<
typename STREAM>
624 return s <<
self.mesh_ <<
", " <<
self.start_.idx() <<
", " <<
self.heh_.idx() <<
", " <<
self.lap_counter_;
628 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:256
auto operator<<(std::ostream &os, const VectorT< Scalar, DIM > &_vec) -> typename std::enable_if< sizeof(decltype(os<< _vec[0])) >=0
output a vector by printing its space-separated compontens
Generic class for iterator ranges.
Definition: PolyConnectivity_inline_impl.hh:92
Definition: CirculatorsT.hh:69
Definition: CirculatorsT.hh:132
Definition: CirculatorsT.hh:154
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
Definition: CirculatorsT.hh:423
Definition: CirculatorsT.hh:462
const Mesh::HalfedgeHandle & current_halfedge_handle() const
Definition: CirculatorsT.hh:587
GenericCirculatorT_DEPRECATED operator++(int)
Post-increment.
Definition: CirculatorsT.hh:520
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