adding cw and ccw circulators

closes #2406

git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@1227 fdac6126-5c0c-442c-9429-916003d36597
This commit is contained in:
Matthias Möller
2015-02-23 16:02:40 +00:00
parent 0f9b4c2358
commit eb877fe9da
13 changed files with 1960 additions and 44 deletions

View File

@@ -845,6 +845,10 @@ All circulators provide the operations listed in
CirculatorT<Mesh>, which are basically the same as the CirculatorT<Mesh>, which are basically the same as the
iterator funtions. iterator funtions.
\note Circulators are similar to bidirectional iterators and therefore they have the bidirectional_iterator_tag.
However, the bidirectional requires that the attribute OpenMesh::Attributes::PrevHalfedge is available.
Otherwise it is just a forward iterator.
\deprecated \deprecated
While it is possible to use \c operator \c bool(), which returns true, as long While it is possible to use \c operator \c bool(), which returns true, as long
as the circulator hasn't reached the end of the sequence, this function is as the circulator hasn't reached the end of the sequence, this function is
@@ -855,6 +859,35 @@ to get circulators around a specified center item:
\include circulator_functions.cc \include circulator_functions.cc
Additionally to the normal circulators there exists some for each
direction (clock-wise, counterclock-wise). Those circulators might be slower
than the normal one, but the direction of circulation is guaranteed.
You can get these types of circulators by adding the infix "ccw" or "cw" to
the function used to request the circulator of an item after the underscore.
Example:
\code
VertexVertexIter vvit = mesh.vv_iter(some_vertex_handle); // fastest (clock or counterclockwise)
VertexVertexCWIter vvcwit = mesh.vv_cwiter(some_vertex_handle); // clockwise
VertexVertexCCWIter vvccwit = mesh.vv_ccwiter(some_vertex_handle); // counter-clockwise
\endcode
It is also possible to convert a cw circulator to a ccw circulator and vice versa.
For this purpose, each circulator provides a constructor taking the other circulator as input.
If a cw circulator is converted, the ccw circulator points on the same element as
the cw circulator pointed on, but the direction for the increment and decrement changed.\n
The conversion is only valid for valid circulators. The resulting circulator from a invalid circulator is still invalid,
but might behave in a fashion not expected by normal iterators. Example:
\code
VertexVertexCWIter vvcwit = mesh.vv_cwend(some_vertex_handle);
VertexVertexCCWIter vvccwit = VertexVertexCCWIter(vvcwit); //conversion of an invalid circulator
--vvcwit; //is valid now (if the range >= 1)
++vvccwit; //can still be invalid
\endcode
CW and CCW circulators requires that OpenMesh::Attributes::PrevHalfedge is available.
\note For every circulator there also exists a constant version. \note For every circulator there also exists a constant version.
To make use of these constant circulators just add the prefix<br /> To make use of these constant circulators just add the prefix<br />
"Const" to the type specifier and add the prefix "c" to the function used to request "Const" to the type specifier and add the prefix "c" to the function used to request

View File

@@ -61,7 +61,7 @@
namespace OpenMesh { namespace OpenMesh {
namespace Iterators { namespace Iterators {
template<class Mesh, class CenterEntityHandle> template<class Mesh, class CenterEntityHandle, bool CW>
class GenericCirculator_CenterEntityFnsT { class GenericCirculator_CenterEntityFnsT {
public: public:
static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter); static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter);
@@ -69,31 +69,61 @@ class GenericCirculator_CenterEntityFnsT {
}; };
template<class Mesh> template<class Mesh>
class GenericCirculator_CenterEntityFnsT<Mesh, typename Mesh::VertexHandle> { class GenericCirculator_CenterEntityFnsT<Mesh, typename Mesh::VertexHandle, true> {
public: public:
inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { 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); heh = mesh->cw_rotated_halfedge_handle(heh);
if (heh == start) lap_counter++; if (heh == start) ++lap_counter;
} }
inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &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--; if (heh == start) --lap_counter;
heh = mesh->ccw_rotated_halfedge_handle(heh); heh = mesh->ccw_rotated_halfedge_handle(heh);
} }
}; };
template<class Mesh> template<class Mesh>
class GenericCirculator_CenterEntityFnsT<Mesh, typename Mesh::FaceHandle> { class GenericCirculator_CenterEntityFnsT<Mesh, typename Mesh::FaceHandle, true> {
public: public:
inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
heh = mesh->next_halfedge_handle(heh); heh = mesh->next_halfedge_handle(heh);
if (heh == start) lap_counter++; if (heh == start) ++lap_counter;
} }
inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &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--; if (heh == start) --lap_counter;
heh = mesh->prev_halfedge_handle(heh); 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> template<class Mesh, class CenterEntityHandle, class ValueHandle>
class GenericCirculator_DereferenciabilityCheckT { class GenericCirculator_DereferenciabilityCheckT {
public: public:
@@ -116,7 +146,7 @@ class GenericCirculator_DereferenciabilityCheckT<Mesh, typename Mesh::VertexHand
} }
}; };
template<class Mesh, class CenterEntityHandle, class ValueHandle> template<class Mesh, class CenterEntityHandle, class ValueHandle, bool CW = true>
class GenericCirculator_ValueHandleFnsT { class GenericCirculator_ValueHandleFnsT {
public: public:
inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const int lap_counter) { inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const int lap_counter) {
@@ -124,15 +154,15 @@ class GenericCirculator_ValueHandleFnsT {
} }
inline static void init(const Mesh*, typename Mesh::HalfedgeHandle&, typename Mesh::HalfedgeHandle&, int&) {}; 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) { inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle>::increment(mesh, heh, start, 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) { inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle>::decrement(mesh, heh, start, lap_counter); GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, CW>::decrement(mesh, heh, start, lap_counter);
} }
}; };
template<class Mesh, class CenterEntityHandle> template<class Mesh, class CenterEntityHandle, bool CW>
class GenericCirculator_ValueHandleFnsT<Mesh, CenterEntityHandle, typename Mesh::FaceHandle> { class GenericCirculator_ValueHandleFnsT<Mesh, CenterEntityHandle, typename Mesh::FaceHandle, CW> {
public: public:
typedef GenericCirculator_DereferenciabilityCheckT<Mesh, CenterEntityHandle, typename Mesh::FaceHandle> GenericCirculator_DereferenciabilityCheck; typedef GenericCirculator_DereferenciabilityCheckT<Mesh, CenterEntityHandle, typename Mesh::FaceHandle> GenericCirculator_DereferenciabilityCheck;
@@ -145,12 +175,12 @@ class GenericCirculator_ValueHandleFnsT<Mesh, CenterEntityHandle, typename Mesh:
}; };
inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
do { do {
GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle>::increment(mesh, heh, start, lap_counter); GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, CW>::increment(mesh, heh, start, lap_counter);
} while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh)); } 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) { inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
do { do {
GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle>::decrement(mesh, heh, start, lap_counter); GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, CW>::decrement(mesh, heh, start, lap_counter);
} while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh)); } while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh));
} }
}; };
@@ -217,7 +247,7 @@ class GenericCirculatorBaseT {
}; };
template<class Mesh, class CenterEntityHandle, class ValueHandle, template<class Mesh, class CenterEntityHandle, class ValueHandle,
ValueHandle (GenericCirculatorBaseT<Mesh>::*Handle2Value)() const> ValueHandle (GenericCirculatorBaseT<Mesh>::*Handle2Value)() const, bool CW = true >
class GenericCirculatorT : protected GenericCirculatorBaseT<Mesh> { class GenericCirculatorT : protected GenericCirculatorBaseT<Mesh> {
public: public:
typedef std::ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
@@ -228,7 +258,7 @@ class GenericCirculatorT : protected GenericCirculatorBaseT<Mesh> {
typedef typename GenericCirculatorBaseT<Mesh>::mesh_ptr mesh_ptr; typedef typename GenericCirculatorBaseT<Mesh>::mesh_ptr mesh_ptr;
typedef typename GenericCirculatorBaseT<Mesh>::mesh_ref mesh_ref; typedef typename GenericCirculatorBaseT<Mesh>::mesh_ref mesh_ref;
typedef GenericCirculator_ValueHandleFnsT<Mesh, CenterEntityHandle, ValueHandle> GenericCirculator_ValueHandleFns; typedef GenericCirculator_ValueHandleFnsT<Mesh, CenterEntityHandle, ValueHandle, CW> GenericCirculator_ValueHandleFns;
public: public:
GenericCirculatorT() {} GenericCirculatorT() {}
@@ -244,6 +274,10 @@ class GenericCirculatorT : protected GenericCirculatorBaseT<Mesh> {
} }
GenericCirculatorT(const GenericCirculatorT &rhs) : GenericCirculatorBaseT<Mesh>(rhs) {} GenericCirculatorT(const GenericCirculatorT &rhs) : GenericCirculatorBaseT<Mesh>(rhs) {}
friend class GenericCirculatorT<Mesh,CenterEntityHandle,ValueHandle,Handle2Value,!CW>;
explicit GenericCirculatorT( const GenericCirculatorT<Mesh,CenterEntityHandle,ValueHandle,Handle2Value,!CW>& rhs )
:GenericCirculatorBaseT<Mesh>(rhs){}
GenericCirculatorT& operator++() { GenericCirculatorT& operator++() {
assert(this->mesh_); assert(this->mesh_);
GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_); GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_);

View File

@@ -105,6 +105,14 @@ public:
typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::VertexHandle, typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::VertexHandle,
&Iterators::GenericCirculatorBaseT<This>::toVertexHandle> &Iterators::GenericCirculatorBaseT<This>::toVertexHandle>
VertexVertexIter; VertexVertexIter;
typedef VertexVertexIter VertexVertexCWIter;
/**
* Enumerates 1-ring vertices in a counter clockwise fashion.
*/
typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::VertexHandle,
&Iterators::GenericCirculatorBaseT<This>::toVertexHandle, false>
VertexVertexCCWIter;
/** /**
* Enumerates outgoing half edges in a clockwise fashion. * Enumerates outgoing half edges in a clockwise fashion.
@@ -112,6 +120,14 @@ public:
typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::HalfedgeHandle, typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::HalfedgeHandle,
&Iterators::GenericCirculatorBaseT<This>::toHalfedgeHandle> &Iterators::GenericCirculatorBaseT<This>::toHalfedgeHandle>
VertexOHalfedgeIter; VertexOHalfedgeIter;
typedef VertexOHalfedgeIter VertexOHalfedgeCWIter;
/**
* Enumerates outgoing half edges in a counter clockwise fashion.
*/
typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::HalfedgeHandle,
&Iterators::GenericCirculatorBaseT<This>::toHalfedgeHandle, false>
VertexOHalfedgeCCWIter;
/** /**
* Enumerates incoming half edges in a clockwise fashion. * Enumerates incoming half edges in a clockwise fashion.
@@ -119,6 +135,14 @@ public:
typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::HalfedgeHandle, typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::HalfedgeHandle,
&Iterators::GenericCirculatorBaseT<This>::toOppositeHalfedgeHandle> &Iterators::GenericCirculatorBaseT<This>::toOppositeHalfedgeHandle>
VertexIHalfedgeIter; VertexIHalfedgeIter;
typedef VertexIHalfedgeIter VertexIHalfedgeCWIter;
/**
* Enumerates incoming half edges in a counter clockwise fashion.
*/
typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::HalfedgeHandle,
&Iterators::GenericCirculatorBaseT<This>::toOppositeHalfedgeHandle, false>
VertexIHalfedgeCCWIter;
/** /**
* Enumerates incident faces in a clockwise fashion. * Enumerates incident faces in a clockwise fashion.
@@ -126,6 +150,14 @@ public:
typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::FaceHandle, typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::FaceHandle,
&Iterators::GenericCirculatorBaseT<This>::toFaceHandle> &Iterators::GenericCirculatorBaseT<This>::toFaceHandle>
VertexFaceIter; VertexFaceIter;
typedef VertexFaceIter VertexFaceCWIter;
/**
* Enumerates incident faces in a counter clockwise fashion.
*/
typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::FaceHandle,
&Iterators::GenericCirculatorBaseT<This>::toFaceHandle, false>
VertexFaceCCWIter;
/** /**
* Enumerates incident edges in a clockwise fashion. * Enumerates incident edges in a clockwise fashion.
@@ -133,6 +165,13 @@ public:
typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::EdgeHandle, typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::EdgeHandle,
&Iterators::GenericCirculatorBaseT<This>::toEdgeHandle> &Iterators::GenericCirculatorBaseT<This>::toEdgeHandle>
VertexEdgeIter; VertexEdgeIter;
typedef VertexEdgeIter VertexEdgeCWIter;
/**
* Enumerates incident edges in a counter clockwise fashion.
*/
typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::EdgeHandle,
&Iterators::GenericCirculatorBaseT<This>::toEdgeHandle, false>
VertexEdgeCCWIter;
/** /**
* Identical to #FaceHalfedgeIter. God knows why this typedef exists. * Identical to #FaceHalfedgeIter. God knows why this typedef exists.
@@ -140,12 +179,29 @@ public:
typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::HalfedgeHandle, typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::HalfedgeHandle,
&Iterators::GenericCirculatorBaseT<This>::toHalfedgeHandle> &Iterators::GenericCirculatorBaseT<This>::toHalfedgeHandle>
HalfedgeLoopIter; HalfedgeLoopIter;
typedef HalfedgeLoopIter HalfedgeLoopCWIter;
/**
* Identical to #FaceHalfedgeIter. God knows why this typedef exists.
*/
typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::HalfedgeHandle,
&Iterators::GenericCirculatorBaseT<This>::toHalfedgeHandle, false>
HalfedgeLoopCCWIter;
typedef VertexVertexIter ConstVertexVertexIter; typedef VertexVertexIter ConstVertexVertexIter;
typedef VertexVertexCWIter ConstVertexVertexCWIter;
typedef VertexVertexCCWIter ConstVertexVertexCCWIter;
typedef VertexOHalfedgeIter ConstVertexOHalfedgeIter; typedef VertexOHalfedgeIter ConstVertexOHalfedgeIter;
typedef VertexOHalfedgeCWIter ConstVertexOHalfedgeCWIter;
typedef VertexOHalfedgeCCWIter ConstVertexOHalfedgeCCWIter;
typedef VertexIHalfedgeIter ConstVertexIHalfedgeIter; typedef VertexIHalfedgeIter ConstVertexIHalfedgeIter;
typedef VertexIHalfedgeCWIter ConstVertexIHalfedgeCWIter;
typedef VertexIHalfedgeCCWIter ConstVertexIHalfedgeCCWIter;
typedef VertexFaceIter ConstVertexFaceIter; typedef VertexFaceIter ConstVertexFaceIter;
typedef VertexFaceCWIter ConstVertexFaceCWIter;
typedef VertexFaceCCWIter ConstVertexFaceCCWIter;
typedef VertexEdgeIter ConstVertexEdgeIter; typedef VertexEdgeIter ConstVertexEdgeIter;
typedef VertexEdgeCWIter ConstVertexEdgeCWIter;
typedef VertexEdgeCCWIter ConstVertexEdgeCCWIter;
/* /*
* Face-centered circulators * Face-centered circulators
@@ -157,6 +213,14 @@ public:
typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::VertexHandle, typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::VertexHandle,
&Iterators::GenericCirculatorBaseT<This>::toVertexHandle> &Iterators::GenericCirculatorBaseT<This>::toVertexHandle>
FaceVertexIter; FaceVertexIter;
typedef FaceVertexIter FaceVertexCCWIter;
/**
* Enumerate incident vertices in a clockwise fashion.
*/
typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::VertexHandle,
&Iterators::GenericCirculatorBaseT<This>::toVertexHandle, false>
FaceVertexCWIter;
/** /**
* Enumerate incident half edges in a counter clockwise fashion. * Enumerate incident half edges in a counter clockwise fashion.
@@ -164,6 +228,14 @@ public:
typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::HalfedgeHandle, typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::HalfedgeHandle,
&Iterators::GenericCirculatorBaseT<This>::toHalfedgeHandle> &Iterators::GenericCirculatorBaseT<This>::toHalfedgeHandle>
FaceHalfedgeIter; FaceHalfedgeIter;
typedef FaceHalfedgeIter FaceHalfedgeCCWIter;
/**
* Enumerate incident half edges in a clockwise fashion.
*/
typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::HalfedgeHandle,
&Iterators::GenericCirculatorBaseT<This>::toHalfedgeHandle, false>
FaceHalfedgeCWIter;
/** /**
* Enumerate incident edges in a counter clockwise fashion. * Enumerate incident edges in a counter clockwise fashion.
@@ -171,6 +243,14 @@ public:
typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::EdgeHandle, typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::EdgeHandle,
&Iterators::GenericCirculatorBaseT<This>::toEdgeHandle> &Iterators::GenericCirculatorBaseT<This>::toEdgeHandle>
FaceEdgeIter; FaceEdgeIter;
typedef FaceEdgeIter FaceEdgeCCWIter;
/**
* Enumerate incident edges in a clockwise fashion.
*/
typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::EdgeHandle,
&Iterators::GenericCirculatorBaseT<This>::toEdgeHandle, false>
FaceEdgeCWIter;
/** /**
* Enumerate adjacent faces in a counter clockwise fashion. * Enumerate adjacent faces in a counter clockwise fashion.
@@ -178,16 +258,34 @@ public:
typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::FaceHandle, typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::FaceHandle,
&Iterators::GenericCirculatorBaseT<This>::toOppositeFaceHandle> &Iterators::GenericCirculatorBaseT<This>::toOppositeFaceHandle>
FaceFaceIter; FaceFaceIter;
typedef FaceFaceIter FaceFaceCCWIter;
/**
* Enumerate adjacent faces in a clockwise fashion.
*/
typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::FaceHandle,
&Iterators::GenericCirculatorBaseT<This>::toOppositeFaceHandle, false>
FaceFaceCWIter;
typedef FaceVertexIter ConstFaceVertexIter; typedef FaceVertexIter ConstFaceVertexIter;
typedef FaceVertexCWIter ConstFaceVertexCWIter;
typedef FaceVertexCCWIter ConstFaceVertexCCWIter;
typedef FaceHalfedgeIter ConstFaceHalfedgeIter; typedef FaceHalfedgeIter ConstFaceHalfedgeIter;
typedef FaceHalfedgeCWIter ConstFaceHalfedgeCWIter;
typedef FaceHalfedgeCCWIter ConstFaceHalfedgeCCWIter;
typedef FaceEdgeIter ConstFaceEdgeIter; typedef FaceEdgeIter ConstFaceEdgeIter;
typedef FaceEdgeCWIter ConstFaceEdgeCWIter;
typedef FaceEdgeCCWIter ConstFaceEdgeCCWIter;
typedef FaceFaceIter ConstFaceFaceIter; typedef FaceFaceIter ConstFaceFaceIter;
typedef FaceFaceCWIter ConstFaceFaceCWIter;
typedef FaceFaceCCWIter ConstFaceFaceCCWIter;
/* /*
* Halfedge circulator * Halfedge circulator
*/ */
typedef HalfedgeLoopIter ConstHalfedgeLoopIter; typedef HalfedgeLoopIter ConstHalfedgeLoopIter;
typedef HalfedgeLoopCWIter ConstHalfedgeLoopCWIter;
typedef HalfedgeLoopCCWIter ConstHalfedgeLoopCCWIter;
//@} //@}
@@ -214,24 +312,58 @@ public:
typedef ConstFaceIter CFIter; typedef ConstFaceIter CFIter;
typedef VertexVertexIter VVIter; typedef VertexVertexIter VVIter;
typedef VertexVertexCWIter VVCWIter;
typedef VertexVertexCCWIter VVCCWIter;
typedef VertexOHalfedgeIter VOHIter; typedef VertexOHalfedgeIter VOHIter;
typedef VertexOHalfedgeCWIter VOHCWIter;
typedef VertexOHalfedgeCCWIter VOHCCWIter;
typedef VertexIHalfedgeIter VIHIter; typedef VertexIHalfedgeIter VIHIter;
typedef VertexIHalfedgeCWIter VIHICWter;
typedef VertexIHalfedgeCCWIter VIHICCWter;
typedef VertexEdgeIter VEIter; typedef VertexEdgeIter VEIter;
typedef VertexEdgeCWIter VECWIter;
typedef VertexEdgeCCWIter VECCWIter;
typedef VertexFaceIter VFIter; typedef VertexFaceIter VFIter;
typedef VertexFaceCWIter VFCWIter;
typedef VertexFaceCCWIter VFCCWIter;
typedef FaceVertexIter FVIter; typedef FaceVertexIter FVIter;
typedef FaceVertexCWIter FVCWIter;
typedef FaceVertexCCWIter FVCCWIter;
typedef FaceHalfedgeIter FHIter; typedef FaceHalfedgeIter FHIter;
typedef FaceHalfedgeCWIter FHCWIter;
typedef FaceHalfedgeCCWIter FHCWWIter;
typedef FaceEdgeIter FEIter; typedef FaceEdgeIter FEIter;
typedef FaceEdgeCWIter FECWIter;
typedef FaceEdgeCCWIter FECWWIter;
typedef FaceFaceIter FFIter; typedef FaceFaceIter FFIter;
typedef ConstVertexVertexIter CVVIter; typedef ConstVertexVertexIter CVVIter;
typedef ConstVertexVertexCWIter CVVCWIter;
typedef ConstVertexVertexCCWIter CVVCCWIter;
typedef ConstVertexOHalfedgeIter CVOHIter; typedef ConstVertexOHalfedgeIter CVOHIter;
typedef ConstVertexOHalfedgeCWIter CVOHCWIter;
typedef ConstVertexOHalfedgeCCWIter CVOHCCWIter;
typedef ConstVertexIHalfedgeIter CVIHIter; typedef ConstVertexIHalfedgeIter CVIHIter;
typedef ConstVertexIHalfedgeCWIter CVIHCWIter;
typedef ConstVertexIHalfedgeCCWIter CVIHCCWIter;
typedef ConstVertexEdgeIter CVEIter; typedef ConstVertexEdgeIter CVEIter;
typedef ConstVertexEdgeCWIter CVECWIter;
typedef ConstVertexEdgeCCWIter CVECCWIter;
typedef ConstVertexFaceIter CVFIter; typedef ConstVertexFaceIter CVFIter;
typedef ConstVertexFaceCWIter CVFCWIter;
typedef ConstVertexFaceCCWIter CVFCCWIter;
typedef ConstFaceVertexIter CFVIter; typedef ConstFaceVertexIter CFVIter;
typedef ConstFaceVertexCWIter CFVCWIter;
typedef ConstFaceVertexCCWIter CFVCCWIter;
typedef ConstFaceHalfedgeIter CFHIter; typedef ConstFaceHalfedgeIter CFHIter;
typedef ConstFaceHalfedgeCWIter CFHCWIter;
typedef ConstFaceHalfedgeCCWIter CFHCCWIter;
typedef ConstFaceEdgeIter CFEIter; typedef ConstFaceEdgeIter CFEIter;
typedef ConstFaceEdgeCWIter CFECWIter;
typedef ConstFaceEdgeCCWIter CFECCWIter;
typedef ConstFaceFaceIter CFFIter; typedef ConstFaceFaceIter CFFIter;
typedef ConstFaceFaceCWIter CFFCWIter;
typedef ConstFaceFaceCCWIter CFFCCWIter;
//@} //@}
public: public:
@@ -426,192 +558,541 @@ public:
/// vertex - vertex circulator /// vertex - vertex circulator
VertexVertexIter vv_iter(VertexHandle _vh) VertexVertexIter vv_iter(VertexHandle _vh)
{ return VertexVertexIter(*this, _vh); } { return VertexVertexIter(*this, _vh); }
/// vertex - vertex circulator cw
VertexVertexCWIter vv_cwiter(VertexHandle _vh)
{ return VertexVertexCWIter(*this, _vh); }
/// vertex - vertex circulator ccw
VertexVertexCCWIter vv_ccwiter(VertexHandle _vh)
{ return VertexVertexCCWIter(*this, _vh); }
/// vertex - incoming halfedge circulator /// vertex - incoming halfedge circulator
VertexIHalfedgeIter vih_iter(VertexHandle _vh) VertexIHalfedgeIter vih_iter(VertexHandle _vh)
{ return VertexIHalfedgeIter(*this, _vh); } { return VertexIHalfedgeIter(*this, _vh); }
/// vertex - incoming halfedge circulator cw
VertexIHalfedgeCWIter vih_cwiter(VertexHandle _vh)
{ return VertexIHalfedgeCWIter(*this, _vh); }
/// vertex - incoming halfedge circulator ccw
VertexIHalfedgeCCWIter vih_ccwiter(VertexHandle _vh)
{ return VertexIHalfedgeCCWIter(*this, _vh); }
/// vertex - outgoing halfedge circulator /// vertex - outgoing halfedge circulator
VertexOHalfedgeIter voh_iter(VertexHandle _vh) VertexOHalfedgeIter voh_iter(VertexHandle _vh)
{ return VertexOHalfedgeIter(*this, _vh); } { return VertexOHalfedgeIter(*this, _vh); }
/// vertex - outgoing halfedge circulator cw
VertexOHalfedgeCWIter voh_cwiter(VertexHandle _vh)
{ return VertexOHalfedgeCWIter(*this, _vh); }
/// vertex - outgoing halfedge circulator ccw
VertexOHalfedgeCCWIter voh_ccwiter(VertexHandle _vh)
{ return VertexOHalfedgeCCWIter(*this, _vh); }
/// vertex - edge circulator /// vertex - edge circulator
VertexEdgeIter ve_iter(VertexHandle _vh) VertexEdgeIter ve_iter(VertexHandle _vh)
{ return VertexEdgeIter(*this, _vh); } { return VertexEdgeIter(*this, _vh); }
/// vertex - edge circulator cw
VertexEdgeCWIter ve_cwiter(VertexHandle _vh)
{ return VertexEdgeCWIter(*this, _vh); }
/// vertex - edge circulator ccw
VertexEdgeCCWIter ve_ccwiter(VertexHandle _vh)
{ return VertexEdgeCCWIter(*this, _vh); }
/// vertex - face circulator /// vertex - face circulator
VertexFaceIter vf_iter(VertexHandle _vh) VertexFaceIter vf_iter(VertexHandle _vh)
{ return VertexFaceIter(*this, _vh); } { return VertexFaceIter(*this, _vh); }
/// vertex - face circulator cw
VertexFaceCWIter vf_cwiter(VertexHandle _vh)
{ return VertexFaceCWIter(*this, _vh); }
/// vertex - face circulator ccw
VertexFaceCCWIter vf_ccwiter(VertexHandle _vh)
{ return VertexFaceCCWIter(*this, _vh); }
/// const vertex circulator /// const vertex circulator
ConstVertexVertexIter cvv_iter(VertexHandle _vh) const ConstVertexVertexIter cvv_iter(VertexHandle _vh) const
{ return ConstVertexVertexIter(*this, _vh); } { return ConstVertexVertexIter(*this, _vh); }
/// const vertex circulator cw
ConstVertexVertexCWIter cvv_cwiter(VertexHandle _vh) const
{ return ConstVertexVertexCWIter(*this, _vh); }
/// const vertex circulator ccw
ConstVertexVertexCCWIter cvv_ccwiter(VertexHandle _vh) const
{ return ConstVertexVertexCCWIter(*this, _vh); }
/// const vertex - incoming halfedge circulator /// const vertex - incoming halfedge circulator
ConstVertexIHalfedgeIter cvih_iter(VertexHandle _vh) const ConstVertexIHalfedgeIter cvih_iter(VertexHandle _vh) const
{ return ConstVertexIHalfedgeIter(*this, _vh); } { return ConstVertexIHalfedgeIter(*this, _vh); }
/// const vertex - incoming halfedge circulator cw
ConstVertexIHalfedgeCWIter cvih_cwiter(VertexHandle _vh) const
{ return ConstVertexIHalfedgeCWIter(*this, _vh); }
/// const vertex - incoming halfedge circulator ccw
ConstVertexIHalfedgeCCWIter cvih_ccwiter(VertexHandle _vh) const
{ return ConstVertexIHalfedgeCCWIter(*this, _vh); }
/// const vertex - outgoing halfedge circulator /// const vertex - outgoing halfedge circulator
ConstVertexOHalfedgeIter cvoh_iter(VertexHandle _vh) const ConstVertexOHalfedgeIter cvoh_iter(VertexHandle _vh) const
{ return ConstVertexOHalfedgeIter(*this, _vh); } { return ConstVertexOHalfedgeIter(*this, _vh); }
/// const vertex - outgoing halfedge circulator cw
ConstVertexOHalfedgeCWIter cvoh_cwiter(VertexHandle _vh) const
{ return ConstVertexOHalfedgeCWIter(*this, _vh); }
/// const vertex - outgoing halfedge circulator ccw
ConstVertexOHalfedgeCCWIter cvoh_ccwiter(VertexHandle _vh) const
{ return ConstVertexOHalfedgeCCWIter(*this, _vh); }
/// const vertex - edge circulator /// const vertex - edge circulator
ConstVertexEdgeIter cve_iter(VertexHandle _vh) const ConstVertexEdgeIter cve_iter(VertexHandle _vh) const
{ return ConstVertexEdgeIter(*this, _vh); } { return ConstVertexEdgeIter(*this, _vh); }
/// const vertex - edge circulator cw
ConstVertexEdgeCWIter cve_cwiter(VertexHandle _vh) const
{ return ConstVertexEdgeCWIter(*this, _vh); }
/// const vertex - edge circulator ccw
ConstVertexEdgeCCWIter cve_ccwiter(VertexHandle _vh) const
{ return ConstVertexEdgeCCWIter(*this, _vh); }
/// const vertex - face circulator /// const vertex - face circulator
ConstVertexFaceIter cvf_iter(VertexHandle _vh) const ConstVertexFaceIter cvf_iter(VertexHandle _vh) const
{ return ConstVertexFaceIter(*this, _vh); } { return ConstVertexFaceIter(*this, _vh); }
/// const vertex - face circulator cw
ConstVertexFaceCWIter cvf_cwiter(VertexHandle _vh) const
{ return ConstVertexFaceCWIter(*this, _vh); }
/// const vertex - face circulator ccw
ConstVertexFaceCCWIter cvf_ccwiter(VertexHandle _vh) const
{ return ConstVertexFaceCCWIter(*this, _vh); }
/// face - vertex circulator /// face - vertex circulator
FaceVertexIter fv_iter(FaceHandle _fh) FaceVertexIter fv_iter(FaceHandle _fh)
{ return FaceVertexIter(*this, _fh); } { return FaceVertexIter(*this, _fh); }
/// face - vertex circulator cw
FaceVertexCWIter fv_cwiter(FaceHandle _fh)
{ return FaceVertexCWIter(*this, _fh); }
/// face - vertex circulator ccw
FaceVertexCCWIter fv_ccwiter(FaceHandle _fh)
{ return FaceVertexCCWIter(*this, _fh); }
/// face - halfedge circulator /// face - halfedge circulator
FaceHalfedgeIter fh_iter(FaceHandle _fh) FaceHalfedgeIter fh_iter(FaceHandle _fh)
{ return FaceHalfedgeIter(*this, _fh); } { return FaceHalfedgeIter(*this, _fh); }
/// face - halfedge circulator cw
FaceHalfedgeCWIter fh_cwiter(FaceHandle _fh)
{ return FaceHalfedgeCWIter(*this, _fh); }
/// face - halfedge circulator ccw
FaceHalfedgeCCWIter fh_ccwiter(FaceHandle _fh)
{ return FaceHalfedgeCCWIter(*this, _fh); }
/// face - edge circulator /// face - edge circulator
FaceEdgeIter fe_iter(FaceHandle _fh) FaceEdgeIter fe_iter(FaceHandle _fh)
{ return FaceEdgeIter(*this, _fh); } { return FaceEdgeIter(*this, _fh); }
/// face - edge circulator cw
FaceEdgeCWIter fe_cwiter(FaceHandle _fh)
{ return FaceEdgeCWIter(*this, _fh); }
/// face - edge circulator ccw
FaceEdgeCCWIter fe_ccwiter(FaceHandle _fh)
{ return FaceEdgeCCWIter(*this, _fh); }
/// face - face circulator /// face - face circulator
FaceFaceIter ff_iter(FaceHandle _fh) FaceFaceIter ff_iter(FaceHandle _fh)
{ return FaceFaceIter(*this, _fh); } { return FaceFaceIter(*this, _fh); }
/// face - face circulator cw
FaceFaceCWIter ff_cwiter(FaceHandle _fh)
{ return FaceFaceCWIter(*this, _fh); }
/// face - face circulator ccw
FaceFaceCCWIter ff_ccwiter(FaceHandle _fh)
{ return FaceFaceCCWIter(*this, _fh); }
/// const face - vertex circulator /// const face - vertex circulator
ConstFaceVertexIter cfv_iter(FaceHandle _fh) const ConstFaceVertexIter cfv_iter(FaceHandle _fh) const
{ return ConstFaceVertexIter(*this, _fh); } { return ConstFaceVertexIter(*this, _fh); }
/// const face - vertex circulator cw
ConstFaceVertexCWIter cfv_cwiter(FaceHandle _fh) const
{ return ConstFaceVertexCWIter(*this, _fh); }
/// const face - vertex circulator ccw
ConstFaceVertexCCWIter cfv_ccwiter(FaceHandle _fh) const
{ return ConstFaceVertexCCWIter(*this, _fh); }
/// const face - halfedge circulator /// const face - halfedge circulator
ConstFaceHalfedgeIter cfh_iter(FaceHandle _fh) const ConstFaceHalfedgeIter cfh_iter(FaceHandle _fh) const
{ return ConstFaceHalfedgeIter(*this, _fh); } { return ConstFaceHalfedgeIter(*this, _fh); }
/// const face - halfedge circulator cw
ConstFaceHalfedgeCWIter cfh_cwiter(FaceHandle _fh) const
{ return ConstFaceHalfedgeCWIter(*this, _fh); }
/// const face - halfedge circulator ccw
ConstFaceHalfedgeCCWIter cfh_ccwiter(FaceHandle _fh) const
{ return ConstFaceHalfedgeCCWIter(*this, _fh); }
/// const face - edge circulator /// const face - edge circulator
ConstFaceEdgeIter cfe_iter(FaceHandle _fh) const ConstFaceEdgeIter cfe_iter(FaceHandle _fh) const
{ return ConstFaceEdgeIter(*this, _fh); } { return ConstFaceEdgeIter(*this, _fh); }
/// const face - edge circulator cw
ConstFaceEdgeCWIter cfe_cwiter(FaceHandle _fh) const
{ return ConstFaceEdgeCWIter(*this, _fh); }
/// const face - edge circulator ccw
ConstFaceEdgeCCWIter cfe_ccwiter(FaceHandle _fh) const
{ return ConstFaceEdgeCCWIter(*this, _fh); }
/// const face - face circulator /// const face - face circulator
ConstFaceFaceIter cff_iter(FaceHandle _fh) const ConstFaceFaceIter cff_iter(FaceHandle _fh) const
{ return ConstFaceFaceIter(*this, _fh); } { return ConstFaceFaceIter(*this, _fh); }
/// const face - face circulator cw
ConstFaceFaceCWIter cff_cwiter(FaceHandle _fh) const
{ return ConstFaceFaceCWIter(*this, _fh); }
/// const face - face circulator
ConstFaceFaceCCWIter cff_ccwiter(FaceHandle _fh) const
{ return ConstFaceFaceCCWIter(*this, _fh); }
// 'begin' circulators // 'begin' circulators
/// vertex - vertex circulator /// vertex - vertex circulator
VertexVertexIter vv_begin(VertexHandle _vh) VertexVertexIter vv_begin(VertexHandle _vh)
{ return VertexVertexIter(*this, _vh); } { return VertexVertexIter(*this, _vh); }
/// vertex - vertex circulator cw
VertexVertexCWIter vv_cwbegin(VertexHandle _vh)
{ return VertexVertexCWIter(*this, _vh); }
/// vertex - vertex circulator ccw
VertexVertexCCWIter vv_ccwbegin(VertexHandle _vh)
{ return VertexVertexCCWIter(*this, _vh); }
/// vertex - incoming halfedge circulator /// vertex - incoming halfedge circulator
VertexIHalfedgeIter vih_begin(VertexHandle _vh) VertexIHalfedgeIter vih_begin(VertexHandle _vh)
{ return VertexIHalfedgeIter(*this, _vh); } { return VertexIHalfedgeIter(*this, _vh); }
/// vertex - incoming halfedge circulator cw
VertexIHalfedgeCWIter vih_cwbegin(VertexHandle _vh)
{ return VertexIHalfedgeCWIter(*this, _vh); }
/// vertex - incoming halfedge circulator ccw
VertexIHalfedgeCCWIter vih_ccwbegin(VertexHandle _vh)
{ return VertexIHalfedgeCCWIter(*this, _vh); }
/// vertex - outgoing halfedge circulator /// vertex - outgoing halfedge circulator
VertexOHalfedgeIter voh_begin(VertexHandle _vh) VertexOHalfedgeIter voh_begin(VertexHandle _vh)
{ return VertexOHalfedgeIter(*this, _vh); } { return VertexOHalfedgeIter(*this, _vh); }
/// vertex - outgoing halfedge circulator cw
VertexOHalfedgeCWIter voh_cwbegin(VertexHandle _vh)
{ return VertexOHalfedgeCWIter(*this, _vh); }
/// vertex - outgoing halfedge circulator ccw
VertexOHalfedgeCCWIter voh_ccwbegin(VertexHandle _vh)
{ return VertexOHalfedgeCCWIter(*this, _vh); }
/// vertex - edge circulator /// vertex - edge circulator
VertexEdgeIter ve_begin(VertexHandle _vh) VertexEdgeIter ve_begin(VertexHandle _vh)
{ return VertexEdgeIter(*this, _vh); } { return VertexEdgeIter(*this, _vh); }
/// vertex - edge circulator cw
VertexEdgeCWIter ve_cwbegin(VertexHandle _vh)
{ return VertexEdgeCWIter(*this, _vh); }
/// vertex - edge circulator ccw
VertexEdgeCCWIter ve_ccwbegin(VertexHandle _vh)
{ return VertexEdgeCCWIter(*this, _vh); }
/// vertex - face circulator /// vertex - face circulator
VertexFaceIter vf_begin(VertexHandle _vh) VertexFaceIter vf_begin(VertexHandle _vh)
{ return VertexFaceIter(*this, _vh); } { return VertexFaceIter(*this, _vh); }
/// vertex - face circulator cw
VertexFaceCWIter vf_cwbegin(VertexHandle _vh)
{ return VertexFaceCWIter(*this, _vh); }
/// vertex - face circulator ccw
VertexFaceCCWIter vf_ccwbegin(VertexHandle _vh)
{ return VertexFaceCCWIter(*this, _vh); }
/// const vertex circulator /// const vertex circulator
ConstVertexVertexIter cvv_begin(VertexHandle _vh) const ConstVertexVertexIter cvv_begin(VertexHandle _vh) const
{ return ConstVertexVertexIter(*this, _vh); } { return ConstVertexVertexIter(*this, _vh); }
/// const vertex circulator cw
ConstVertexVertexCWIter cvv_cwbegin(VertexHandle _vh) const
{ return ConstVertexVertexCWIter(*this, _vh); }
/// const vertex circulator ccw
ConstVertexVertexCCWIter cvv_ccwbegin(VertexHandle _vh) const
{ return ConstVertexVertexCCWIter(*this, _vh); }
/// const vertex - incoming halfedge circulator /// const vertex - incoming halfedge circulator
ConstVertexIHalfedgeIter cvih_begin(VertexHandle _vh) const ConstVertexIHalfedgeIter cvih_begin(VertexHandle _vh) const
{ return ConstVertexIHalfedgeIter(*this, _vh); } { return ConstVertexIHalfedgeIter(*this, _vh); }
/// const vertex - incoming halfedge circulator cw
ConstVertexIHalfedgeCWIter cvih_cwbegin(VertexHandle _vh) const
{ return ConstVertexIHalfedgeCWIter(*this, _vh); }
/// const vertex - incoming halfedge circulator ccw
ConstVertexIHalfedgeCCWIter cvih_ccwbegin(VertexHandle _vh) const
{ return ConstVertexIHalfedgeCCWIter(*this, _vh); }
/// const vertex - outgoing halfedge circulator /// const vertex - outgoing halfedge circulator
ConstVertexOHalfedgeIter cvoh_begin(VertexHandle _vh) const ConstVertexOHalfedgeIter cvoh_begin(VertexHandle _vh) const
{ return ConstVertexOHalfedgeIter(*this, _vh); } { return ConstVertexOHalfedgeIter(*this, _vh); }
/// const vertex - outgoing halfedge circulator cw
ConstVertexOHalfedgeCWIter cvoh_cwbegin(VertexHandle _vh) const
{ return ConstVertexOHalfedgeCWIter(*this, _vh); }
/// const vertex - outgoing halfedge circulator ccw
ConstVertexOHalfedgeCCWIter cvoh_ccwbegin(VertexHandle _vh) const
{ return ConstVertexOHalfedgeCCWIter(*this, _vh); }
/// const vertex - edge circulator /// const vertex - edge circulator
ConstVertexEdgeIter cve_begin(VertexHandle _vh) const ConstVertexEdgeIter cve_begin(VertexHandle _vh) const
{ return ConstVertexEdgeIter(*this, _vh); } { return ConstVertexEdgeIter(*this, _vh); }
/// const vertex - edge circulator cw
ConstVertexEdgeCWIter cve_cwbegin(VertexHandle _vh) const
{ return ConstVertexEdgeCWIter(*this, _vh); }
/// const vertex - edge circulator ccw
ConstVertexEdgeCCWIter cve_ccwbegin(VertexHandle _vh) const
{ return ConstVertexEdgeCCWIter(*this, _vh); }
/// const vertex - face circulator /// const vertex - face circulator
ConstVertexFaceIter cvf_begin(VertexHandle _vh) const ConstVertexFaceIter cvf_begin(VertexHandle _vh) const
{ return ConstVertexFaceIter(*this, _vh); } { return ConstVertexFaceIter(*this, _vh); }
/// const vertex - face circulator cw
ConstVertexFaceCWIter cvf_cwbegin(VertexHandle _vh) const
{ return ConstVertexFaceCWIter(*this, _vh); }
/// const vertex - face circulator ccw
ConstVertexFaceCCWIter cvf_ccwbegin(VertexHandle _vh) const
{ return ConstVertexFaceCCWIter(*this, _vh); }
/// face - vertex circulator /// face - vertex circulator
FaceVertexIter fv_begin(FaceHandle _fh) FaceVertexIter fv_begin(FaceHandle _fh)
{ return FaceVertexIter(*this, _fh); } { return FaceVertexIter(*this, _fh); }
/// face - vertex circulator cw
FaceVertexCWIter fv_cwbegin(FaceHandle _fh)
{ return FaceVertexCWIter(*this, _fh); }
/// face - vertex circulator ccw
FaceVertexCCWIter fv_ccwbegin(FaceHandle _fh)
{ return FaceVertexCCWIter(*this, _fh); }
/// face - halfedge circulator /// face - halfedge circulator
FaceHalfedgeIter fh_begin(FaceHandle _fh) FaceHalfedgeIter fh_begin(FaceHandle _fh)
{ return FaceHalfedgeIter(*this, _fh); } { return FaceHalfedgeIter(*this, _fh); }
/// face - halfedge circulator cw
FaceHalfedgeCWIter fh_cwbegin(FaceHandle _fh)
{ return FaceHalfedgeCWIter(*this, _fh); }
/// face - halfedge circulator ccw
FaceHalfedgeCCWIter fh_ccwbegin(FaceHandle _fh)
{ return FaceHalfedgeCCWIter(*this, _fh); }
/// face - edge circulator /// face - edge circulator
FaceEdgeIter fe_begin(FaceHandle _fh) FaceEdgeIter fe_begin(FaceHandle _fh)
{ return FaceEdgeIter(*this, _fh); } { return FaceEdgeIter(*this, _fh); }
/// face - edge circulator cw
FaceEdgeCWIter fe_cwbegin(FaceHandle _fh)
{ return FaceEdgeCWIter(*this, _fh); }
/// face - edge circulator ccw
FaceEdgeCCWIter fe_ccwbegin(FaceHandle _fh)
{ return FaceEdgeCCWIter(*this, _fh); }
/// face - face circulator /// face - face circulator
FaceFaceIter ff_begin(FaceHandle _fh) FaceFaceIter ff_begin(FaceHandle _fh)
{ return FaceFaceIter(*this, _fh); } { return FaceFaceIter(*this, _fh); }
/// face - face circulator cw
FaceFaceCWIter ff_cwbegin(FaceHandle _fh)
{ return FaceFaceCWIter(*this, _fh); }
/// face - face circulator ccw
FaceFaceCCWIter ff_ccwbegin(FaceHandle _fh)
{ return FaceFaceCCWIter(*this, _fh); }
/// halfedge circulator /// halfedge circulator
HalfedgeLoopIter hl_begin(HalfedgeHandle _heh) HalfedgeLoopIter hl_begin(HalfedgeHandle _heh)
{ return HalfedgeLoopIter(*this, _heh); } { return HalfedgeLoopIter(*this, _heh); }
/// halfedge circulator
HalfedgeLoopCWIter hl_cwbegin(HalfedgeHandle _heh)
{ return HalfedgeLoopCWIter(*this, _heh); }
/// halfedge circulator ccw
HalfedgeLoopCCWIter hl_ccwbegin(HalfedgeHandle _heh)
{ return HalfedgeLoopCCWIter(*this, _heh); }
/// const face - vertex circulator /// const face - vertex circulator
ConstFaceVertexIter cfv_begin(FaceHandle _fh) const ConstFaceVertexIter cfv_begin(FaceHandle _fh) const
{ return ConstFaceVertexIter(*this, _fh); } { return ConstFaceVertexIter(*this, _fh); }
/// const face - vertex circulator cw
ConstFaceVertexCWIter cfv_cwbegin(FaceHandle _fh) const
{ return ConstFaceVertexCWIter(*this, _fh); }
/// const face - vertex circulator ccw
ConstFaceVertexCCWIter cfv_ccwbegin(FaceHandle _fh) const
{ return ConstFaceVertexCCWIter(*this, _fh); }
/// const face - halfedge circulator /// const face - halfedge circulator
ConstFaceHalfedgeIter cfh_begin(FaceHandle _fh) const ConstFaceHalfedgeIter cfh_begin(FaceHandle _fh) const
{ return ConstFaceHalfedgeIter(*this, _fh); } { return ConstFaceHalfedgeIter(*this, _fh); }
/// const face - halfedge circulator cw
ConstFaceHalfedgeCWIter cfh_cwbegin(FaceHandle _fh) const
{ return ConstFaceHalfedgeCWIter(*this, _fh); }
/// const face - halfedge circulator ccw
ConstFaceHalfedgeCCWIter cfh_ccwbegin(FaceHandle _fh) const
{ return ConstFaceHalfedgeCCWIter(*this, _fh); }
/// const face - edge circulator /// const face - edge circulator
ConstFaceEdgeIter cfe_begin(FaceHandle _fh) const ConstFaceEdgeIter cfe_begin(FaceHandle _fh) const
{ return ConstFaceEdgeIter(*this, _fh); } { return ConstFaceEdgeIter(*this, _fh); }
/// const face - edge circulator cw
ConstFaceEdgeCWIter cfe_cwbegin(FaceHandle _fh) const
{ return ConstFaceEdgeCWIter(*this, _fh); }
/// const face - edge circulator ccw
ConstFaceEdgeCCWIter cfe_ccwbegin(FaceHandle _fh) const
{ return ConstFaceEdgeCCWIter(*this, _fh); }
/// const face - face circulator /// const face - face circulator
ConstFaceFaceIter cff_begin(FaceHandle _fh) const ConstFaceFaceIter cff_begin(FaceHandle _fh) const
{ return ConstFaceFaceIter(*this, _fh); } { return ConstFaceFaceIter(*this, _fh); }
/// const face - face circulator cw
ConstFaceFaceCWIter cff_cwbegin(FaceHandle _fh) const
{ return ConstFaceFaceCWIter(*this, _fh); }
/// const face - face circulator ccw
ConstFaceFaceCCWIter cff_ccwbegin(FaceHandle _fh) const
{ return ConstFaceFaceCCWIter(*this, _fh); }
/// const halfedge circulator /// const halfedge circulator
ConstHalfedgeLoopIter chl_begin(HalfedgeHandle _heh) const ConstHalfedgeLoopIter chl_begin(HalfedgeHandle _heh) const
{ return ConstHalfedgeLoopIter(*this, _heh); } { return ConstHalfedgeLoopIter(*this, _heh); }
/// const halfedge circulator cw
ConstHalfedgeLoopCWIter chl_cwbegin(HalfedgeHandle _heh) const
{ return ConstHalfedgeLoopCWIter(*this, _heh); }
/// const halfedge circulator ccw
ConstHalfedgeLoopCCWIter chl_ccwbegin(HalfedgeHandle _heh) const
{ return ConstHalfedgeLoopCCWIter(*this, _heh); }
// 'end' circulators // 'end' circulators
/// vertex - vertex circulator /// vertex - vertex circulator
VertexVertexIter vv_end(VertexHandle _vh) VertexVertexIter vv_end(VertexHandle _vh)
{ return VertexVertexIter(*this, _vh, true); } { return VertexVertexIter(*this, _vh, true); }
/// vertex - vertex circulator cw
VertexVertexCWIter vv_cwend(VertexHandle _vh)
{ return VertexVertexCWIter(*this, _vh, true); }
/// vertex - vertex circulator ccw
VertexVertexCCWIter vv_ccwend(VertexHandle _vh)
{ return VertexVertexCCWIter(*this, _vh, true); }
/// vertex - incoming halfedge circulator /// vertex - incoming halfedge circulator
VertexIHalfedgeIter vih_end(VertexHandle _vh) VertexIHalfedgeIter vih_end(VertexHandle _vh)
{ return VertexIHalfedgeIter(*this, _vh, true); } { return VertexIHalfedgeIter(*this, _vh, true); }
/// vertex - incoming halfedge circulator cw
VertexIHalfedgeCWIter vih_cwend(VertexHandle _vh)
{ return VertexIHalfedgeCWIter(*this, _vh, true); }
/// vertex - incoming halfedge circulator ccw
VertexIHalfedgeCCWIter vih_ccwend(VertexHandle _vh)
{ return VertexIHalfedgeCCWIter(*this, _vh, true); }
/// vertex - outgoing halfedge circulator /// vertex - outgoing halfedge circulator
VertexOHalfedgeIter voh_end(VertexHandle _vh) VertexOHalfedgeIter voh_end(VertexHandle _vh)
{ return VertexOHalfedgeIter(*this, _vh, true); } { return VertexOHalfedgeIter(*this, _vh, true); }
/// vertex - outgoing halfedge circulator cw
VertexOHalfedgeCWIter voh_cwend(VertexHandle _vh)
{ return VertexOHalfedgeCWIter(*this, _vh, true); }
/// vertex - outgoing halfedge circulator ccw
VertexOHalfedgeCCWIter voh_ccwend(VertexHandle _vh)
{ return VertexOHalfedgeCCWIter(*this, _vh, true); }
/// vertex - edge circulator /// vertex - edge circulator
VertexEdgeIter ve_end(VertexHandle _vh) VertexEdgeIter ve_end(VertexHandle _vh)
{ return VertexEdgeIter(*this, _vh, true); } { return VertexEdgeIter(*this, _vh, true); }
/// vertex - edge circulator cw
VertexEdgeCWIter ve_cwend(VertexHandle _vh)
{ return VertexEdgeCWIter(*this, _vh, true); }
/// vertex - edge circulator ccw
VertexEdgeCCWIter ve_ccwend(VertexHandle _vh)
{ return VertexEdgeCCWIter(*this, _vh, true); }
/// vertex - face circulator /// vertex - face circulator
VertexFaceIter vf_end(VertexHandle _vh) VertexFaceIter vf_end(VertexHandle _vh)
{ return VertexFaceIter(*this, _vh, true); } { return VertexFaceIter(*this, _vh, true); }
/// vertex - face circulator cw
VertexFaceCWIter vf_cwend(VertexHandle _vh)
{ return VertexFaceCWIter(*this, _vh, true); }
/// vertex - face circulator ccw
VertexFaceCCWIter vf_ccwend(VertexHandle _vh)
{ return VertexFaceCCWIter(*this, _vh, true); }
/// const vertex circulator /// const vertex circulator
ConstVertexVertexIter cvv_end(VertexHandle _vh) const ConstVertexVertexIter cvv_end(VertexHandle _vh) const
{ return ConstVertexVertexIter(*this, _vh, true); } { return ConstVertexVertexIter(*this, _vh, true); }
/// const vertex circulator cw
ConstVertexVertexCWIter cvv_cwend(VertexHandle _vh) const
{ return ConstVertexVertexCWIter(*this, _vh, true); }
/// const vertex circulator ccw
ConstVertexVertexCCWIter cvv_ccwend(VertexHandle _vh) const
{ return ConstVertexVertexCCWIter(*this, _vh, true); }
/// const vertex - incoming halfedge circulator /// const vertex - incoming halfedge circulator
ConstVertexIHalfedgeIter cvih_end(VertexHandle _vh) const ConstVertexIHalfedgeIter cvih_end(VertexHandle _vh) const
{ return ConstVertexIHalfedgeIter(*this, _vh, true); } { return ConstVertexIHalfedgeIter(*this, _vh, true); }
/// const vertex - incoming halfedge circulator cw
ConstVertexIHalfedgeCWIter cvih_cwend(VertexHandle _vh) const
{ return ConstVertexIHalfedgeCWIter(*this, _vh, true); }
/// const vertex - incoming halfedge circulator ccw
ConstVertexIHalfedgeCCWIter cvih_ccwend(VertexHandle _vh) const
{ return ConstVertexIHalfedgeCCWIter(*this, _vh, true); }
/// const vertex - outgoing halfedge circulator /// const vertex - outgoing halfedge circulator
ConstVertexOHalfedgeIter cvoh_end(VertexHandle _vh) const ConstVertexOHalfedgeIter cvoh_end(VertexHandle _vh) const
{ return ConstVertexOHalfedgeIter(*this, _vh, true); } { return ConstVertexOHalfedgeIter(*this, _vh, true); }
/// const vertex - outgoing halfedge circulator cw
ConstVertexOHalfedgeCWIter cvoh_cwend(VertexHandle _vh) const
{ return ConstVertexOHalfedgeCWIter(*this, _vh, true); }
/// const vertex - outgoing halfedge circulator ccw
ConstVertexOHalfedgeCCWIter cvoh_ccwend(VertexHandle _vh) const
{ return ConstVertexOHalfedgeCCWIter(*this, _vh, true); }
/// const vertex - edge circulator /// const vertex - edge circulator
ConstVertexEdgeIter cve_end(VertexHandle _vh) const ConstVertexEdgeIter cve_end(VertexHandle _vh) const
{ return ConstVertexEdgeIter(*this, _vh, true); } { return ConstVertexEdgeIter(*this, _vh, true); }
/// const vertex - edge circulator cw
ConstVertexEdgeCWIter cve_cwend(VertexHandle _vh) const
{ return ConstVertexEdgeCWIter(*this, _vh, true); }
/// const vertex - edge circulator ccw
ConstVertexEdgeCCWIter cve_ccwend(VertexHandle _vh) const
{ return ConstVertexEdgeCCWIter(*this, _vh, true); }
/// const vertex - face circulator /// const vertex - face circulator
ConstVertexFaceIter cvf_end(VertexHandle _vh) const ConstVertexFaceIter cvf_end(VertexHandle _vh) const
{ return ConstVertexFaceIter(*this, _vh, true); } { return ConstVertexFaceIter(*this, _vh, true); }
/// const vertex - face circulator cw
ConstVertexFaceCWIter cvf_cwend(VertexHandle _vh) const
{ return ConstVertexFaceCWIter(*this, _vh, true); }
/// const vertex - face circulator ccw
ConstVertexFaceCCWIter cvf_ccwend(VertexHandle _vh) const
{ return ConstVertexFaceCCWIter(*this, _vh, true); }
/// face - vertex circulator /// face - vertex circulator
FaceVertexIter fv_end(FaceHandle _fh) FaceVertexIter fv_end(FaceHandle _fh)
{ return FaceVertexIter(*this, _fh, true); } { return FaceVertexIter(*this, _fh, true); }
/// face - vertex circulator cw
FaceVertexCWIter fv_cwend(FaceHandle _fh)
{ return FaceVertexCWIter(*this, _fh, true); }
/// face - vertex circulator ccw
FaceVertexCCWIter fv_ccwend(FaceHandle _fh)
{ return FaceVertexCCWIter(*this, _fh, true); }
/// face - halfedge circulator /// face - halfedge circulator
FaceHalfedgeIter fh_end(FaceHandle _fh) FaceHalfedgeIter fh_end(FaceHandle _fh)
{ return FaceHalfedgeIter(*this, _fh, true); } { return FaceHalfedgeIter(*this, _fh, true); }
/// face - halfedge circulator cw
FaceHalfedgeCWIter fh_cwend(FaceHandle _fh)
{ return FaceHalfedgeCWIter(*this, _fh, true); }
/// face - halfedge circulator ccw
FaceHalfedgeCCWIter fh_ccwend(FaceHandle _fh)
{ return FaceHalfedgeCCWIter(*this, _fh, true); }
/// face - edge circulator /// face - edge circulator
FaceEdgeIter fe_end(FaceHandle _fh) FaceEdgeIter fe_end(FaceHandle _fh)
{ return FaceEdgeIter(*this, _fh, true); } { return FaceEdgeIter(*this, _fh, true); }
/// face - edge circulator cw
FaceEdgeCWIter fe_cwend(FaceHandle _fh)
{ return FaceEdgeCWIter(*this, _fh, true); }
/// face - edge circulator ccw
FaceEdgeCCWIter fe_ccwend(FaceHandle _fh)
{ return FaceEdgeCCWIter(*this, _fh, true); }
/// face - face circulator /// face - face circulator
FaceFaceIter ff_end(FaceHandle _fh) FaceFaceIter ff_end(FaceHandle _fh)
{ return FaceFaceIter(*this, _fh, true); } { return FaceFaceIter(*this, _fh, true); }
/// face - face circulator cw
FaceFaceCWIter ff_cwend(FaceHandle _fh)
{ return FaceFaceCWIter(*this, _fh, true); }
/// face - face circulator ccw
FaceFaceCCWIter ff_ccwend(FaceHandle _fh)
{ return FaceFaceCCWIter(*this, _fh, true); }
/// face - face circulator /// face - face circulator
HalfedgeLoopIter hl_end(HalfedgeHandle _heh) HalfedgeLoopIter hl_end(HalfedgeHandle _heh)
{ return HalfedgeLoopIter(*this, _heh, true); } { return HalfedgeLoopIter(*this, _heh, true); }
/// face - face circulator cw
HalfedgeLoopCWIter hl_cwend(HalfedgeHandle _heh)
{ return HalfedgeLoopCWIter(*this, _heh, true); }
/// face - face circulator ccw
HalfedgeLoopCCWIter hl_ccwend(HalfedgeHandle _heh)
{ return HalfedgeLoopCCWIter(*this, _heh, true); }
/// const face - vertex circulator /// const face - vertex circulator
ConstFaceVertexIter cfv_end(FaceHandle _fh) const ConstFaceVertexIter cfv_end(FaceHandle _fh) const
{ return ConstFaceVertexIter(*this, _fh, true); } { return ConstFaceVertexIter(*this, _fh, true); }
/// const face - vertex circulator cw
ConstFaceVertexCWIter cfv_cwend(FaceHandle _fh) const
{ return ConstFaceVertexCWIter(*this, _fh, true); }
/// const face - vertex circulator ccw
ConstFaceVertexCCWIter cfv_ccwend(FaceHandle _fh) const
{ return ConstFaceVertexCCWIter(*this, _fh, true); }
/// const face - halfedge circulator /// const face - halfedge circulator
ConstFaceHalfedgeIter cfh_end(FaceHandle _fh) const ConstFaceHalfedgeIter cfh_end(FaceHandle _fh) const
{ return ConstFaceHalfedgeIter(*this, _fh, true); } { return ConstFaceHalfedgeIter(*this, _fh, true); }
/// const face - halfedge circulator cw
ConstFaceHalfedgeCWIter cfh_cwend(FaceHandle _fh) const
{ return ConstFaceHalfedgeCWIter(*this, _fh, true); }
/// const face - halfedge circulator ccw
ConstFaceHalfedgeCCWIter cfh_ccwend(FaceHandle _fh) const
{ return ConstFaceHalfedgeCCWIter(*this, _fh, true); }
/// const face - edge circulator /// const face - edge circulator
ConstFaceEdgeIter cfe_end(FaceHandle _fh) const ConstFaceEdgeIter cfe_end(FaceHandle _fh) const
{ return ConstFaceEdgeIter(*this, _fh, true); } { return ConstFaceEdgeIter(*this, _fh, true); }
/// const face - edge circulator cw
ConstFaceEdgeCWIter cfe_cwend(FaceHandle _fh) const
{ return ConstFaceEdgeCWIter(*this, _fh, true); }
/// const face - edge circulator ccw
ConstFaceEdgeCCWIter cfe_ccwend(FaceHandle _fh) const
{ return ConstFaceEdgeCCWIter(*this, _fh, true); }
/// const face - face circulator /// const face - face circulator
ConstFaceFaceIter cff_end(FaceHandle _fh) const ConstFaceFaceIter cff_end(FaceHandle _fh) const
{ return ConstFaceFaceIter(*this, _fh, true); } { return ConstFaceFaceIter(*this, _fh, true); }
/// const face - face circulator /// const face - face circulator
ConstFaceFaceCWIter cff_cwend(FaceHandle _fh) const
{ return ConstFaceFaceCWIter(*this, _fh, true); }
/// const face - face circulator
ConstFaceFaceCCWIter cff_ccwend(FaceHandle _fh) const
{ return ConstFaceFaceCCWIter(*this, _fh, true); }
/// const face - face circulator
ConstHalfedgeLoopIter chl_end(HalfedgeHandle _heh) const ConstHalfedgeLoopIter chl_end(HalfedgeHandle _heh) const
{ return ConstHalfedgeLoopIter(*this, _heh, true); } { return ConstHalfedgeLoopIter(*this, _heh, true); }
/// const face - face circulator cw
ConstHalfedgeLoopCWIter chl_cwend(HalfedgeHandle _heh) const
{ return ConstHalfedgeLoopCWIter(*this, _heh, true); }
/// const face - face circulator ccw
ConstHalfedgeLoopCCWIter chl_ccwend(HalfedgeHandle _heh) const
{ return ConstHalfedgeLoopCCWIter(*this, _heh, true); }
//@} //@}
/** @name Range based iterators and circulators */ /** @name Range based iterators and circulators */

View File

@@ -2,6 +2,7 @@
#include <Unittests/unittests_common.hh> #include <Unittests/unittests_common.hh>
#include <iostream> #include <iostream>
#include <algorithm>
namespace { namespace {
@@ -129,6 +130,145 @@ TEST_F(OpenMeshTrimeshCirculatorFaceEdge, FaceEdgeIterWithoutHolesIncrement) {
} }
} }
/*
* test CW and CCW iterators
*/
TEST_F(OpenMeshTrimeshCirculatorFaceEdge, CWAndCCWTest) {
mesh_.clear();
// Add some vertices
Mesh::VertexHandle vhandle[6];
vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
vhandle[3] = mesh_.add_vertex(Mesh::Point(3, 0, 0));
vhandle[4] = mesh_.add_vertex(Mesh::Point(4, 1, 0));
vhandle[5] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
// Add three faces
std::vector<Mesh::VertexHandle> face_vhandles;
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[2]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[3]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[5]);
face_vhandles.push_back(vhandle[3]);
mesh_.add_face(face_vhandles);
/* Test setup:
*
* 0 ------ 2 ------ 4
* \ / \ /
* \ 0 / \ 2 /
* \ / 1 \ /
* 1 ------- 3
* \ /
* \ 3 /
* \ /
* \ /
* 5
*/
int indices[4] = {4, 1, 3, 4};
int rev_indices[4];
std::reverse_copy(indices,indices+4,rev_indices);
//CCW
Mesh::FaceEdgeCCWIter fe_ccwit = mesh_.fe_ccwbegin(mesh_.face_handle(1));
Mesh::FaceEdgeCCWIter fe_ccwend = mesh_.fe_ccwend(mesh_.face_handle(1));
size_t i = 0;
for (;fe_ccwit != fe_ccwend; ++fe_ccwit, ++i)
{
EXPECT_EQ(indices[i], fe_ccwit->idx()) << "Index wrong in FaceEdgeCCWIter";
}
EXPECT_FALSE(fe_ccwit.is_valid()) << "Iterator invalid in FaceEdgeCCWIter at end";
EXPECT_TRUE( fe_ccwit == fe_ccwend ) << "End iterator for FaceEdgeCCWIter not matching";
//constant CCW
Mesh::ConstFaceEdgeCCWIter cfe_ccwit = mesh_.cfe_ccwbegin(mesh_.face_handle(1));
Mesh::ConstFaceEdgeCCWIter cfe_ccwend = mesh_.cfe_ccwend(mesh_.face_handle(1));
i = 0;
for (;cfe_ccwit != cfe_ccwend; ++cfe_ccwit, ++i)
{
EXPECT_EQ(indices[i], cfe_ccwit->idx()) << "Index wrong in ConstFaceEdgeCCWIter";
}
EXPECT_FALSE(cfe_ccwit.is_valid()) << "Iterator invalid in ConstFaceEdgeCCWIter at end";
EXPECT_TRUE( cfe_ccwit == cfe_ccwend ) << "End iterator for ConstFaceEdgeCCWIter not matching";
//CW
Mesh::FaceEdgeCWIter fe_cwit = mesh_.fe_cwbegin(mesh_.face_handle(1));
Mesh::FaceEdgeCWIter fe_cwend = mesh_.fe_cwend(mesh_.face_handle(1));
i = 0;
for (;fe_cwit != fe_cwend; ++fe_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], fe_cwit->idx()) << "Index wrong in FaceEdgeCWIter";
}
EXPECT_FALSE(fe_cwit.is_valid()) << "Iterator invalid in FaceEdgeCWIter at end";
EXPECT_TRUE( fe_cwit == fe_cwend ) << "End iterator for FaceEdgeCWIter not matching";
//constant CW
Mesh::ConstFaceEdgeCWIter cfe_cwit = mesh_.cfe_cwbegin(mesh_.face_handle(1));
Mesh::ConstFaceEdgeCWIter cfe_cwend = mesh_.cfe_cwend(mesh_.face_handle(1));
i = 0;
for (;cfe_cwit != cfe_cwend; ++cfe_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], cfe_cwit->idx()) << "Index wrong in ConstFaceEdgeCWIter";
}
EXPECT_FALSE(cfe_cwit.is_valid()) << "Iterator invalid in ConstFaceEdgeCWIter at end";
EXPECT_TRUE( cfe_cwit == cfe_cwend ) << "End iterator for ConstFaceEdgeCWIter not matching";
/*
* conversion properties:
* a) cw_begin == CWIter(ccw_begin())
* b) cw_iter->idx() == CCWIter(cw_iter)->idx() for valid iterators
* c) --cw_iter == CWIter(++ccwIter) for valid iterators
* d) cw_end == CWIter(ccw_end()) => --cw_end != CWIter(++ccw_end()) *
*/
Mesh::FaceEdgeCWIter fe_cwIter = mesh_.fe_cwbegin(mesh_.face_handle(1));
// a)
EXPECT_TRUE( fe_cwIter == Mesh::FaceEdgeCWIter(mesh_.fe_ccwbegin(mesh_.face_handle(1))) ) << "ccw to cw conversion failed";
EXPECT_TRUE( Mesh::FaceEdgeCCWIter(fe_cwIter) == mesh_.fe_ccwbegin(mesh_.face_handle(1)) ) << "cw to ccw conversion failed";
// b)
EXPECT_EQ( fe_cwIter->idx(), Mesh::FaceEdgeCCWIter(fe_cwIter)->idx()) << "iterators doesnt point on the same element";
// c)
++fe_cwIter;
fe_ccwend = mesh_.fe_ccwend(mesh_.face_handle(1));
--fe_ccwend;
EXPECT_EQ(fe_cwIter->idx(),fe_ccwend->idx()) << "iteratoes are not equal after inc/dec";
// additional conversion check
fe_ccwend = Mesh::FaceEdgeCCWIter(fe_cwIter);
EXPECT_EQ(fe_cwIter->idx(),fe_ccwend->idx())<< "iterators doesnt point on the same element";
// d)
fe_cwIter = Mesh::FaceEdgeCWIter(mesh_.fe_ccwend(mesh_.face_handle(1)));
EXPECT_FALSE(fe_cwIter.is_valid()) << "end iterator is not invalid";
EXPECT_TRUE(Mesh::FaceEdgeCCWIter(mesh_.fe_cwend(mesh_.face_handle(1))) == mesh_.fe_ccwend(mesh_.face_handle(1))) << "end iterators are not equal";
}
/* /*
* Test if the end iterator stays invalid after one lap * Test if the end iterator stays invalid after one lap

View File

@@ -2,6 +2,7 @@
#include <Unittests/unittests_common.hh> #include <Unittests/unittests_common.hh>
#include <iostream> #include <iostream>
#include <algorithm>
namespace { namespace {
@@ -205,6 +206,146 @@ TEST_F(OpenMeshTrimeshCirculatorFaceFace, FaceFaceIterWithoutHoles) {
} }
/*
* Test CW and CCW iterators
*/
TEST_F(OpenMeshTrimeshCirculatorFaceFace, CWAndCCWCheck) {
mesh_.clear();
// Add some vertices
Mesh::VertexHandle vhandle[6];
vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
vhandle[3] = mesh_.add_vertex(Mesh::Point(3, 0, 0));
vhandle[4] = mesh_.add_vertex(Mesh::Point(4, 1, 0));
vhandle[5] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
// Add three faces
std::vector<Mesh::VertexHandle> face_vhandles;
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[2]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[3]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[5]);
face_vhandles.push_back(vhandle[3]);
mesh_.add_face(face_vhandles);
/* Test setup:
*
* 0 ------ 2 ------ 4
* \ / \ /
* \ 0 / \ 2 /
* \ / 1 \ /
* 1 ------- 3
* \ /
* \ 3 /
* \ /
* \ /
* 5
*/
int indices[4] = {2, 0, 3, 2};
int rev_indices[4];
std::reverse_copy(indices,indices+4,rev_indices);
//CCW
Mesh::FaceFaceCCWIter ff_ccwit = mesh_.ff_ccwbegin(mesh_.face_handle(1));
Mesh::FaceFaceCCWIter ff_ccwend = mesh_.ff_ccwend(mesh_.face_handle(1));
size_t i = 0;
for (;ff_ccwit != ff_ccwend; ++ff_ccwit, ++i)
{
EXPECT_EQ(indices[i], ff_ccwit->idx()) << "Index wrong in FaceFaceCCWIter";
}
EXPECT_FALSE(ff_ccwit.is_valid()) << "Iterator invalid in FaceFaceCCWIter at end";
EXPECT_TRUE( ff_ccwit == ff_ccwend ) << "End iterator for FaceFaceCCWIter not matching";
//constant CCW
Mesh::ConstFaceFaceCCWIter cff_ccwit = mesh_.cff_ccwbegin(mesh_.face_handle(1));
Mesh::ConstFaceFaceCCWIter cff_ccwend = mesh_.cff_ccwend(mesh_.face_handle(1));
i = 0;
for (;cff_ccwit != cff_ccwend; ++cff_ccwit, ++i)
{
EXPECT_EQ(indices[i], cff_ccwit->idx()) << "Index wrong in ConstFaceFaceCCWIter";
}
EXPECT_FALSE(cff_ccwit.is_valid()) << "Iterator invalid in ConstFaceFaceCCWIter at end";
EXPECT_TRUE( cff_ccwit == cff_ccwend ) << "End iterator for ConstFaceFaceCCWIter not matching";
//CW
Mesh::FaceFaceCWIter ff_cwit = mesh_.ff_cwbegin(mesh_.face_handle(1));
Mesh::FaceFaceCWIter ff_cwend = mesh_.ff_cwend(mesh_.face_handle(1));
i = 0;
for (;ff_cwit != ff_cwend; ++ff_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], ff_cwit->idx()) << "Index wrong in FaceFaceCWIter";
}
EXPECT_FALSE(ff_cwit.is_valid()) << "Iterator invalid in FaceFaceCWIter at end";
EXPECT_TRUE( ff_cwit == ff_cwend ) << "End iterator for FaceFaceCWIter not matching";
//constant CW
Mesh::ConstFaceFaceCWIter cff_cwit = mesh_.cff_cwbegin(mesh_.face_handle(1));
Mesh::ConstFaceFaceCWIter cff_cwend = mesh_.cff_cwend(mesh_.face_handle(1));
i = 0;
for (;cff_cwit != cff_cwend; ++cff_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], cff_cwit->idx()) << "Index wrong in ConstFaceFaceCWIter";
}
EXPECT_FALSE(cff_cwit.is_valid()) << "Iterator invalid in ConstFaceFaceCWIter at end";
EXPECT_TRUE( cff_cwit == cff_cwend ) << "End iterator for ConstFaceFaceCWIter not matching";
/*
* conversion properties:
* a) cw_begin == CWIter(ccw_begin())
* b) cw_iter->idx() == CCWIter(cw_iter)->idx() for valid iterators
* c) --cw_iter == CWIter(++ccwIter) for valid iterators
* d) cw_end == CWIter(ccw_end()) => --cw_end != CWIter(++ccw_end()) *
*/
Mesh::FaceFaceCWIter ff_cwIter = mesh_.ff_cwbegin(mesh_.face_handle(1));
// a)
EXPECT_TRUE( ff_cwIter == Mesh::FaceFaceCWIter(mesh_.ff_ccwbegin(mesh_.face_handle(1))) ) << "ccw to cw conversion failed";
EXPECT_TRUE( Mesh::FaceFaceCCWIter(ff_cwIter) == mesh_.ff_ccwbegin(mesh_.face_handle(1)) ) << "cw to ccw conversion failed";
// b)
EXPECT_EQ( ff_cwIter->idx(), Mesh::FaceFaceCCWIter(ff_cwIter)->idx()) << "iterators doesnt point on the same element";
// c)
++ff_cwIter;
ff_ccwend = mesh_.ff_ccwend(mesh_.face_handle(1));
--ff_ccwend;
EXPECT_EQ(ff_cwIter->idx(),ff_ccwend->idx()) << "iteratoes are not equal after inc/dec";
// additional conversion check
ff_ccwend = Mesh::FaceFaceCCWIter(ff_cwIter);
EXPECT_EQ(ff_cwIter->idx(),ff_ccwend->idx())<< "iterators doesnt point on the same element";
// d)
ff_cwIter = Mesh::FaceFaceCWIter(mesh_.ff_ccwend(mesh_.face_handle(1)));
EXPECT_FALSE(ff_cwIter.is_valid()) << "end iterator is not invalid";
EXPECT_TRUE(Mesh::FaceFaceCCWIter(mesh_.ff_cwend(mesh_.face_handle(1))) == mesh_.ff_ccwend(mesh_.face_handle(1))) << "end iterators are not equal";
}
/* /*

View File

@@ -2,6 +2,7 @@
#include <Unittests/unittests_common.hh> #include <Unittests/unittests_common.hh>
#include <iostream> #include <iostream>
#include <algorithm>
namespace { namespace {
@@ -127,6 +128,146 @@ TEST_F(OpenMeshTrimeshCirculatorFaceHalfEdge, FaceHalfedgeIterWithoutHolesIncrem
} }
/*
* test CW and CCW iterators
*/
TEST_F(OpenMeshTrimeshCirculatorFaceHalfEdge, CWAndCCWTest) {
mesh_.clear();
// Add some vertices
Mesh::VertexHandle vhandle[6];
vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
vhandle[3] = mesh_.add_vertex(Mesh::Point(3, 0, 0));
vhandle[4] = mesh_.add_vertex(Mesh::Point(4, 1, 0));
vhandle[5] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
// Add three faces
std::vector<Mesh::VertexHandle> face_vhandles;
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[2]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[3]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[5]);
face_vhandles.push_back(vhandle[3]);
mesh_.add_face(face_vhandles);
/* Test setup:
*
* 0 ------ 2 ------ 4
* \ / \ /
* \ 0 / \ 2 /
* \ / 1 \ /
* 1 ------- 3
* \ /
* \ 3 /
* \ /
* \ /
* 5
*/
int indices[4] = {8, 3, 6, 8};
int rev_indices[4];
std::reverse_copy(indices,indices+4,rev_indices);
//CCW
Mesh::FaceHalfedgeIter fh_ccwit = mesh_.fh_ccwbegin(mesh_.face_handle(1));
Mesh::FaceHalfedgeIter fh_ccwend = mesh_.fh_ccwend(mesh_.face_handle(1));
size_t i = 0;
for (;fh_ccwit != fh_ccwend; ++fh_ccwit, ++i)
{
EXPECT_EQ(indices[i], fh_ccwit->idx()) << "Index wrong in FaceHalfedgeIter";
}
EXPECT_FALSE(fh_ccwit.is_valid()) << "Iterator invalid in FaceHalfedgeIter at end";
EXPECT_TRUE( fh_ccwit == fh_ccwend ) << "End iterator for FaceHalfedgeIter not matching";
//constant CCW
Mesh::ConstFaceHalfedgeIter cfh_ccwit = mesh_.cfh_ccwbegin(mesh_.face_handle(1));
Mesh::ConstFaceHalfedgeIter cfh_ccwend = mesh_.cfh_ccwend(mesh_.face_handle(1));
i = 0;
for (;cfh_ccwit != cfh_ccwend; ++cfh_ccwit, ++i)
{
EXPECT_EQ(indices[i], cfh_ccwit->idx()) << "Index wrong in ConstFaceHalfedgeIter";
}
EXPECT_FALSE(cfh_ccwit.is_valid()) << "Iterator invalid in ConstFaceHalfedgeIter at end";
EXPECT_TRUE( cfh_ccwit == cfh_ccwend ) << "End iterator for ConstFaceHalfedgeIter not matching";
//CW
Mesh::FaceHalfedgeCWIter fh_cwit = mesh_.fh_cwbegin(mesh_.face_handle(1));
Mesh::FaceHalfedgeCWIter fh_cwend = mesh_.fh_cwend(mesh_.face_handle(1));
i = 0;
for (;fh_cwit != fh_cwend; ++fh_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], fh_cwit->idx()) << "Index wrong in FaceHalfedgeCWIter";
}
EXPECT_FALSE(fh_cwit.is_valid()) << "Iterator invalid in FaceHalfedgeCWIter at end";
EXPECT_TRUE( fh_cwit == fh_cwend ) << "End iterator for FaceHalfedgeCWIter not matching";
//constant CW
Mesh::ConstFaceHalfedgeCWIter cfh_cwit = mesh_.cfh_cwbegin(mesh_.face_handle(1));
Mesh::ConstFaceHalfedgeCWIter cfh_cwend = mesh_.cfh_cwend(mesh_.face_handle(1));
i = 0;
for (;cfh_cwit != cfh_cwend; ++cfh_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], cfh_cwit->idx()) << "Index wrong in ConstFaceHalfedgeCWIter";
}
EXPECT_FALSE(cfh_cwit.is_valid()) << "Iterator invalid in ConstFaceHalfedgeCWIter at end";
EXPECT_TRUE( cfh_cwit == cfh_cwend ) << "End iterator for ConstFaceHalfedgeCWIter not matching";
/*
* conversion properties:
* a) cw_begin == CWIter(ccw_begin())
* b) cw_iter->idx() == CCWIter(cw_iter)->idx() for valid iterators
* c) --cw_iter == CWIter(++ccwIter) for valid iterators
* d) cw_end == CWIter(ccw_end()) => --cw_end != CWIter(++ccw_end()) *
*/
Mesh::FaceHalfedgeCWIter fh_cwIter = mesh_.fh_cwbegin(mesh_.face_handle(1));
// a)
EXPECT_TRUE( fh_cwIter == Mesh::FaceHalfedgeCWIter(mesh_.fh_ccwbegin(mesh_.face_handle(1))) ) << "ccw to cw conversion failed";
EXPECT_TRUE( Mesh::FaceHalfedgeCCWIter(fh_cwIter) == mesh_.fh_ccwbegin(mesh_.face_handle(1)) ) << "cw to ccw conversion failed";
// b)
EXPECT_EQ( fh_cwIter->idx(), Mesh::FaceHalfedgeCCWIter(fh_cwIter)->idx()) << "iterators doesnt point on the same element";
// c)
++fh_cwIter;
fh_ccwend = mesh_.fh_ccwend(mesh_.face_handle(1));
--fh_ccwend;
EXPECT_EQ(fh_cwIter->idx(),fh_ccwend->idx()) << "iteratoes are not equal after inc/dec";
// additional conversion check
fh_ccwend = Mesh::FaceHalfedgeCCWIter(fh_cwIter);
EXPECT_EQ(fh_cwIter->idx(),fh_ccwend->idx())<< "iterators doesnt point on the same element";
// d)
fh_cwIter = Mesh::FaceHalfedgeCWIter(mesh_.fh_ccwend(mesh_.face_handle(1)));
EXPECT_FALSE(fh_cwIter.is_valid()) << "end iterator is not invalid";
EXPECT_TRUE(Mesh::FaceHalfedgeCCWIter(mesh_.fh_cwend(mesh_.face_handle(1))) == mesh_.fh_ccwend(mesh_.face_handle(1))) << "end iterators are not equal";
}
/* /*
* Test if the end iterator stays invalid after one lap * Test if the end iterator stays invalid after one lap

View File

@@ -206,5 +206,139 @@ TEST_F(OpenMeshTrimeshCirculatorFaceVertex, FaceVertexIterCheckInvalidationAtEnd
} }
/*
* Test CW and CCW iterators
*/
TEST_F(OpenMeshTrimeshCirculatorFaceVertex, CWAndCCWCheck) {
mesh_.clear();
// Add some vertices
Mesh::VertexHandle vhandle[5];
vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
vhandle[3] = mesh_.add_vertex(Mesh::Point(0,-1, 0));
vhandle[4] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
// Add two faces
std::vector<Mesh::VertexHandle> face_vhandles;
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[2]);
Mesh::FaceHandle fh0 = mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[1]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
/* Test setup:
0 ==== 2
|\ 0 /|
| \ / |
|2 1 3|
| / \ |
|/ 1 \|
3 ==== 4 */
int indices[4] = {0, 1, 2, 0};
int rev_indices[4];
std::reverse_copy(indices,indices+4,rev_indices);
//CCW
Mesh::FaceVertexCCWIter fv_ccwit = mesh_.fv_ccwbegin(fh0);
Mesh::FaceVertexCCWIter fv_ccwend = mesh_.fv_ccwend(fh0);
size_t i = 0;
for (;fv_ccwit != fv_ccwend; ++fv_ccwit, ++i)
{
EXPECT_EQ(indices[i], fv_ccwit->idx()) << "Index wrong in FaceVertexCCWIter";
}
EXPECT_FALSE(fv_ccwit.is_valid()) << "Iterator invalid in FaceVertexCCWIter at end";
EXPECT_TRUE( fv_ccwit == fv_ccwend ) << "End iterator for FaceVertexCCWIter not matching";
//constant CCW
Mesh::ConstFaceVertexCCWIter cfv_ccwit = mesh_.cfv_ccwbegin(fh0);
Mesh::ConstFaceVertexCCWIter cfv_ccwend = mesh_.cfv_ccwend(fh0);
i = 0;
for (;cfv_ccwit != cfv_ccwend; ++cfv_ccwit, ++i)
{
EXPECT_EQ(indices[i], cfv_ccwit->idx()) << "Index wrong in ConstFaceVertexCCWIter";
}
EXPECT_FALSE(cfv_ccwit.is_valid()) << "Iterator invalid in ConstFaceVertexCCWIter at end";
EXPECT_TRUE( cfv_ccwit == cfv_ccwend ) << "End iterator for ConstFaceVertexCCWIter not matching";
//CW
Mesh::FaceVertexCWIter fv_cwit = mesh_.fv_cwbegin(fh0);
Mesh::FaceVertexCWIter fv_cwend = mesh_.fv_cwend(fh0);
i = 0;
for (;fv_cwit != fv_cwend; ++fv_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], fv_cwit->idx()) << "Index wrong in FaceVertexCWIter";
}
EXPECT_FALSE(fv_cwit.is_valid()) << "Iterator invalid in FaceVertexCWIter at end";
EXPECT_TRUE( fv_cwit == fv_cwend ) << "End iterator for FaceVertexCWIter not matching";
//constant CW
Mesh::ConstFaceVertexCWIter cfv_cwit = mesh_.cfv_cwbegin(fh0);
Mesh::ConstFaceVertexCWIter cfv_cwend = mesh_.cfv_cwend(fh0);
i = 0;
for (;cfv_cwit != cfv_cwend; ++cfv_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], cfv_cwit->idx()) << "Index wrong in ConstFaceVertexCWIter";
}
EXPECT_FALSE(cfv_cwit.is_valid()) << "Iterator invalid in ConstFaceVertexCWIter at end";
EXPECT_TRUE( cfv_cwit == cfv_cwend ) << "End iterator for ConstFaceVertexCWIter not matching";
/*
* conversion properties:
* a) cw_begin == CWIter(ccw_begin())
* b) cw_iter->idx() == CCWIter(cw_iter)->idx() for valid iterators
* c) --cw_iter == CWIter(++ccwIter) for valid iterators
* d) cw_end == CWIter(ccw_end()) => --cw_end != CWIter(++ccw_end()) *
*/
Mesh::FaceVertexCWIter fv_cwIter = mesh_.fv_cwbegin(mesh_.face_handle(1));
// a)
EXPECT_TRUE( fv_cwIter == Mesh::FaceVertexCWIter(mesh_.fv_ccwbegin(mesh_.face_handle(1))) ) << "ccw to cw conversion failed";
EXPECT_TRUE( Mesh::FaceVertexCCWIter(fv_cwIter) == mesh_.fv_ccwbegin(mesh_.face_handle(1)) ) << "cw to ccw conversion failed";
// b)
EXPECT_EQ( fv_cwIter->idx(), Mesh::FaceVertexCCWIter(fv_cwIter)->idx()) << "iterators doesnt point on the same element";
// c)
++fv_cwIter;
fv_ccwend = mesh_.fv_ccwend(mesh_.face_handle(1));
--fv_ccwend;
EXPECT_EQ(fv_cwIter->idx(),fv_ccwend->idx()) << "iteratoes are not equal after inc/dec";
// additional conversion check
fv_ccwend = Mesh::FaceVertexCCWIter(fv_cwIter);
EXPECT_EQ(fv_cwIter->idx(),fv_ccwend->idx())<< "iterators doesnt point on the same element";
// d)
fv_cwIter = Mesh::FaceVertexCWIter(mesh_.fv_ccwend(mesh_.face_handle(1)));
EXPECT_FALSE(fv_cwIter.is_valid()) << "end iterator is not invalid";
EXPECT_TRUE(Mesh::FaceVertexCCWIter(mesh_.fv_cwend(mesh_.face_handle(1))) == mesh_.fv_ccwend(mesh_.face_handle(1))) << "end iterators are not equal";
}
} }

View File

@@ -226,4 +226,144 @@ TEST_F(OpenMeshTrimeshCirculatorHalfedgeLoop, HalfedgeLoopWithoutFace) {
} }
/*
* Test CW and CCW iterators
*/
TEST_F(OpenMeshTrimeshCirculatorHalfedgeLoop, CWAndCCWCheck) {
mesh_.clear();
// Add some vertices
Mesh::VertexHandle vhandle[6];
vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
vhandle[3] = mesh_.add_vertex(Mesh::Point(3, 0, 0));
vhandle[4] = mesh_.add_vertex(Mesh::Point(4, 1, 0));
vhandle[5] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
// Add three faces
std::vector<Mesh::VertexHandle> face_vhandles;
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[2]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[3]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[5]);
face_vhandles.push_back(vhandle[3]);
mesh_.add_face(face_vhandles);
/* Test setup:
*
* 0 ------ 2 ------ 4
* \ / \ /
* \ 0 / \ 2 /
* \ / 1 \ /
* 1 ------- 3
* \ /
* \ 3 /
* \ /
* \ /
* 5
*/
int indices[4] = {3, 8, 6, 3};
int rev_indices[4];
std::reverse_copy(indices,indices+4,rev_indices);
//CCW
Mesh::HalfedgeLoopCCWIter hl_ccwit = mesh_.hl_ccwbegin(mesh_.halfedge_handle(3));
Mesh::HalfedgeLoopCCWIter hl_ccwend = mesh_.hl_ccwend(mesh_.halfedge_handle(3));
size_t i = 0;
for (;hl_ccwit != hl_ccwend; ++hl_ccwit, ++i)
{
EXPECT_EQ(indices[i], hl_ccwit->idx()) << "Index wrong in HalfedgeLoopCCWIter";
}
EXPECT_FALSE(hl_ccwit.is_valid()) << "Iterator invalid in HalfedgeLoopCCWIter at end";
EXPECT_TRUE( hl_ccwit == hl_ccwend ) << "End iterator for HalfedgeLoopCCWIter not matching";
//constant CCW
Mesh::ConstHalfedgeLoopCCWIter chl_ccwit = mesh_.chl_ccwbegin(mesh_.halfedge_handle(3));
Mesh::ConstHalfedgeLoopCCWIter chl_ccwend = mesh_.chl_ccwend(mesh_.halfedge_handle(3));
i = 0;
for (;chl_ccwit != chl_ccwend; ++chl_ccwit, ++i)
{
EXPECT_EQ(indices[i], chl_ccwit->idx()) << "Index wrong in ConstHalfedgeLoopCCWIter";
}
EXPECT_FALSE(chl_ccwit.is_valid()) << "Iterator invalid in ConstHalfedgeLoopCCWIter at end";
EXPECT_TRUE( chl_ccwit == chl_ccwend ) << "End iterator for ConstHalfedgeLoopCCWIter not matching";
//CW
Mesh::HalfedgeLoopCWIter hl_cwit = mesh_.hl_cwbegin(mesh_.halfedge_handle(3));
Mesh::HalfedgeLoopCWIter hl_cwend = mesh_.hl_cwend(mesh_.halfedge_handle(3));
i = 0;
for (;hl_cwit != hl_cwend; ++hl_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], hl_cwit->idx()) << "Index wrong in HalfedgeLoopCWIter";
}
EXPECT_FALSE(hl_cwit.is_valid()) << "Iterator invalid in HalfedgeLoopCWIter at end";
EXPECT_TRUE( hl_cwit == hl_cwend ) << "End iterator for HalfedgeLoopCWIter not matching";
//constant CW
Mesh::ConstHalfedgeLoopCWIter chl_cwit = mesh_.chl_cwbegin(mesh_.halfedge_handle(3));
Mesh::ConstHalfedgeLoopCWIter chl_cwend = mesh_.chl_cwend(mesh_.halfedge_handle(3));
i = 0;
for (;chl_cwit != chl_cwend; ++chl_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], chl_cwit->idx()) << "Index wrong in ConstHalfedgeLoopCWIter";
}
EXPECT_FALSE(chl_cwit.is_valid()) << "Iterator invalid in ConstHalfedgeLoopCWIter at end";
EXPECT_TRUE( chl_cwit == chl_cwend ) << "End iterator for ConstHalfedgeLoopCWIter not matching";
/*
* conversion properties:
* a) cw_begin == CWIter(ccw_begin())
* b) cw_iter->idx() == CCWIter(cw_iter)->idx() for valid iterators
* c) --cw_iter == CWIter(++ccwIter) for valid iterators
* d) cw_end == CWIter(ccw_end()) => --cw_end != CWIter(++ccw_end()) *
*/
Mesh::HalfedgeLoopCWIter hl_cwIter = mesh_.hl_cwbegin(mesh_.halfedge_handle(3));
// a)
EXPECT_TRUE( hl_cwIter == Mesh::HalfedgeLoopCWIter(mesh_.hl_ccwbegin(mesh_.halfedge_handle(3))) ) << "ccw to cw conversion failed";
EXPECT_TRUE( Mesh::HalfedgeLoopCCWIter(hl_cwIter) == mesh_.hl_ccwbegin(mesh_.halfedge_handle(3)) ) << "cw to ccw conversion failed";
// b)
EXPECT_EQ( hl_cwIter->idx(), Mesh::HalfedgeLoopCCWIter(hl_cwIter)->idx()) << "iterators doesnt point on the same element";
// c)
++hl_cwIter;
hl_ccwend = mesh_.hl_ccwend(mesh_.halfedge_handle(3));
--hl_ccwend;
EXPECT_EQ(hl_cwIter->idx(),hl_ccwend->idx()) << "iteratoes are not equal after inc/dec";
// additional conversion check
hl_ccwend = Mesh::HalfedgeLoopCCWIter(hl_cwIter);
EXPECT_EQ(hl_cwIter->idx(),hl_ccwend->idx())<< "iterators doesnt point on the same element";
// d)
hl_cwIter = Mesh::HalfedgeLoopCWIter(mesh_.hl_ccwend(mesh_.halfedge_handle(3)));
EXPECT_FALSE(hl_cwIter.is_valid()) << "end iterator is not invalid";
EXPECT_TRUE(Mesh::HalfedgeLoopCCWIter(mesh_.hl_cwend(mesh_.halfedge_handle(3))) == mesh_.hl_ccwend(mesh_.halfedge_handle(3))) << "end iterators are not equal";
}
} }

View File

@@ -280,4 +280,138 @@ TEST_F(OpenMeshTrimeshCirculatorVertexEdge, VertexEdgeIterCheckInvalidationAtEnd
} }
/*
* Test CW and CCW iterators
*/
TEST_F(OpenMeshTrimeshCirculatorVertexEdge, CWAndCCWCheck) {
mesh_.clear();
// Add some vertices
Mesh::VertexHandle vhandle[5];
vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
vhandle[3] = mesh_.add_vertex(Mesh::Point(0,-1, 0));
vhandle[4] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
// Add two faces
std::vector<Mesh::VertexHandle> face_vhandles;
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[2]);
Mesh::FaceHandle fh0 = mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[1]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
/* Test setup:
0 ==== 2
|\ 0 /|
| \ / |
|2 1 3|
| / \ |
|/ 1 \|
3 ==== 4 */
int indices[5] = {5, 1, 0, 3, 5};
int rev_indices[5];
std::reverse_copy(indices,indices+5,rev_indices);
//CCW
Mesh::VertexEdgeCCWIter ve_ccwit = mesh_.ve_ccwbegin(vhandle[1]);
Mesh::VertexEdgeCCWIter ve_ccwend = mesh_.ve_ccwend(vhandle[1]);
size_t i = 0;
for (;ve_ccwit != ve_ccwend; ++ve_ccwit, ++i)
{
EXPECT_EQ(indices[i], ve_ccwit->idx()) << "Index wrong in VertexEdgeCCWIter";
}
EXPECT_FALSE(ve_ccwit.is_valid()) << "Iterator invalid in VertexEdgeCCWIter at end";
EXPECT_TRUE( ve_ccwit == ve_ccwend ) << "End iterator for VertexEdgeCCWIter not matching";
//constant CCW
Mesh::ConstVertexEdgeCCWIter cve_ccwit = mesh_.cve_ccwbegin(vhandle[1]);
Mesh::ConstVertexEdgeCCWIter cve_ccwend = mesh_.cve_ccwend(vhandle[1]);
i = 0;
for (;cve_ccwit != cve_ccwend; ++cve_ccwit, ++i)
{
EXPECT_EQ(indices[i], cve_ccwit->idx()) << "Index wrong in ConstVertexEdgeCCWIter";
}
EXPECT_FALSE(cve_ccwit.is_valid()) << "Iterator invalid in ConstVertexEdgeCCWIter at end";
EXPECT_TRUE( cve_ccwit == cve_ccwend ) << "End iterator for ConstVertexEdgeCCWIter not matching";
//CW
Mesh::VertexEdgeCWIter ve_cwit = mesh_.ve_cwbegin(vhandle[1]);
Mesh::VertexEdgeCWIter ve_cwend = mesh_.ve_cwend(vhandle[1]);
i = 0;
for (;ve_cwit != ve_cwend; ++ve_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], ve_cwit->idx()) << "Index wrong in VertexEdgeCWIter";
}
EXPECT_FALSE(ve_cwit.is_valid()) << "Iterator invalid in VertexEdgeCWIter at end";
EXPECT_TRUE( ve_cwit == ve_cwend ) << "End iterator for VertexEdgeCWIter not matching";
//constant CW
Mesh::ConstVertexEdgeCWIter cve_cwit = mesh_.cve_cwbegin(vhandle[1]);
Mesh::ConstVertexEdgeCWIter cve_cwend = mesh_.cve_cwend(vhandle[1]);
i = 0;
for (;cve_cwit != cve_cwend; ++cve_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], cve_cwit->idx()) << "Index wrong in ConstVertexEdgeCWIter";
}
EXPECT_FALSE(cve_cwit.is_valid()) << "Iterator invalid in ConstVertexEdgeCWIter at end";
EXPECT_TRUE( cve_cwit == cve_cwend ) << "End iterator for ConstVertexEdgeCWIter not matching";
/*
* conversion properties:
* a) cw_begin == CWIter(ccw_begin())
* b) cw_iter->idx() == CCWIter(cw_iter)->idx() for valid iterators
* c) --cw_iter == CWIter(++ccwIter) for valid iterators
* d) cw_end == CWIter(ccw_end()) => --cw_end != CWIter(++ccw_end()) *
*/
Mesh::VertexEdgeCWIter ve_cwIter = mesh_.ve_cwbegin(vhandle[1]);
// a)
EXPECT_TRUE( ve_cwIter == Mesh::VertexEdgeCWIter(mesh_.ve_ccwbegin(vhandle[1])) ) << "ccw to cw conversion failed";
EXPECT_TRUE( Mesh::VertexEdgeCCWIter(ve_cwIter) == mesh_.ve_ccwbegin(vhandle[1]) ) << "cw to ccw conversion failed";
// b)
EXPECT_EQ( ve_cwIter->idx(), Mesh::VertexEdgeCCWIter(ve_cwIter)->idx()) << "iterators doesnt point on the same element";
// c)
++ve_cwIter;
ve_ccwend = mesh_.ve_ccwend(vhandle[1]);
--ve_ccwend;
EXPECT_EQ(ve_cwIter->idx(),ve_ccwend->idx()) << "iteratoes are not equal after inc/dec";
// additional conversion check
ve_ccwend = Mesh::VertexEdgeCCWIter(ve_cwIter);
EXPECT_EQ(ve_cwIter->idx(),ve_ccwend->idx())<< "iterators doesnt point on the same element";
// d)
ve_cwIter = Mesh::VertexEdgeCWIter(mesh_.ve_ccwend(vhandle[1]));
EXPECT_FALSE(ve_cwIter.is_valid()) << "end iterator is not invalid";
EXPECT_TRUE(Mesh::VertexEdgeCCWIter(mesh_.ve_cwend(vhandle[1])) == mesh_.ve_ccwend(vhandle[1])) << "end iterators are not equal";
}
} }

View File

@@ -451,4 +451,139 @@ TEST_F(OpenMeshTrimeshCirculatorVertexFace, VertexFaceIterWithoutHolesDecrement)
} }
/*
* Test CW and CCW iterators
*/
TEST_F(OpenMeshTrimeshCirculatorVertexFace, CWAndCCWCheck) {
mesh_.clear();
// Add some vertices
Mesh::VertexHandle vhandle[5];
vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
vhandle[3] = mesh_.add_vertex(Mesh::Point(0,-1, 0));
vhandle[4] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
// Add two faces
std::vector<Mesh::VertexHandle> face_vhandles;
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[2]);
Mesh::FaceHandle fh0 = mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[1]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
/* Test setup:
0 ==== 2
|\ 0 /|
| \ / |
|2 1 3|
| / \ |
|/ 1 \|
3 ==== 4 */
int indices[5] = {3, 0, 2, 1, 3};
int rev_indices[5];
std::reverse_copy(indices,indices+5,rev_indices);
//CCW
Mesh::VertexFaceCCWIter vf_ccwit = mesh_.vf_ccwbegin(vhandle[1]);
Mesh::VertexFaceCCWIter vf_ccwend = mesh_.vf_ccwend(vhandle[1]);
size_t i = 0;
for (;vf_ccwit != vf_ccwend; ++vf_ccwit, ++i)
{
EXPECT_EQ(indices[i], vf_ccwit->idx()) << "Index wrong in VertexFaceCCWIter";
}
EXPECT_FALSE(vf_ccwit.is_valid()) << "Iterator invalid in VertexFaceCCWIter at end";
EXPECT_TRUE( vf_ccwit == vf_ccwend ) << "End iterator for VertexFaceCCWIter not matching";
//constant CCW
Mesh::ConstVertexFaceCCWIter cvf_ccwit = mesh_.cvf_ccwbegin(vhandle[1]);
Mesh::ConstVertexFaceCCWIter cvf_ccwend = mesh_.cvf_ccwend(vhandle[1]);
i = 0;
for (;cvf_ccwit != cvf_ccwend; ++cvf_ccwit, ++i)
{
EXPECT_EQ(indices[i], cvf_ccwit->idx()) << "Index wrong in ConstVertexFaceCCWIter";
}
EXPECT_FALSE(cvf_ccwit.is_valid()) << "Iterator invalid in ConstVertexFaceCCWIter at end";
EXPECT_TRUE( cvf_ccwit == cvf_ccwend ) << "End iterator for ConstVertexFaceCCWIter not matching";
//CW
Mesh::VertexFaceCWIter vf_cwit = mesh_.vf_cwbegin(vhandle[1]);
Mesh::VertexFaceCWIter vf_cwend = mesh_.vf_cwend(vhandle[1]);
i = 0;
for (;vf_cwit != vf_cwend; ++vf_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], vf_cwit->idx()) << "Index wrong in VertexFaceCWIter";
}
EXPECT_FALSE(vf_cwit.is_valid()) << "Iterator invalid in VertexFaceCWIter at end";
EXPECT_TRUE( vf_cwit == vf_cwend ) << "End iterator for VertexFaceCWIter not matching";
//constant CW
Mesh::ConstVertexFaceCWIter cvf_cwit = mesh_.cvf_cwbegin(vhandle[1]);
Mesh::ConstVertexFaceCWIter cvf_cwend = mesh_.cvf_cwend(vhandle[1]);
i = 0;
for (;cvf_cwit != cvf_cwend; ++cvf_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], cvf_cwit->idx()) << "Index wrong in ConstVertexFaceCWIter";
}
EXPECT_FALSE(cvf_cwit.is_valid()) << "Iterator invalid in ConstVertexFaceCWIter at end";
EXPECT_TRUE( cvf_cwit == cvf_cwend ) << "End iterator for ConstVertexFaceCWIter not matching";
/*
* conversion properties:
* a) cw_begin == CWIter(ccw_begin())
* b) cw_iter->idx() == CCWIter(cw_iter)->idx() for valid iterators
* c) --cw_iter == CWIter(++ccwIter) for valid iterators
* d) cw_end == CWIter(ccw_end()) => --cw_end != CWIter(++ccw_end()) *
*/
Mesh::VertexFaceCWIter vf_cwIter = mesh_.vf_cwbegin(vhandle[1]);
// a)
EXPECT_TRUE( vf_cwIter == Mesh::VertexFaceCWIter(mesh_.vf_ccwbegin(vhandle[1])) ) << "ccw to cw conversion failed";
EXPECT_TRUE( Mesh::VertexFaceCCWIter(vf_cwIter) == mesh_.vf_ccwbegin(vhandle[1]) ) << "cw to ccw conversion failed";
// b)
EXPECT_EQ( vf_cwIter->idx(), Mesh::VertexFaceCCWIter(vf_cwIter)->idx()) << "iterators doesnt point on the same element";
// c)
++vf_cwIter;
vf_ccwend = mesh_.vf_ccwend(vhandle[1]);
--vf_ccwend;
EXPECT_EQ(vf_cwIter->idx(),vf_ccwend->idx()) << "iteratoes are not equal after inc/dec";
// additional conversion check
vf_ccwend = Mesh::VertexFaceCCWIter(vf_cwIter);
EXPECT_EQ(vf_cwIter->idx(),vf_ccwend->idx())<< "iterators doesnt point on the same element";
// d)
vf_cwIter = Mesh::VertexFaceCWIter(mesh_.vf_ccwend(vhandle[1]));
EXPECT_FALSE(vf_cwIter.is_valid()) << "end iterator is not invalid";
EXPECT_TRUE(Mesh::VertexFaceCCWIter(mesh_.vf_cwend(vhandle[1])) == mesh_.vf_ccwend(vhandle[1])) << "end iterators are not equal";
}
} }

View File

@@ -394,5 +394,139 @@ TEST_F(OpenMeshTrimeshCirculatorVertexIHalfEdge, VertexIHalfEdgeIterCheckInvalid
} }
/*
* Test CW and CCW iterators
*/
TEST_F(OpenMeshTrimeshCirculatorVertexIHalfEdge, CWAndCCWCheck) {
mesh_.clear();
// Add some vertices
Mesh::VertexHandle vhandle[5];
vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
vhandle[3] = mesh_.add_vertex(Mesh::Point(0,-1, 0));
vhandle[4] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
// Add two faces
std::vector<Mesh::VertexHandle> face_vhandles;
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[2]);
Mesh::FaceHandle fh0 = mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[1]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
/* Test setup:
0 ==== 2
|\ 0 /|
| \ / |
|2 1 3|
| / \ |
|/ 1 \|
3 ==== 4 */
int indices[4] = {14, 5, 2, 14};
int rev_indices[4];
std::reverse_copy(indices,indices+4,rev_indices);
//CCW
Mesh::VertexIHalfedgeCCWIter vih_ccwit = mesh_.vih_ccwbegin(vhandle[2]);
Mesh::VertexIHalfedgeCCWIter vih_ccwend = mesh_.vih_ccwend(vhandle[2]);
size_t i = 0;
for (;vih_ccwit != vih_ccwend; ++vih_ccwit, ++i)
{
EXPECT_EQ(indices[i], vih_ccwit->idx()) << "Index wrong in VertexIHalfedgeCCWIter";
}
EXPECT_FALSE(vih_ccwit.is_valid()) << "Iterator invalid in VertexIHalfedgeCCWIter at end";
EXPECT_TRUE( vih_ccwit == vih_ccwend ) << "End iterator for VertexIHalfedgeCCWIter not matching";
//constant CCW
Mesh::ConstVertexIHalfedgeCCWIter cvih_ccwit = mesh_.cvih_ccwbegin(vhandle[2]);
Mesh::ConstVertexIHalfedgeCCWIter cvih_ccwend = mesh_.cvih_ccwend(vhandle[2]);
i = 0;
for (;cvih_ccwit != cvih_ccwend; ++cvih_ccwit, ++i)
{
EXPECT_EQ(indices[i], cvih_ccwit->idx()) << "Index wrong in ConstVertexIHalfedgeCCWIter";
}
EXPECT_FALSE(cvih_ccwit.is_valid()) << "Iterator invalid in ConstVertexIHalfedgeCCWIter at end";
EXPECT_TRUE( cvih_ccwit == cvih_ccwend ) << "End iterator for ConstVertexIHalfedgeCCWIter not matching";
//CW
Mesh::VertexIHalfedgeCWIter vih_cwit = mesh_.vih_cwbegin(vhandle[2]);
Mesh::VertexIHalfedgeCWIter vih_cwend = mesh_.vih_cwend(vhandle[2]);
i = 0;
for (;vih_cwit != vih_cwend; ++vih_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], vih_cwit->idx()) << "Index wrong in VertexIHalfedgeCWIter";
}
EXPECT_FALSE(vih_cwit.is_valid()) << "Iterator invalid in VertexIHalfedgeCWIter at end";
EXPECT_TRUE( vih_cwit == vih_cwend ) << "End iterator for VertexIHalfedgeCWIter not matching";
//constant CW
Mesh::ConstVertexIHalfedgeCWIter cvih_cwit = mesh_.cvih_cwbegin(vhandle[2]);
Mesh::ConstVertexIHalfedgeCWIter cvih_cwend = mesh_.cvih_cwend(vhandle[2]);
i = 0;
for (;cvih_cwit != cvih_cwend; ++cvih_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], cvih_cwit->idx()) << "Index wrong in ConstVertexIHalfedgeCWIter";
}
EXPECT_FALSE(cvih_cwit.is_valid()) << "Iterator invalid in ConstVertexIHalfedgeCWIter at end";
EXPECT_TRUE( cvih_cwit == cvih_cwend ) << "End iterator for ConstVertexIHalfedgeCWIter not matching";
/*
* conversion properties:
* a) cw_begin == CWIter(ccw_begin())
* b) cw_iter->idx() == CCWIter(cw_iter)->idx() for valid iterators
* c) --cw_iter == CWIter(++ccwIter) for valid iterators
* d) cw_end == CWIter(ccw_end()) => --cw_end != CWIter(++ccw_end()) *
*/
Mesh::VertexIHalfedgeCWIter vih_cwIter = mesh_.vih_cwbegin(vhandle[2]);
// a)
EXPECT_TRUE( vih_cwIter == Mesh::VertexIHalfedgeCWIter(mesh_.vih_ccwbegin(vhandle[2])) ) << "ccw to cw conversion failed";
EXPECT_TRUE( Mesh::VertexIHalfedgeCCWIter(vih_cwIter) == mesh_.vih_ccwbegin(vhandle[2]) ) << "cw to ccw conversion failed";
// b)
EXPECT_EQ( vih_cwIter->idx(), Mesh::VertexIHalfedgeCCWIter(vih_cwIter)->idx()) << "iterators doesnt point on the same element";
// c)
++vih_cwIter;
vih_ccwend = mesh_.vih_ccwend(vhandle[2]);
--vih_ccwend;
EXPECT_EQ(vih_cwIter->idx(),vih_ccwend->idx()) << "iteratoes are not equal after inc/dec";
// additional conversion check
vih_ccwend = Mesh::VertexIHalfedgeCCWIter(vih_cwIter);
EXPECT_EQ(vih_cwIter->idx(),vih_ccwend->idx())<< "iterators doesnt point on the same element";
// d)
vih_cwIter = Mesh::VertexIHalfedgeCWIter(mesh_.vih_ccwend(vhandle[2]));
EXPECT_FALSE(vih_cwIter.is_valid()) << "end iterator is not invalid";
EXPECT_TRUE(Mesh::VertexIHalfedgeCCWIter(mesh_.vih_cwend(vhandle[2])) == mesh_.vih_ccwend(vhandle[2])) << "end iterators are not equal";
}
} }

View File

@@ -394,6 +394,141 @@ TEST_F(OpenMeshTrimeshCirculatorVertexOHalfEdge, VertexOHalfEdgeIterCheckInvalid
} }
/*
* Test CW and CCW iterators
*/
TEST_F(OpenMeshTrimeshCirculatorVertexOHalfEdge, CWAndCCWCheck) {
mesh_.clear();
// Add some vertices
Mesh::VertexHandle vhandle[5];
vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
vhandle[3] = mesh_.add_vertex(Mesh::Point(0,-1, 0));
vhandle[4] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
// Add two faces
std::vector<Mesh::VertexHandle> face_vhandles;
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[2]);
Mesh::FaceHandle fh0 = mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[1]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
/* Test setup:
0 ==== 2
|\ 0 /|
| \ / |
|2 1 3|
| / \ |
|/ 1 \|
3 ==== 4 */
int indices[5] = {11, 2, 1, 6, 11};
int rev_indices[5];
std::reverse_copy(indices,indices+5,rev_indices);
//CCW
Mesh::VertexOHalfedgeCCWIter voh_ccwit = mesh_.voh_ccwbegin(vhandle[1]);
Mesh::VertexOHalfedgeCCWIter voh_ccwend = mesh_.voh_ccwend(vhandle[1]);
size_t i = 0;
for (;voh_ccwit != voh_ccwend; ++voh_ccwit, ++i)
{
EXPECT_EQ(indices[i], voh_ccwit->idx()) << "Index wrong in VertexOHalfedgeCCWIter";
}
EXPECT_FALSE(voh_ccwit.is_valid()) << "Iterator invalid in VertexOHalfedgeCCWIter at end";
EXPECT_TRUE( voh_ccwit == voh_ccwend ) << "End iterator for VertexOHalfedgeCCWIter not matching";
//constant CCW
Mesh::ConstVertexOHalfedgeCCWIter cvoh_ccwit = mesh_.cvoh_ccwbegin(vhandle[1]);
Mesh::ConstVertexOHalfedgeCCWIter cvoh_ccwend = mesh_.cvoh_ccwend(vhandle[1]);
i = 0;
for (;cvoh_ccwit != cvoh_ccwend; ++cvoh_ccwit, ++i)
{
EXPECT_EQ(indices[i], cvoh_ccwit->idx()) << "Index wrong in ConstVertexOHalfedgeCCWIter";
}
EXPECT_FALSE(cvoh_ccwit.is_valid()) << "Iterator invalid in ConstVertexOHalfedgeCCWIter at end";
EXPECT_TRUE( cvoh_ccwit == cvoh_ccwend ) << "End iterator for ConstVertexOHalfedgeCCWIter not matching";
//CW
Mesh::VertexOHalfedgeCWIter voh_cwit = mesh_.voh_cwbegin(vhandle[1]);
Mesh::VertexOHalfedgeCWIter voh_cwend = mesh_.voh_cwend(vhandle[1]);
i = 0;
for (;voh_cwit != voh_cwend; ++voh_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], voh_cwit->idx()) << "Index wrong in VertexOHalfedgeCWIter";
}
EXPECT_FALSE(voh_cwit.is_valid()) << "Iterator invalid in VertexOHalfedgeCWIter at end";
EXPECT_TRUE( voh_cwit == voh_cwend ) << "End iterator for VertexOHalfedgeCWIter not matching";
//constant CW
Mesh::ConstVertexOHalfedgeCWIter cvoh_cwit = mesh_.cvoh_cwbegin(vhandle[1]);
Mesh::ConstVertexOHalfedgeCWIter cvoh_cwend = mesh_.cvoh_cwend(vhandle[1]);
i = 0;
for (;cvoh_cwit != cvoh_cwend; ++cvoh_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], cvoh_cwit->idx()) << "Index wrong in ConstVertexOHalfedgeCWIter";
}
EXPECT_FALSE(cvoh_cwit.is_valid()) << "Iterator invalid in ConstVertexOHalfedgeCWIter at end";
EXPECT_TRUE( cvoh_cwit == cvoh_cwend ) << "End iterator for ConstVertexOHalfedgeCWIter not matching";
/*
* conversion properties:
* a) cw_begin == CWIter(ccw_begin())
* b) cw_iter->idx() == CCWIter(cw_iter)->idx() for valid iterators
* c) --cw_iter == CWIter(++ccwIter) for valid iterators
* d) cw_end == CWIter(ccw_end()) => --cw_end != CWIter(++ccw_end()) *
*/
Mesh::VertexOHalfedgeCWIter voh_cwIter = mesh_.voh_cwbegin(vhandle[1]);
// a)
EXPECT_TRUE( voh_cwIter == Mesh::VertexOHalfedgeCWIter(mesh_.voh_ccwbegin(vhandle[1])) ) << "ccw to cw conversion failed";
EXPECT_TRUE( Mesh::VertexOHalfedgeCCWIter(voh_cwIter) == mesh_.voh_ccwbegin(vhandle[1]) ) << "cw to ccw conversion failed";
// b)
EXPECT_EQ( voh_cwIter->idx(), Mesh::VertexOHalfedgeCCWIter(voh_cwIter)->idx()) << "iterators doesnt point on the same element";
// c)
++voh_cwIter;
voh_ccwend = mesh_.voh_ccwend(vhandle[1]);
--voh_ccwend;
EXPECT_EQ(voh_cwIter->idx(),voh_ccwend->idx()) << "iteratoes are not equal after inc/dec";
// additional conversion check
voh_ccwend = Mesh::VertexOHalfedgeCCWIter(voh_cwIter);
EXPECT_EQ(voh_cwIter->idx(),voh_ccwend->idx())<< "iterators doesnt point on the same element";
// d)
voh_cwIter = Mesh::VertexOHalfedgeCWIter(mesh_.voh_ccwend(vhandle[1]));
EXPECT_FALSE(voh_cwIter.is_valid()) << "end iterator is not invalid";
EXPECT_TRUE(Mesh::VertexOHalfedgeCCWIter(mesh_.voh_cwend(vhandle[1])) == mesh_.voh_ccwend(vhandle[1])) << "end iterators are not equal";
}
} }

View File

@@ -283,6 +283,140 @@ TEST_F(OpenMeshTrimeshCirculatorVertexVertex, VertexVertexIterCheckInvalidationA
} }
/*
* Test CW and CCW iterators
*/
TEST_F(OpenMeshTrimeshCirculatorVertexVertex, CWAndCCWCheck) {
mesh_.clear();
// Add some vertices
Mesh::VertexHandle vhandle[5];
vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
vhandle[3] = mesh_.add_vertex(Mesh::Point(0,-1, 0));
vhandle[4] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
// Add two faces
std::vector<Mesh::VertexHandle> face_vhandles;
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[2]);
Mesh::FaceHandle fh0 = mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[1]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
/* Test setup:
0 ==== 2
|\ 0 /|
| \ / |
|2 1 3|
| / \ |
|/ 1 \|
3 ==== 4 */
int indices[5] = {4, 2, 0, 3, 4};
int rev_indices[5];
std::reverse_copy(indices,indices+5,rev_indices);
//CCW
Mesh::VertexVertexCCWIter vv_ccwit = mesh_.vv_ccwbegin(vhandle[1]);
Mesh::VertexVertexCCWIter vv_ccwend = mesh_.vv_ccwend(vhandle[1]);
size_t i = 0;
for (;vv_ccwit != vv_ccwend; ++vv_ccwit, ++i)
{
EXPECT_EQ(indices[i], vv_ccwit->idx()) << "Index wrong in VertexVertexCCWIter";
}
EXPECT_FALSE(vv_ccwit.is_valid()) << "Iterator invalid in VertexVertexCCWIter at end";
EXPECT_TRUE( vv_ccwit == vv_ccwend ) << "End iterator for VertexVertexCCWIter not matching";
//constant CCW
Mesh::ConstVertexVertexCCWIter cvv_ccwit = mesh_.cvv_ccwbegin(vhandle[1]);
Mesh::ConstVertexVertexCCWIter cvv_ccwend = mesh_.cvv_ccwend(vhandle[1]);
i = 0;
for (;cvv_ccwit != cvv_ccwend; ++cvv_ccwit, ++i)
{
EXPECT_EQ(indices[i], cvv_ccwit->idx()) << "Index wrong in ConstVertexVertexCCWIter";
}
EXPECT_FALSE(cvv_ccwit.is_valid()) << "Iterator invalid in ConstVertexVertexCCWIter at end";
EXPECT_TRUE( cvv_ccwit == cvv_ccwend ) << "End iterator for ConstVertexVertexCCWIter not matching";
//CW
Mesh::VertexVertexCWIter vv_cwit = mesh_.vv_cwbegin(vhandle[1]);
Mesh::VertexVertexCWIter vv_cwend = mesh_.vv_cwend(vhandle[1]);
i = 0;
for (;vv_cwit != vv_cwend; ++vv_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], vv_cwit->idx()) << "Index wrong in VertexVertexCWIter";
}
EXPECT_FALSE(vv_cwit.is_valid()) << "Iterator invalid in VertexVertexCWIter at end";
EXPECT_TRUE( vv_cwit == vv_cwend ) << "End iterator for VertexVertexCWIter not matching";
//constant CW
Mesh::ConstVertexVertexCWIter cvv_cwit = mesh_.cvv_cwbegin(vhandle[1]);
Mesh::ConstVertexVertexCWIter cvv_cwend = mesh_.cvv_cwend(vhandle[1]);
i = 0;
for (;cvv_cwit != cvv_cwend; ++cvv_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], cvv_cwit->idx()) << "Index wrong in ConstVertexVertexCWIter";
}
EXPECT_FALSE(cvv_cwit.is_valid()) << "Iterator invalid in ConstVertexVertexCWIter at end";
EXPECT_TRUE( cvv_cwit == cvv_cwend ) << "End iterator for ConstVertexVertexCWIter not matching";
/*
* conversion properties:
* a) cw_begin == CWIter(ccw_begin())
* b) cw_iter->idx() == CCWIter(cw_iter)->idx() for valid iterators
* c) --cw_iter == CWIter(++ccwIter) for valid iterators
* d) cw_end == CWIter(ccw_end()) => --cw_end != CWIter(++ccw_end()) *
*/
Mesh::VertexVertexCWIter vv_cwIter = mesh_.vv_cwbegin(vhandle[1]);
// a)
EXPECT_TRUE( vv_cwIter == Mesh::VertexVertexCWIter(mesh_.vv_ccwbegin(vhandle[1])) ) << "ccw to cw convvrsion failed";
EXPECT_TRUE( Mesh::VertexVertexCCWIter(vv_cwIter) == mesh_.vv_ccwbegin(vhandle[1]) ) << "cw to ccw convvrsion failed";
// b)
EXPECT_EQ( vv_cwIter->idx(), Mesh::VertexVertexCCWIter(vv_cwIter)->idx()) << "iterators doesnt point on the same element";
// c)
++vv_cwIter;
vv_ccwend = mesh_.vv_ccwend(vhandle[1]);
--vv_ccwend;
EXPECT_EQ(vv_cwIter->idx(),vv_ccwend->idx()) << "iteratoes are not equal after inc/dec";
// additional conversion check
vv_ccwend = Mesh::VertexVertexCCWIter(vv_cwIter);
EXPECT_EQ(vv_cwIter->idx(),vv_ccwend->idx())<< "iterators doesnt point on the same element";
// d)
vv_cwIter = Mesh::VertexVertexCWIter(mesh_.vv_ccwend(vhandle[1]));
EXPECT_FALSE(vv_cwIter.is_valid()) << "end iterator is not invalid";
EXPECT_TRUE(Mesh::VertexVertexCCWIter(mesh_.vv_cwend(vhandle[1])) == mesh_.vv_ccwend(vhandle[1])) << "end iterators are not equal";
}
} }