56 #include <OpenMesh/Core/Mesh/SmartHandles.hh> 66 template<
class Mesh,
class CenterEntityHandle,
bool CW>
69 static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter);
70 static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter);
76 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
77 heh = mesh->cw_rotated_halfedge_handle(heh);
78 if (heh == start) ++lap_counter;
80 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
81 if (heh == start) --lap_counter;
82 heh = mesh->ccw_rotated_halfedge_handle(heh);
89 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
90 heh = mesh->next_halfedge_handle(heh);
91 if (heh == start) ++lap_counter;
93 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
94 if (heh == start) --lap_counter;
95 heh = mesh->prev_halfedge_handle(heh);
105 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
106 heh = mesh->ccw_rotated_halfedge_handle(heh);
107 if (heh == start) ++lap_counter;
109 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
110 if (heh == start) --lap_counter;
111 heh = mesh->cw_rotated_halfedge_handle(heh);
118 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
119 heh = mesh->prev_halfedge_handle(heh);
120 if (heh == start) ++lap_counter;
122 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
123 if (heh == start) --lap_counter;
124 heh = mesh->next_halfedge_handle(heh);
129 template<
class Mesh,
class CenterEntityHandle,
class ValueHandle>
138 inline static bool isDereferenciable(
const Mesh *mesh,
const typename Mesh::HalfedgeHandle &heh) {
139 return mesh->face_handle(mesh->opposite_halfedge_handle(heh)).is_valid();
146 inline static bool isDereferenciable(
const Mesh *mesh,
const typename Mesh::HalfedgeHandle &heh) {
147 return mesh->face_handle(heh).is_valid();
151 template<
class Mesh,
class CenterEntityHandle,
class ValueHandle,
bool CW = true>
154 inline static bool is_valid(
const typename Mesh::HalfedgeHandle &heh,
const int lap_counter) {
155 return ( heh.is_valid() && (lap_counter == 0 ) );
157 inline static void init(
const Mesh*,
typename Mesh::HalfedgeHandle&,
typename Mesh::HalfedgeHandle&,
int&) {};
158 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
161 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
166 template<
class Mesh,
class CenterEntityHandle,
bool CW>
171 inline static bool is_valid(
const typename Mesh::HalfedgeHandle &heh,
const int lap_counter) {
172 return ( heh.is_valid() && (lap_counter == 0));
174 inline static void init(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
175 if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
176 increment(mesh, heh, start, lap_counter);
178 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
181 }
while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
183 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
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_) {}
205 inline typename Mesh::FaceHandle toFaceHandle()
const {
206 return mesh_->face_handle(heh_);
209 inline typename Mesh::FaceHandle toOppositeFaceHandle()
const {
210 return mesh_->face_handle(toOppositeHalfedgeHandle());
213 inline typename Mesh::EdgeHandle toEdgeHandle()
const {
214 return mesh_->edge_handle(heh_);
217 inline typename Mesh::HalfedgeHandle toHalfedgeHandle()
const {
221 inline typename Mesh::HalfedgeHandle toOppositeHalfedgeHandle()
const {
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);
247 typename Mesh::HalfedgeHandle start_, heh_;
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_);
289 GenericCirculatorT& operator++() {
291 GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
294 GenericCirculatorT& operator--() {
296 GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
303 GenericCirculatorT cpy(*
this);
311 GenericCirculatorT cpy(*
this);
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;
341 GenericCirculatorT &operator=(
const GenericCirculatorT &rhs) {
346 bool operator==(
const GenericCirculatorT &rhs)
const {
350 bool operator!=(
const GenericCirculatorT &rhs)
const {
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>
391 inline static bool is_valid(
const typename Mesh::HalfedgeHandle &heh,
const typename Mesh::HalfedgeHandle &start,
const int lap_counter) {
392 return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 )) );
394 inline static void init(
const Mesh*,
typename Mesh::HalfedgeHandle&,
typename Mesh::HalfedgeHandle&,
int&) {};
395 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
398 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
403 template<
class Mesh,
class CenterEntityHandle>
408 inline static bool is_valid(
const typename Mesh::HalfedgeHandle &heh,
const typename Mesh::HalfedgeHandle &start,
const int lap_counter) {
409 return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 )));
411 inline static void init(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
412 if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
413 increment(mesh, heh, start, lap_counter);
415 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
418 }
while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
420 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
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 )
476 #endif // NO_DECREMENT_DEPRECATED_WARNINGS 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 495 #endif //NO_DECREMENT_DEPRECATED_WARNINGS 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;
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.")
571 smart_value_type handle()
const {
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;
Handle for a face entity.
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
Handle for a halfedge entity.
pointer operator->() const
Pointer dereferentiation.
GenericCirculatorT_DEPRECATED operator--(int)
Post-decrement.
smart_value_type operator*() const
Standard dereferencing operator.
Handle for a vertex entity.
bool is_valid() const
The handle is valid iff the index is not negative.
SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity *_mesh)
Creats a SmartVertexHandle from a VertexHandle and a Mesh.
GenericCirculatorT operator++(int)
Post-increment.
smart_value_type operator*() const
Standard dereferencing operator.
pointer operator->() const
Pointer dereferentiation.
GenericCirculatorT_DEPRECATED operator++(int)
Post-increment.
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
GenericCirculatorT operator--(int)
Post-decrement.