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 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;
506 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
511 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
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 )
536 GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
549#ifndef NO_DECREMENT_DEPRECATED_WARNINGS
550 OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
551#undef DECREMENT_DEPRECATED_WARNINGS_TEXT
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;
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
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: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: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
Return the handle of the current target.
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
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