Loading...
Searching...
No Matches
CirculatorsT.hh
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2022, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
#pragma once
//=============================================================================
//
// Vertex and Face circulators for PolyMesh/TriMesh
//
//=============================================================================
//== INCLUDES =================================================================
#include <OpenMesh/Core/System/config.h>
#include <cassert>
#include <cstddef>
#include <iterator>
//== NAMESPACES ===============================================================
namespace OpenMesh {
template <typename> class CirculatorRange;
namespace Iterators {
template<class Mesh, class CenterEntityHandle, bool CW>
class GenericCirculator_CenterEntityFnsT {
public:
static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter);
static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter);
};
template<class Mesh>
class GenericCirculator_CenterEntityFnsT<Mesh, typename Mesh::VertexHandle, true> {
public:
inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
heh = mesh->cw_rotated_halfedge_handle(heh);
if (heh == start) ++lap_counter;
}
inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
if (heh == start) --lap_counter;
heh = mesh->ccw_rotated_halfedge_handle(heh);
}
};
template<class Mesh>
class GenericCirculator_CenterEntityFnsT<Mesh, typename Mesh::FaceHandle, true> {
public:
inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
heh = mesh->next_halfedge_handle(heh);
if (heh == start) ++lap_counter;
}
inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
if (heh == start) --lap_counter;
heh = mesh->prev_halfedge_handle(heh);
}
};
// CCW
template<class Mesh>
class GenericCirculator_CenterEntityFnsT<Mesh, typename Mesh::VertexHandle, false> {
public:
inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
heh = mesh->ccw_rotated_halfedge_handle(heh);
if (heh == start) ++lap_counter;
}
inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
if (heh == start) --lap_counter;
heh = mesh->cw_rotated_halfedge_handle(heh);
}
};
template<class Mesh>
class GenericCirculator_CenterEntityFnsT<Mesh, typename Mesh::FaceHandle, false> {
public:
inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
heh = mesh->prev_halfedge_handle(heh);
if (heh == start) ++lap_counter;
}
inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
if (heh == start) --lap_counter;
heh = mesh->next_halfedge_handle(heh);
}
};
template<class Mesh, class CenterEntityHandle, class ValueHandle>
class GenericCirculator_DereferenciabilityCheckT {
public:
//inline static bool isDereferenciable(const Mesh *mesh, const typename Mesh::HalfedgeHandle &heh, const typename Mesh::HalfedgeHandle &start, const int &lap_counter);
};
template<class Mesh>
class GenericCirculator_DereferenciabilityCheckT<Mesh, typename Mesh::FaceHandle, typename Mesh::FaceHandle> {
public:
inline static bool isDereferenciable(const Mesh *mesh, const typename Mesh::HalfedgeHandle &heh) {
return mesh->face_handle(mesh->opposite_halfedge_handle(heh)).is_valid();
}
};
template<class Mesh>
class GenericCirculator_DereferenciabilityCheckT<Mesh, typename Mesh::VertexHandle, typename Mesh::FaceHandle> {
public:
inline static bool isDereferenciable(const Mesh *mesh, const typename Mesh::HalfedgeHandle &heh) {
return mesh->face_handle(heh).is_valid();
}
};
template<class Mesh, class CenterEntityHandle, class ValueHandle, bool CW = true>
class GenericCirculator_ValueHandleFnsT {
public:
inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const int lap_counter) {
return ( heh.is_valid() && (lap_counter == 0 ) );
}
inline static void init(const Mesh* mesh, typename Mesh::HalfedgeHandle& heh, typename Mesh::HalfedgeHandle& start, int& lap_counter, bool adjust_for_ccw)
{
if (!CW) // TODO: constexpr if
{
if (adjust_for_ccw)
{
// increment current heh and start so that cw and ccw version dont start with the same element but ranges are actually reversed
int lc = lap_counter;
increment(mesh, heh, start, lap_counter);
start = heh;
lap_counter = lc;
}
}
}
inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, CW>::increment(mesh, heh, start, lap_counter);
}
inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, CW>::decrement(mesh, heh, start, lap_counter);
}
};
template<class Mesh, class CenterEntityHandle, bool CW>
class GenericCirculator_ValueHandleFnsT<Mesh, CenterEntityHandle, typename Mesh::FaceHandle, CW> {
public:
typedef GenericCirculator_DereferenciabilityCheckT<Mesh, CenterEntityHandle, typename Mesh::FaceHandle> GenericCirculator_DereferenciabilityCheck;
inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const int lap_counter) {
return ( heh.is_valid() && (lap_counter == 0));
}
inline static void init(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter, bool adjust_for_ccw)
{
if (!CW) // TODO: constexpr if
{
if (adjust_for_ccw)
{
// increment current heh and start so that cw and ccw version dont start with the same element but ranges are actually reversed
int lc = lap_counter;
increment(mesh, heh, start, lap_counter);
start = heh;
lap_counter = lc;
}
}
if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
increment(mesh, heh, start, lap_counter);
};
inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
do {
GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, CW>::increment(mesh, heh, start, lap_counter);
} while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
}
inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
do {
GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, CW>::decrement(mesh, heh, start, lap_counter);
} while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
}
};
template<class Mesh>
class GenericCirculatorBaseT {
public:
typedef const Mesh* mesh_ptr;
typedef const Mesh& mesh_ref;
template <typename> friend class OpenMesh::CirculatorRange;
public:
GenericCirculatorBaseT() : mesh_(0), lap_counter_(0) {}
GenericCirculatorBaseT(mesh_ref mesh, typename Mesh::HalfedgeHandle heh, bool end = false) :
mesh_(&mesh), start_(heh), heh_(heh), lap_counter_(static_cast<int>(end && heh.is_valid())) {}
GenericCirculatorBaseT(const GenericCirculatorBaseT &rhs) :
mesh_(rhs.mesh_), start_(rhs.start_), heh_(rhs.heh_), lap_counter_(rhs.lap_counter_) {}
inline typename Mesh::FaceHandle toFaceHandle() const {
return mesh_->face_handle(heh_);
}
inline typename Mesh::FaceHandle toOppositeFaceHandle() const {
return mesh_->face_handle(toOppositeHalfedgeHandle());
}
inline typename Mesh::EdgeHandle toEdgeHandle() const {
return mesh_->edge_handle(heh_);
}
inline typename Mesh::HalfedgeHandle toHalfedgeHandle() const {
return heh_;
}
inline typename Mesh::HalfedgeHandle toOppositeHalfedgeHandle() const {
return mesh_->opposite_halfedge_handle(heh_);
}
inline typename Mesh::VertexHandle toVertexHandle() const {
return mesh_->to_vertex_handle(heh_);
}
inline GenericCirculatorBaseT &operator=(const GenericCirculatorBaseT &rhs) {
mesh_ = rhs.mesh_;
start_ = rhs.start_;
heh_ = rhs.heh_;
lap_counter_ = rhs.lap_counter_;
return *this;
}
inline bool operator==(const GenericCirculatorBaseT &rhs) const {
return mesh_ == rhs.mesh_ && start_ == rhs.start_ && heh_ == rhs.heh_ && lap_counter_ == rhs.lap_counter_;
}
inline bool operator!=(const GenericCirculatorBaseT &rhs) const {
return !operator==(rhs);
}
protected:
mesh_ptr mesh_;
typename Mesh::HalfedgeHandle start_, heh_;
int lap_counter_;
};
//template<class Mesh, class CenterEntityHandle, class ValueHandle,
// ValueHandle (GenericCirculatorBaseT<Mesh>::*Handle2Value)() const, bool CW = true >
template <typename GenericCirculatorT_TraitsT, bool CW = true>
class GenericCirculatorT : protected GenericCirculatorBaseT<typename GenericCirculatorT_TraitsT::Mesh> {
public:
using Mesh = typename GenericCirculatorT_TraitsT::Mesh;
using value_type = typename GenericCirculatorT_TraitsT::ValueHandle;
using CenterEntityHandle = typename GenericCirculatorT_TraitsT::CenterEntityHandle;
using smart_value_type = decltype(make_smart(std::declval<value_type>(), std::declval<Mesh>()));
typedef std::ptrdiff_t difference_type;
typedef const value_type& reference;
typedef const smart_value_type* pointer;
typedef std::bidirectional_iterator_tag iterator_category;
typedef typename GenericCirculatorBaseT<Mesh>::mesh_ptr mesh_ptr;
typedef typename GenericCirculatorBaseT<Mesh>::mesh_ref mesh_ref;
typedef GenericCirculator_ValueHandleFnsT<Mesh, CenterEntityHandle, value_type, CW> GenericCirculator_ValueHandleFns;
template <typename> friend class OpenMesh::CirculatorRange;
public:
GenericCirculatorT() {}
GenericCirculatorT(mesh_ref mesh, CenterEntityHandle start, bool end = false) :
GenericCirculatorBaseT<Mesh>(mesh, mesh.halfedge_handle(start), end)
{
bool adjust_for_ccw = true;
GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_, adjust_for_ccw);
}
GenericCirculatorT(mesh_ref mesh, typename Mesh::HalfedgeHandle heh, bool end = false) :
GenericCirculatorBaseT<Mesh>(mesh, heh, end)
{
bool adjust_for_ccw = false; // if iterator is initialized with specific heh, we want to start there
GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_, adjust_for_ccw);
}
GenericCirculatorT(const GenericCirculatorT &rhs) : GenericCirculatorBaseT<Mesh>(rhs) {}
friend class GenericCirculatorT<GenericCirculatorT_TraitsT,!CW>;
explicit GenericCirculatorT( const GenericCirculatorT<GenericCirculatorT_TraitsT,!CW>& rhs )
:GenericCirculatorBaseT<Mesh>(rhs){}
GenericCirculatorT& operator++() {
assert(this->mesh_);
GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
return *this;
}
GenericCirculatorT& operator--() {
assert(this->mesh_);
GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
return *this;
}
GenericCirculatorT operator++(int) {
assert(this->mesh_);
GenericCirculatorT cpy(*this);
++(*this);
return cpy;
}
GenericCirculatorT operator--(int) {
assert(this->mesh_);
GenericCirculatorT cpy(*this);
--(*this);
return cpy;
}
smart_value_type operator*() const {
#ifndef NDEBUG
assert(this->heh_.is_valid());
value_type res = GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_);
assert(res.is_valid());
return make_smart(res, this->mesh_);
#else
return make_smart(GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_);
#endif
}
pointer operator->() const {
pointer_deref_value = **this;
return &pointer_deref_value;
}
GenericCirculatorT &operator=(const GenericCirculatorT &rhs) {
GenericCirculatorBaseT<Mesh>::operator=(rhs);
return *this;
};
bool operator==(const GenericCirculatorT &rhs) const {
return GenericCirculatorBaseT<Mesh>::operator==(rhs);
}
bool operator!=(const GenericCirculatorT &rhs) const {
return GenericCirculatorBaseT<Mesh>::operator!=(rhs);
}
bool is_valid() const {
return GenericCirculator_ValueHandleFns::is_valid(this->heh_, this->lap_counter_);
}
template<typename STREAM>
friend STREAM &operator<< (STREAM &s, const GenericCirculatorT &self) {
return s << self.mesh_ << ", " << self.start_.idx() << ", " << self.heh_.idx() << ", " << self.lap_counter_;
}
private:
mutable smart_value_type pointer_deref_value;
};
// OLD CIRCULATORS
// deprecated circulators, will be removed soon
// if you remove these circulators and go to the old ones, PLEASE ENABLE FOLLOWING UNITTESTS:
//
// OpenMeshTrimeshCirculatorVertexIHalfEdge.VertexIHalfEdgeIterCheckInvalidationAtEnds
// OpenMeshTrimeshCirculatorVertexEdge.VertexEdgeIterCheckInvalidationAtEnds
// OpenMeshTrimeshCirculatorVertexVertex.VertexVertexIterCheckInvalidationAtEnds
// OpenMeshTrimeshCirculatorVertexOHalfEdge.VertexOHalfEdgeIterCheckInvalidationAtEnds
// OpenMeshTrimeshCirculatorVertexFace.VertexFaceIterCheckInvalidationAtEnds
// OpenMeshTrimeshCirculatorVertexFace.VertexFaceIterWithoutHolesDecrement
// OpenMeshTrimeshCirculatorFaceEdge.FaceEdgeIterCheckInvalidationAtEnds
// OpenMeshTrimeshCirculatorFaceFace.FaceFaceIterCheckInvalidationAtEnds
// OpenMeshTrimeshCirculatorFaceHalfEdge.FaceHalfedgeIterWithoutHolesIncrement
// OpenMeshTrimeshCirculatorFaceVertex.FaceVertexIterCheckInvalidationAtEnds
// OpenMeshTrimeshCirculatorFaceHalfEdge.FaceHalfedgeIterCheckInvalidationAtEnds
//
template<class Mesh, class CenterEntityHandle, class ValueHandle>
class GenericCirculator_ValueHandleFnsT_DEPRECATED {
public:
inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh,const typename Mesh::HalfedgeHandle &start, const int lap_counter) {
return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 )) );
}
inline static void init(const Mesh*, typename Mesh::HalfedgeHandle&, typename Mesh::HalfedgeHandle&, int&) {};
inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, true>::increment(mesh, heh, start, lap_counter);
}
inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, true>::decrement(mesh, heh, start, lap_counter);
}
};
template<class Mesh, class CenterEntityHandle>
class GenericCirculator_ValueHandleFnsT_DEPRECATED<Mesh, CenterEntityHandle, typename Mesh::FaceHandle> {
public:
typedef GenericCirculator_DereferenciabilityCheckT<Mesh, CenterEntityHandle, typename Mesh::FaceHandle> GenericCirculator_DereferenciabilityCheck;
inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const typename Mesh::HalfedgeHandle &start, const int lap_counter) {
return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 )));
}
inline static void init(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
increment(mesh, heh, start, lap_counter);
};
inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
do {
GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, true>::increment(mesh, heh, start, lap_counter);
} while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
}
inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
do {
GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, true>::decrement(mesh, heh, start, lap_counter);
} while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
}
};
template <typename GenericCirculatorT_DEPRECATED_TraitsT>
class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<typename GenericCirculatorT_DEPRECATED_TraitsT::Mesh> {
public:
using Mesh = typename GenericCirculatorT_DEPRECATED_TraitsT::Mesh;
using CenterEntityHandle = typename GenericCirculatorT_DEPRECATED_TraitsT::CenterEntityHandle;
using value_type = typename GenericCirculatorT_DEPRECATED_TraitsT::ValueHandle;
using smart_value_type = decltype (make_smart(std::declval<value_type>(), std::declval<Mesh>()));
typedef std::ptrdiff_t difference_type;
typedef const value_type& reference;
typedef const smart_value_type* pointer;
typedef std::bidirectional_iterator_tag iterator_category;
typedef typename GenericCirculatorBaseT<Mesh>::mesh_ptr mesh_ptr;
typedef typename GenericCirculatorBaseT<Mesh>::mesh_ref mesh_ref;
typedef GenericCirculator_ValueHandleFnsT_DEPRECATED<Mesh, CenterEntityHandle, value_type> GenericCirculator_ValueHandleFns;
template <typename> friend class OpenMesh::CirculatorRange;
public:
GenericCirculatorT_DEPRECATED() {}
GenericCirculatorT_DEPRECATED(mesh_ref mesh, CenterEntityHandle start, bool end = false) :
GenericCirculatorBaseT<Mesh>(mesh, mesh.halfedge_handle(start), end) {
GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
}
GenericCirculatorT_DEPRECATED(mesh_ref mesh, typename Mesh::HalfedgeHandle heh, bool end = false) :
GenericCirculatorBaseT<Mesh>(mesh, heh, end) {
GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
}
GenericCirculatorT_DEPRECATED(const GenericCirculatorT_DEPRECATED &rhs) : GenericCirculatorBaseT<Mesh>(rhs) {}
GenericCirculatorT_DEPRECATED& operator++() {
assert(this->mesh_);
GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);
return *this;
}
#ifndef NO_DECREMENT_DEPRECATED_WARNINGS
#define DECREMENT_DEPRECATED_WARNINGS_TEXT "The current decrement operator has the unintended behavior that it stays\
valid when iterating below the start and will visit the first entity\
twice before getting invalid. Furthermore it gets valid again, if you\
increment at the end.\
When you are sure that you don't iterate below the start anywhere in\
your code or rely on this behaviour, you can disable this warning by\
setting the define NO_DECREMENT_DEPRECATED_WARNINGS at the command line (or enable it via the\
cmake flags).\
To be save, you can use the CW/CCW circulator definitions, which behave\
the same as the original ones, without the previously mentioned issues."
OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
#endif // NO_DECREMENT_DEPRECATED_WARNINGS
GenericCirculatorT_DEPRECATED& operator--() {
assert(this->mesh_);
GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_);
return *this;
}
GenericCirculatorT_DEPRECATED operator++(int) {
assert(this->mesh_);
GenericCirculatorT_DEPRECATED cpy(*this);
++(*this);
return cpy;
}
#ifndef NO_DECREMENT_DEPRECATED_WARNINGS
OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
#undef DECREMENT_DEPRECATED_WARNINGS_TEXT
#endif //NO_DECREMENT_DEPRECATED_WARNINGS
GenericCirculatorT_DEPRECATED operator--(int) {
assert(this->mesh_);
GenericCirculatorT_DEPRECATED cpy(*this);
--(*this);
return cpy;
}
smart_value_type operator*() const {
#ifndef NDEBUG
assert(this->heh_.is_valid());
value_type res = (GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_));
assert(res.is_valid());
return make_smart(res, this->mesh_);
#else
return make_smart(GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_);
#endif
}
pointer operator->() const {
pointer_deref_value = **this;
return &pointer_deref_value;
}
GenericCirculatorT_DEPRECATED &operator=(const GenericCirculatorT_DEPRECATED &rhs) {
GenericCirculatorBaseT<Mesh>::operator=(rhs);
return *this;
};
bool operator==(const GenericCirculatorT_DEPRECATED &rhs) const {
return GenericCirculatorBaseT<Mesh>::operator==(rhs);
}
bool operator!=(const GenericCirculatorT_DEPRECATED &rhs) const {
return GenericCirculatorBaseT<Mesh>::operator!=(rhs);
}
bool is_valid() const {
return GenericCirculator_ValueHandleFns::is_valid(this->heh_,this->start_, this->lap_counter_);
}
OM_DEPRECATED("current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.")
const typename Mesh::HalfedgeHandle &current_halfedge_handle() const {
return this->heh_;
}
OM_DEPRECATED("Do not use this error prone implicit cast. Compare to end-iterator or use is_valid(), instead.")
operator bool() const {
return is_valid();
}
OM_DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.")
smart_value_type handle() const {
return **this;
}
OM_DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
operator value_type() const {
return **this;
}
template<typename STREAM>
friend STREAM &operator<< (STREAM &s, const GenericCirculatorT_DEPRECATED &self) {
return s << self.mesh_ << ", " << self.start_.idx() << ", " << self.heh_.idx() << ", " << self.lap_counter_;
}
private:
mutable smart_value_type pointer_deref_value;
};
} // namespace Iterators
} // namespace OpenMesh
OpenMesh
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition MeshItems.hh:59
OpenMesh::make_smart
SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity *_mesh)
Creats a SmartVertexHandle from a VertexHandle and a Mesh.
Definition SmartHandles.hh:256
OpenMesh::CirculatorRange
Generic class for iterator ranges.
Definition PolyConnectivity_inline_impl.hh:92
OpenMesh::Iterators::GenericCirculator_CenterEntityFnsT
Definition CirculatorsT.hh:69
OpenMesh::Iterators::GenericCirculator_DereferenciabilityCheckT
Definition CirculatorsT.hh:132
OpenMesh::Iterators::GenericCirculator_ValueHandleFnsT
Definition CirculatorsT.hh:154
OpenMesh::Iterators::GenericCirculatorBaseT
Definition CirculatorsT.hh:219
OpenMesh::Iterators::GenericCirculatorT
Definition CirculatorsT.hh:284
OpenMesh::Iterators::GenericCirculatorT::operator*
smart_value_type operator*() const
Standard dereferencing operator.
Definition CirculatorsT.hh:351
OpenMesh::Iterators::GenericCirculatorT::operator++
GenericCirculatorT operator++(int)
Post-increment.
Definition CirculatorsT.hh:335
OpenMesh::Iterators::GenericCirculatorT::operator--
GenericCirculatorT operator--(int)
Post-decrement.
Definition CirculatorsT.hh:343
OpenMesh::Iterators::GenericCirculatorT::operator->
pointer operator->() const
Pointer dereferentiation.
Definition CirculatorsT.hh:370
OpenMesh::Iterators::GenericCirculator_ValueHandleFnsT_DEPRECATED
Definition CirculatorsT.hh:423
OpenMesh::Iterators::GenericCirculatorT_DEPRECATED
Definition CirculatorsT.hh:462
OpenMesh::Iterators::GenericCirculatorT_DEPRECATED::operator++
GenericCirculatorT_DEPRECATED operator++(int)
Post-increment.
Definition CirculatorsT.hh:520
OpenMesh::Iterators::GenericCirculatorT_DEPRECATED::current_halfedge_handle
const Mesh::HalfedgeHandle & current_halfedge_handle() const
Definition CirculatorsT.hh:587
OpenMesh::Iterators::GenericCirculatorT_DEPRECATED::operator->
pointer operator->() const
Pointer dereferentiation.
Definition CirculatorsT.hh:559
OpenMesh::Iterators::GenericCirculatorT_DEPRECATED::operator--
GenericCirculatorT_DEPRECATED operator--(int)
Post-decrement.
Definition CirculatorsT.hh:532
OpenMesh::Iterators::GenericCirculatorT_DEPRECATED::operator*
smart_value_type operator*() const
Standard dereferencing operator.
Definition CirculatorsT.hh:540
OpenMesh::Iterators::GenericCirculatorT_DEPRECATED::handle
smart_value_type handle() const
Return the handle of the current target.
Definition CirculatorsT.hh:607
OpenMesh::VertexHandle
Handle for a vertex entity.
Definition Handles.hh:121
OpenMesh::HalfedgeHandle
Handle for a halfedge entity.
Definition Handles.hh:128
OpenMesh::FaceHandle
Handle for a face entity.
Definition Handles.hh:142
OpenMesh::PolyMesh_ArrayKernelT
Polygonal mesh based on the ArrayKernel.
Definition PolyMesh_ArrayKernelT.hh:96
OpenMesh::PolyMeshT::VertexHandle
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition PolyMeshT.hh:136
OpenMesh::PolyMeshT::EdgeHandle
Kernel::EdgeHandle EdgeHandle
Scalar type.
Definition PolyMeshT.hh:138
OpenMesh::PolyMeshT::FaceHandle
Kernel::FaceHandle FaceHandle
Scalar type.
Definition PolyMeshT.hh:139
OpenMesh::PolyMeshT::HalfedgeHandle
Kernel::HalfedgeHandle HalfedgeHandle
Scalar type.
Definition PolyMeshT.hh:137