42 #ifndef OPENMESH_CIRCULATORS_HH
43 #define OPENMESH_CIRCULATORS_HH
54 #include <OpenMesh/Core/System/config.h>
64 template<
class Mesh,
class CenterEntityHandle>
67 static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter);
68 static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter);
74 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
75 heh = mesh->cw_rotated_halfedge_handle(heh);
76 if (heh == start) ++lap_counter;
78 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
79 if (heh == start) --lap_counter;
80 heh = mesh->ccw_rotated_halfedge_handle(heh);
87 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
88 heh = mesh->next_halfedge_handle(heh);
89 if (heh == start) ++lap_counter;
91 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
92 if (heh == start) --lap_counter;
93 heh = mesh->prev_halfedge_handle(heh);
97 template<
class Mesh,
class CenterEntityHandle,
class ValueHandle>
106 inline static bool isDereferenciable(
const Mesh *mesh,
const typename Mesh::HalfedgeHandle &heh) {
107 return mesh->face_handle(mesh->opposite_halfedge_handle(heh)).is_valid();
114 inline static bool isDereferenciable(
const Mesh *mesh,
const typename Mesh::HalfedgeHandle &heh) {
115 return mesh->face_handle(heh).
is_valid();
119 template<
class Mesh,
class CenterEntityHandle,
class ValueHandle>
122 inline static bool is_valid(
const typename Mesh::HalfedgeHandle &heh,
const typename Mesh::HalfedgeHandle &start,
const int &lap_counter) {
123 return heh.is_valid() && ((start != heh) || (lap_counter == 0));
125 inline static void init(
const Mesh*,
typename Mesh::HalfedgeHandle&,
typename Mesh::HalfedgeHandle&,
int&) {};
126 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
129 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
134 template<
class Mesh,
class CenterEntityHandle>
139 inline static bool is_valid(
const typename Mesh::HalfedgeHandle &heh,
const typename Mesh::HalfedgeHandle &start,
const int &lap_counter) {
140 return heh.is_valid() && ((start != heh) || (lap_counter == 0));
142 inline static void init(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
143 if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0)
144 increment(mesh, heh, start, lap_counter);
146 inline static void increment(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
149 }
while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
151 inline static void decrement(
const Mesh *mesh,
typename Mesh::HalfedgeHandle &heh,
typename Mesh::HalfedgeHandle &start,
int &lap_counter) {
154 }
while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
161 typedef const Mesh* mesh_ptr;
162 typedef const Mesh& mesh_ref;
168 mesh_(&mesh), start_(heh), heh_(heh), lap_counter_(static_cast<int>(end)) {}
171 mesh_(rhs.mesh_), start_(rhs.start_), heh_(rhs.heh_), lap_counter_(rhs.lap_counter_) {}
173 inline typename Mesh::FaceHandle toFaceHandle()
const {
174 return mesh_->face_handle(heh_);
177 inline typename Mesh::FaceHandle toOppositeFaceHandle()
const {
178 return mesh_->face_handle(toOppositeHalfedgeHandle());
181 inline typename Mesh::EdgeHandle toEdgeHandle()
const {
182 return mesh_->edge_handle(heh_);
185 inline typename Mesh::HalfedgeHandle toHalfedgeHandle()
const {
189 inline typename Mesh::HalfedgeHandle toOppositeHalfedgeHandle()
const {
190 return mesh_->opposite_halfedge_handle(heh_);
193 inline typename Mesh::VertexHandle toVertexHandle()
const {
194 return mesh_->to_vertex_handle(heh_);
201 lap_counter_ = rhs.lap_counter_;
206 return mesh_ == rhs.mesh_ && start_ == rhs.start_ && heh_ == rhs.heh_ && lap_counter_ == rhs.lap_counter_;
210 return !operator==(rhs);
215 typename Mesh::HalfedgeHandle start_, heh_;
219 template<
class Mesh,
class CenterEntityHandle,
class ValueHandle,
223 typedef std::ptrdiff_t difference_type;
224 typedef ValueHandle value_type;
225 typedef const value_type& reference;
226 typedef const value_type* pointer;
227 typedef std::bidirectional_iterator_tag iterator_category;
229 typedef typename GenericCirculatorBaseT<Mesh>::mesh_ptr mesh_ptr;
230 typedef typename GenericCirculatorBaseT<Mesh>::mesh_ref mesh_ref;
238 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
243 GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
249 GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
254 GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
277 assert(this->heh_.is_valid());
278 value_type res = (this->*Handle2Value)();
279 assert(res.is_valid());
282 return (this->*Handle2Value)();
295 pointer_deref_value = **
this;
296 return &pointer_deref_value;
304 bool operator==(
const GenericCirculatorT &rhs)
const {
305 return GenericCirculatorBaseT<Mesh>::operator==(rhs);
308 bool operator!=(
const GenericCirculatorT &rhs)
const {
309 return GenericCirculatorBaseT<Mesh>::operator!=(rhs);
312 bool is_valid()
const {
313 return GenericCirculator_ValueHandleFns::is_valid(this->heh_, this->start_, this->lap_counter_);
316 DEPRECATED(
"current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.")
326 DEPRECATED(
"Do not use this error prone implicit cast. Compare to end-iterator or use is_valid(), instead.")
332 operator
bool()
const {
341 DEPRECATED(
"This function clutters your code. Use dereferencing operators -> and * instead.")
342 value_type handle()
const {
352 DEPRECATED(
"Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
353 operator value_type()
const {
357 template<
typename STREAM>
359 return s <<
self.mesh_ <<
", " <<
self.start_.idx() <<
", " <<
self.heh_.idx() <<
", " <<
self.lap_counter_;
363 mutable value_type pointer_deref_value;
Definition: CirculatorsT.hh:98
bool is_valid() const
The handle is valid iff the index is not equal to -1.
Definition: Handles.hh:70
Definition: CirculatorsT.hh:120
Definition: CirculatorsT.hh:221
Handle for a halfedge entity.
Definition: Handles.hh:121
Definition: CirculatorsT.hh:159
pointer operator->() const
Pointer dereferentiation.
Definition: CirculatorsT.hh:294
GenericCirculatorT operator++(int)
Post-increment.
Definition: CirculatorsT.hh:259
GenericCirculatorT operator--(int)
Post-decrement.
Definition: CirculatorsT.hh:267
value_type operator*() const
Standard dereferencing operator.
Definition: CirculatorsT.hh:275
Handle for a face entity.
Definition: Handles.hh:135
std::ostream & operator<<(std::ostream &_os, const BaseHandle &_hnd)
Write handle _hnd to stream _os.
Definition: Handles.hh:104
Handle for a vertex entity.
Definition: Handles.hh:114
Definition: CirculatorsT.hh:65