65 template<
class Mesh,
class CenterEntityHandle,
bool CW>
68 static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter);
69 static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter);
75 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
76 heh = mesh->cw_rotated_halfedge_handle(heh);
77 if (heh == start) ++lap_counter;
79 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
80 if (heh == start) --lap_counter;
81 heh = mesh->ccw_rotated_halfedge_handle(heh);
88 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
89 heh = mesh->next_halfedge_handle(heh);
90 if (heh == start) ++lap_counter;
92 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
93 if (heh == start) --lap_counter;
94 heh = mesh->prev_halfedge_handle(heh);
104 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
105 heh = mesh->ccw_rotated_halfedge_handle(heh);
106 if (heh == start) ++lap_counter;
108 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
109 if (heh == start) --lap_counter;
110 heh = mesh->cw_rotated_halfedge_handle(heh);
117 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
118 heh = mesh->prev_halfedge_handle(heh);
119 if (heh == start) ++lap_counter;
121 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
122 if (heh == start) --lap_counter;
123 heh = mesh->next_halfedge_handle(heh);
128 template<
class Mesh,
class CenterEntityHandle,
class ValueHandle>
137 inline static bool isDereferenciable(
const Mesh *mesh,
const typename Mesh::HalfedgeHandle &heh) {
138 return mesh->face_handle(mesh->opposite_halfedge_handle(heh)).is_valid();
145 inline static bool isDereferenciable(
const Mesh *mesh,
const typename Mesh::HalfedgeHandle &heh) {
146 return mesh->face_handle(heh).is_valid();
150 template<
class Mesh,
class CenterEntityHandle,
class ValueHandle,
bool CW = true>
153 inline static bool is_valid(
const typename Mesh::HalfedgeHandle &heh,
const int lap_counter) {
154 return ( heh.is_valid() && (lap_counter == 0 ) );
156 inline static void init(
const Mesh*,
typename Mesh::HalfedgeHandle&,
typename Mesh::HalfedgeHandle&,
int&) {};
157 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
160 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
165 template<
class Mesh,
class CenterEntityHandle,
bool CW>
170 inline static bool is_valid(
const typename Mesh::HalfedgeHandle &heh,
const int lap_counter) {
171 return ( heh.is_valid() && (lap_counter == 0));
173 inline static void init(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
174 if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
175 increment(mesh, heh, start, lap_counter);
177 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
180 }
while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
182 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
185 }
while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
199 mesh_(&mesh), start_(heh), heh_(heh), lap_counter_(static_cast<int>(end && heh.is_valid())) {}
202 mesh_(rhs.mesh_), start_(rhs.start_), heh_(rhs.heh_), lap_counter_(rhs.lap_counter_) {}
204 inline typename Mesh::FaceHandle toFaceHandle()
const {
205 return mesh_->face_handle(heh_);
208 inline typename Mesh::FaceHandle toOppositeFaceHandle()
const {
209 return mesh_->face_handle(toOppositeHalfedgeHandle());
212 inline typename Mesh::EdgeHandle toEdgeHandle()
const {
213 return mesh_->edge_handle(heh_);
216 inline typename Mesh::HalfedgeHandle toHalfedgeHandle()
const {
220 inline typename Mesh::HalfedgeHandle toOppositeHalfedgeHandle()
const {
221 return mesh_->opposite_halfedge_handle(heh_);
225 return mesh_->to_vertex_handle(heh_);
232 lap_counter_ = rhs.lap_counter_;
237 return mesh_ == rhs.mesh_ && start_ == rhs.start_ && heh_ == rhs.heh_ && lap_counter_ == rhs.lap_counter_;
241 return !operator==(rhs);
246 typename Mesh::HalfedgeHandle start_, heh_;
252 template <
typename GenericCirculatorT_TraitsT,
bool CW = true>
255 using Mesh =
typename GenericCirculatorT_TraitsT::Mesh;
256 using value_type =
typename GenericCirculatorT_TraitsT::ValueHandle;
257 using CenterEntityHandle =
typename GenericCirculatorT_TraitsT::CenterEntityHandle;
259 using smart_value_type = decltype(
make_smart(std::declval<value_type>(), std::declval<Mesh>()));
261 typedef std::ptrdiff_t difference_type;
262 typedef const value_type& reference;
263 typedef const smart_value_type* pointer;
264 typedef std::bidirectional_iterator_tag iterator_category;
275 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
277 GenericCirculatorT(mesh_ref mesh,
typename Mesh::HalfedgeHandle heh,
bool end =
false) :
280 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
288 GenericCirculatorT& operator++() {
290 GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
293 GenericCirculatorT& operator--() {
295 GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
302 GenericCirculatorT cpy(*
this);
310 GenericCirculatorT cpy(*
this);
318 assert(this->heh_.is_valid());
319 value_type res = GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_);
320 assert(res.is_valid());
323 return make_smart(GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_);
336 pointer_deref_value = **
this;
337 return &pointer_deref_value;
340 GenericCirculatorT &operator=(
const GenericCirculatorT &rhs) {
345 bool operator==(
const GenericCirculatorT &rhs)
const {
349 bool operator!=(
const GenericCirculatorT &rhs)
const {
353 bool is_valid()
const {
354 return GenericCirculator_ValueHandleFns::is_valid(this->heh_, this->lap_counter_);
357 template<
typename STREAM>
358 friend STREAM &
operator<< (STREAM &s,
const GenericCirculatorT &
self) {
359 return s <<
self.mesh_ <<
", " <<
self.start_.idx() <<
", " <<
self.heh_.idx() <<
", " <<
self.lap_counter_;
363 mutable smart_value_type pointer_deref_value;
387 template<
class Mesh,
class CenterEntityHandle,
class ValueHandle>
390 inline static bool is_valid(
const typename Mesh::HalfedgeHandle &heh,
const typename Mesh::HalfedgeHandle &start,
const int lap_counter) {
391 return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 )) );
393 inline static void init(
const Mesh*,
typename Mesh::HalfedgeHandle&,
typename Mesh::HalfedgeHandle&,
int&) {};
394 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
397 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
402 template<
class Mesh,
class CenterEntityHandle>
407 inline static bool is_valid(
const typename Mesh::HalfedgeHandle &heh,
const typename Mesh::HalfedgeHandle &start,
const int lap_counter) {
408 return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 )));
410 inline static void init(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
411 if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
412 increment(mesh, heh, start, lap_counter);
414 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
417 }
while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
419 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
422 }
while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
426 template <
typename GenericCirculatorT_DEPRECATED_TraitsT>
429 using Mesh =
typename GenericCirculatorT_DEPRECATED_TraitsT::Mesh;
430 using CenterEntityHandle =
typename GenericCirculatorT_DEPRECATED_TraitsT::CenterEntityHandle;
431 using value_type =
typename GenericCirculatorT_DEPRECATED_TraitsT::ValueHandle;
432 using smart_value_type = decltype (
make_smart(std::declval<value_type>(), std::declval<Mesh>()));
434 typedef std::ptrdiff_t difference_type;
435 typedef const value_type& reference;
436 typedef const smart_value_type* pointer;
437 typedef std::bidirectional_iterator_tag iterator_category;
448 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
453 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
459 GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
462 #ifndef NO_DECREMENT_DEPRECATED_WARNINGS 463 #define DECREMENT_DEPRECATED_WARNINGS_TEXT "The current decrement operator has the unintended behavior that it stays\ 464 valid when iterating below the start and will visit the first entity\ 465 twice before getting invalid. Furthermore it gets valid again, if you\ 466 increment at the end.\ 467 When you are sure that you don't iterate below the start anywhere in\ 468 your code or rely on this behaviour, you can disable this warning by\ 469 setting the define NO_DECREMENT_DEPRECATED_WARNINGS at the command line (or enable it via the\ 471 To be save, you can use the CW/CCW circulator definitions, which behave\ 472 the same as the original ones, without the previously mentioned issues." 475 #endif // NO_DECREMENT_DEPRECATED_WARNINGS 478 GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
491 #ifndef NO_DECREMENT_DEPRECATED_WARNINGS 493 #undef DECREMENT_DEPRECATED_WARNINGS_TEXT 494 #endif //NO_DECREMENT_DEPRECATED_WARNINGS 505 assert(this->heh_.is_valid());
506 value_type res = (GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_));
507 assert(res.is_valid());
510 return make_smart(GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_);
523 pointer_deref_value = **
this;
524 return &pointer_deref_value;
540 bool is_valid()
const {
541 return GenericCirculator_ValueHandleFns::is_valid(this->heh_,this->start_, this->lap_counter_);
544 OM_DEPRECATED(
"current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.")
554 OM_DEPRECATED(
"Do not use this error prone implicit cast. Compare to end-iterator or use is_valid(), instead.")
560 operator
bool()
const {
569 OM_DEPRECATED(
"This function clutters your code. Use dereferencing operators -> and * instead.")
570 smart_value_type handle()
const {
580 OM_DEPRECATED(
"Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
581 operator value_type()
const {
585 template<
typename STREAM>
587 return s <<
self.mesh_ <<
", " <<
self.start_.idx() <<
", " <<
self.heh_.idx() <<
", " <<
self.lap_counter_;
591 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.
SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity *_mesh)
Creats a SmartVertexHandle from a VertexHandle and a Mesh.
#define OM_DEPRECATED(msg)
define OM_SUPPRESS_DEPRECATED to suppress deprecated code warnings
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.