Merge branch 'master' into CustomProperties

This commit is contained in:
Max Lyon
2021-03-15 09:53:00 +01:00
17 changed files with 990 additions and 294 deletions

View File

@@ -60,6 +60,9 @@
//== NAMESPACES ===============================================================
namespace OpenMesh {
template <typename> class CirculatorRange;
namespace Iterators {
template<class Mesh, class CenterEntityHandle, bool CW>
@@ -153,7 +156,21 @@ class GenericCirculator_ValueHandleFnsT {
inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const int lap_counter) {
return ( heh.is_valid() && (lap_counter == 0 ) );
}
inline static void init(const Mesh*, typename Mesh::HalfedgeHandle&, typename Mesh::HalfedgeHandle&, int&) {};
inline static void init(const Mesh* mesh, typename Mesh::HalfedgeHandle& heh, typename Mesh::HalfedgeHandle& start, int& lap_counter, bool adjust_for_ccw)
{
if (!CW) // TODO: constexpr if
{
if (adjust_for_ccw)
{
// increment current heh and start so that cw and ccw version dont start with the same element but ranges are actually reversed
int lc = lap_counter;
increment(mesh, heh, start, lap_counter);
start = heh;
lap_counter = lc;
}
}
}
inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
GenericCirculator_CenterEntityFnsT<Mesh, CenterEntityHandle, CW>::increment(mesh, heh, start, lap_counter);
}
@@ -170,7 +187,19 @@ class GenericCirculator_ValueHandleFnsT<Mesh, CenterEntityHandle, typename Mesh:
inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const int lap_counter) {
return ( heh.is_valid() && (lap_counter == 0));
}
inline static void init(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) {
inline static void init(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter, bool adjust_for_ccw)
{
if (!CW) // TODO: constexpr if
{
if (adjust_for_ccw)
{
// increment current heh and start so that cw and ccw version dont start with the same element but ranges are actually reversed
int lc = lap_counter;
increment(mesh, heh, start, lap_counter);
start = heh;
lap_counter = lc;
}
}
if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 )
increment(mesh, heh, start, lap_counter);
};
@@ -192,6 +221,8 @@ class GenericCirculatorBaseT {
typedef const Mesh* mesh_ptr;
typedef const Mesh& mesh_ref;
template <typename> friend class OpenMesh::CirculatorRange;
public:
GenericCirculatorBaseT() : mesh_(0), lap_counter_(0) {}
@@ -267,17 +298,21 @@ class GenericCirculatorT : protected GenericCirculatorBaseT<typename GenericCirc
typedef typename GenericCirculatorBaseT<Mesh>::mesh_ref mesh_ref;
typedef GenericCirculator_ValueHandleFnsT<Mesh, CenterEntityHandle, value_type, CW> GenericCirculator_ValueHandleFns;
template <typename> friend class OpenMesh::CirculatorRange;
public:
GenericCirculatorT() {}
GenericCirculatorT(mesh_ref mesh, CenterEntityHandle start, bool end = false) :
GenericCirculatorBaseT<Mesh>(mesh, mesh.halfedge_handle(start), end) {
GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
GenericCirculatorBaseT<Mesh>(mesh, mesh.halfedge_handle(start), end)
{
bool adjust_for_ccw = true;
GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_, adjust_for_ccw);
}
GenericCirculatorT(mesh_ref mesh, typename Mesh::HalfedgeHandle heh, bool end = false) :
GenericCirculatorBaseT<Mesh>(mesh, heh, end) {
GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
GenericCirculatorBaseT<Mesh>(mesh, heh, end)
{
bool adjust_for_ccw = false; // if iterator is initialized with specific heh, we want to start there
GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_, adjust_for_ccw);
}
GenericCirculatorT(const GenericCirculatorT &rhs) : GenericCirculatorBaseT<Mesh>(rhs) {}
@@ -440,6 +475,8 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<typename
typedef typename GenericCirculatorBaseT<Mesh>::mesh_ref mesh_ref;
typedef GenericCirculator_ValueHandleFnsT_DEPRECATED<Mesh, CenterEntityHandle, value_type> GenericCirculator_ValueHandleFns;
template <typename> friend class OpenMesh::CirculatorRange;
public:
GenericCirculatorT_DEPRECATED() {}
GenericCirculatorT_DEPRECATED(mesh_ref mesh, CenterEntityHandle start, bool end = false) :

View File

@@ -98,8 +98,10 @@ struct CirculatorRangeTraitT
using ITER_TYPE = ITER_T;
using CENTER_ENTITY_TYPE = CENTER_ENTITY_T;
using TO_ENTITYE_TYPE = TO_ENTITY_T;
static ITER_TYPE begin(const CONTAINER_TYPE& _container, CENTER_ENTITY_TYPE _ce) { return (_container.*begin_fn)(_ce); }
static ITER_TYPE end(const CONTAINER_TYPE& _container, CENTER_ENTITY_TYPE _ce) { return (_container.*end_fn)(_ce); }
static ITER_TYPE begin(const CONTAINER_TYPE& _container, CENTER_ENTITY_TYPE _ce) { return (_container.*begin_fn)(_ce); }
static ITER_TYPE begin(const CONTAINER_TYPE& _container, HalfedgeHandle _heh, int) { return ITER_TYPE(_container, _heh); }
static ITER_TYPE end(const CONTAINER_TYPE& _container, CENTER_ENTITY_TYPE _ce) { return (_container.*end_fn)(_ce); }
static ITER_TYPE end(const CONTAINER_TYPE& _container, HalfedgeHandle _heh, int) { return ITER_TYPE(_container, _heh, true); }
};
struct SmartVertexHandle;
@@ -1167,76 +1169,38 @@ public:
typename ElementRange<HandleType>::Range all_elements() const;
typedef CirculatorRange<CirculatorRangeTraitT<
PolyConnectivity,
ConstVertexVertexCWIter,
VertexHandle,
VertexHandle,
&PolyConnectivity::cvv_cwbegin,
&PolyConnectivity::cvv_cwend>> ConstVertexVertexRange;
typedef CirculatorRange<CirculatorRangeTraitT<
PolyConnectivity,
ConstVertexIHalfedgeIter,
VertexHandle,
HalfedgeHandle,
&PolyConnectivity::cvih_begin,
&PolyConnectivity::cvih_end>> ConstVertexIHalfedgeRange;
typedef CirculatorRange<CirculatorRangeTraitT<
PolyConnectivity,
ConstVertexOHalfedgeIter,
VertexHandle,
HalfedgeHandle,
&PolyConnectivity::cvoh_begin,
&PolyConnectivity::cvoh_end>> ConstVertexOHalfedgeRange;
typedef CirculatorRange<CirculatorRangeTraitT<
PolyConnectivity,
ConstVertexEdgeIter,
VertexHandle,
EdgeHandle,
&PolyConnectivity::cve_begin,
&PolyConnectivity::cve_end>> ConstVertexEdgeRange;
typedef CirculatorRange<CirculatorRangeTraitT<
PolyConnectivity,
ConstVertexFaceIter,
VertexHandle,
FaceHandle,
&PolyConnectivity::cvf_begin,
&PolyConnectivity::cvf_end>> ConstVertexFaceRange;
typedef CirculatorRange<CirculatorRangeTraitT<
PolyConnectivity,
ConstFaceVertexIter,
FaceHandle,
VertexHandle,
&PolyConnectivity::cfv_begin,
&PolyConnectivity::cfv_end>> ConstFaceVertexRange;
typedef CirculatorRange<CirculatorRangeTraitT<
PolyConnectivity,
ConstFaceHalfedgeIter,
FaceHandle,
HalfedgeHandle,
&PolyConnectivity::cfh_begin,
&PolyConnectivity::cfh_end>> ConstFaceHalfedgeRange;
typedef CirculatorRange<CirculatorRangeTraitT<
PolyConnectivity,
ConstFaceEdgeIter,
FaceHandle,
EdgeHandle,
&PolyConnectivity::cfe_begin,
&PolyConnectivity::cfe_end>> ConstFaceEdgeRange;
typedef CirculatorRange<CirculatorRangeTraitT<
PolyConnectivity,
ConstFaceFaceIter,
FaceHandle,
FaceHandle,
&PolyConnectivity::cff_begin,
&PolyConnectivity::cff_end>> ConstFaceFaceRange;
typedef CirculatorRange<CirculatorRangeTraitT<
PolyConnectivity,
ConstHalfedgeLoopIter,
HalfedgeHandle,
HalfedgeHandle,
&PolyConnectivity::chl_begin,
&PolyConnectivity::chl_end>> ConstHalfedgeLoopRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstVertexVertexIter , VertexHandle , VertexHandle , &PolyConnectivity::cvv_begin , &PolyConnectivity::cvv_end >> ConstVertexVertexRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstVertexIHalfedgeIter , VertexHandle , HalfedgeHandle, &PolyConnectivity::cvih_begin , &PolyConnectivity::cvih_end >> ConstVertexIHalfedgeRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstVertexOHalfedgeIter , VertexHandle , HalfedgeHandle, &PolyConnectivity::cvoh_begin , &PolyConnectivity::cvoh_end >> ConstVertexOHalfedgeRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstVertexEdgeIter , VertexHandle , EdgeHandle , &PolyConnectivity::cve_begin , &PolyConnectivity::cve_end >> ConstVertexEdgeRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstVertexFaceIter , VertexHandle , FaceHandle , &PolyConnectivity::cvf_begin , &PolyConnectivity::cvf_end >> ConstVertexFaceRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstFaceVertexIter , FaceHandle , VertexHandle , &PolyConnectivity::cfv_begin , &PolyConnectivity::cfv_end >> ConstFaceVertexRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstFaceHalfedgeIter , FaceHandle , HalfedgeHandle, &PolyConnectivity::cfh_begin , &PolyConnectivity::cfh_end >> ConstFaceHalfedgeRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstFaceEdgeIter , FaceHandle , EdgeHandle , &PolyConnectivity::cfe_begin , &PolyConnectivity::cfe_end >> ConstFaceEdgeRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstFaceFaceIter , FaceHandle , FaceHandle , &PolyConnectivity::cff_begin , &PolyConnectivity::cff_end >> ConstFaceFaceRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstHalfedgeLoopIter , HalfedgeHandle, HalfedgeHandle, &PolyConnectivity::chl_begin , &PolyConnectivity::chl_end >> ConstHalfedgeLoopRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstVertexVertexCWIter , VertexHandle , VertexHandle , &PolyConnectivity::cvv_cwbegin , &PolyConnectivity::cvv_cwend >> ConstVertexVertexCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstVertexIHalfedgeCWIter , VertexHandle , HalfedgeHandle, &PolyConnectivity::cvih_cwbegin , &PolyConnectivity::cvih_cwend >> ConstVertexIHalfedgeCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstVertexOHalfedgeCWIter , VertexHandle , HalfedgeHandle, &PolyConnectivity::cvoh_cwbegin , &PolyConnectivity::cvoh_cwend >> ConstVertexOHalfedgeCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstVertexEdgeCWIter , VertexHandle , EdgeHandle , &PolyConnectivity::cve_cwbegin , &PolyConnectivity::cve_cwend >> ConstVertexEdgeCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstVertexFaceCWIter , VertexHandle , FaceHandle , &PolyConnectivity::cvf_cwbegin , &PolyConnectivity::cvf_cwend >> ConstVertexFaceCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstFaceVertexCWIter , FaceHandle , VertexHandle , &PolyConnectivity::cfv_cwbegin , &PolyConnectivity::cfv_cwend >> ConstFaceVertexCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstFaceHalfedgeCWIter , FaceHandle , HalfedgeHandle, &PolyConnectivity::cfh_cwbegin , &PolyConnectivity::cfh_cwend >> ConstFaceHalfedgeCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstFaceEdgeCWIter , FaceHandle , EdgeHandle , &PolyConnectivity::cfe_cwbegin , &PolyConnectivity::cfe_cwend >> ConstFaceEdgeCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstFaceFaceCWIter , FaceHandle , FaceHandle , &PolyConnectivity::cff_cwbegin , &PolyConnectivity::cff_cwend >> ConstFaceFaceCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstHalfedgeLoopCWIter , HalfedgeHandle, HalfedgeHandle, &PolyConnectivity::chl_cwbegin , &PolyConnectivity::chl_cwend >> ConstHalfedgeLoopCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstVertexVertexCCWIter , VertexHandle , VertexHandle , &PolyConnectivity::cvv_ccwbegin , &PolyConnectivity::cvv_ccwend >> ConstVertexVertexCCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstVertexIHalfedgeCCWIter, VertexHandle , HalfedgeHandle, &PolyConnectivity::cvih_ccwbegin , &PolyConnectivity::cvih_ccwend >> ConstVertexIHalfedgeCCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstVertexOHalfedgeCCWIter, VertexHandle , HalfedgeHandle, &PolyConnectivity::cvoh_ccwbegin , &PolyConnectivity::cvoh_ccwend >> ConstVertexOHalfedgeCCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstVertexEdgeCCWIter , VertexHandle , EdgeHandle , &PolyConnectivity::cve_ccwbegin , &PolyConnectivity::cve_ccwend >> ConstVertexEdgeCCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstVertexFaceCCWIter , VertexHandle , FaceHandle , &PolyConnectivity::cvf_ccwbegin , &PolyConnectivity::cvf_ccwend >> ConstVertexFaceCCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstFaceVertexCCWIter , FaceHandle , VertexHandle , &PolyConnectivity::cfv_ccwbegin , &PolyConnectivity::cfv_ccwend >> ConstFaceVertexCCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstFaceHalfedgeCCWIter , FaceHandle , HalfedgeHandle, &PolyConnectivity::cfh_ccwbegin , &PolyConnectivity::cfh_ccwend >> ConstFaceHalfedgeCCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstFaceEdgeCCWIter , FaceHandle , EdgeHandle , &PolyConnectivity::cfe_ccwbegin , &PolyConnectivity::cfe_ccwend >> ConstFaceEdgeCCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstFaceFaceCCWIter , FaceHandle , FaceHandle , &PolyConnectivity::cff_ccwbegin , &PolyConnectivity::cff_ccwend >> ConstFaceFaceCCWRange;
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstHalfedgeLoopCCWIter , HalfedgeHandle, HalfedgeHandle, &PolyConnectivity::chl_ccwbegin , &PolyConnectivity::chl_ccwend >> ConstHalfedgeLoopCCWRange;
/**
* @return The vertices adjacent to the specified vertex
@@ -1250,12 +1214,26 @@ public:
*/
ConstVertexIHalfedgeRange vih_range(VertexHandle _vh) const;
/**
* @return The incoming halfedges incident to the specified vertex
* as a range object suitable for C++11 range based for loops.
* Like vih_range(VertexHandle _heh.to()) but starts iteration at _heh
*/
ConstVertexIHalfedgeRange vih_range(HalfedgeHandle _heh) const;
/**
* @return The outgoing halfedges incident to the specified vertex
* as a range object suitable for C++11 range based for loops.
*/
ConstVertexOHalfedgeRange voh_range(VertexHandle _vh) const;
/**
* @return The outgoing halfedges incident to the specified vertex
* as a range object suitable for C++11 range based for loops.
* Like voh_range(VertexHandle _heh.from()) but starts iteration at _heh
*/
ConstVertexOHalfedgeRange voh_range(HalfedgeHandle _heh) const;
/**
* @return The edges incident to the specified vertex
* as a range object suitable for C++11 range based for loops.
@@ -1298,6 +1276,156 @@ public:
*/
ConstHalfedgeLoopRange hl_range(HalfedgeHandle _heh) const;
/**
* @return The vertices adjacent to the specified vertex
* as a range object suitable for C++11 range based for loops.
*/
ConstVertexVertexCWRange vv_cw_range(VertexHandle _vh) const;
/**
* @return The incoming halfedges incident to the specified vertex
* as a range object suitable for C++11 range based for loops.
*/
ConstVertexIHalfedgeCWRange vih_cw_range(VertexHandle _vh) const;
/**
* @return The incoming halfedges incident to the specified vertex
* as a range object suitable for C++11 range based for loops.
* Like vih_cw_range(VertexHandle _heh.to()) but starts iteration at _heh
*/
ConstVertexIHalfedgeCWRange vih_cw_range(HalfedgeHandle _heh) const;
/**
* @return The outgoing halfedges incident to the specified vertex
* as a range object suitable for C++11 range based for loops.
*/
ConstVertexOHalfedgeCWRange voh_cw_range(VertexHandle _vh) const;
/**
* @return The outgoing halfedges incident to the specified vertex
* as a range object suitable for C++11 range based for loops.
* Like voh_cw_range(VertexHandle _heh.from()) but starts iteration at _heh
*/
ConstVertexOHalfedgeCWRange voh_cw_range(HalfedgeHandle _heh) const;
/**
* @return The edges incident to the specified vertex
* as a range object suitable for C++11 range based for loops.
*/
ConstVertexEdgeCWRange ve_cw_range(VertexHandle _vh) const ;
/**
* @return The faces incident to the specified vertex
* as a range object suitable for C++11 range based for loops.
*/
ConstVertexFaceCWRange vf_cw_range(VertexHandle _vh) const;
/**
* @return The vertices incident to the specified face
* as a range object suitable for C++11 range based for loops.
*/
ConstFaceVertexCWRange fv_cw_range(FaceHandle _fh) const;
/**
* @return The halfedges incident to the specified face
* as a range object suitable for C++11 range based for loops.
*/
ConstFaceHalfedgeCWRange fh_cw_range(FaceHandle _fh) const;
/**
* @return The edges incident to the specified face
* as a range object suitable for C++11 range based for loops.
*/
ConstFaceEdgeCWRange fe_cw_range(FaceHandle _fh) const;
/**
* @return The faces adjacent to the specified face
* as a range object suitable for C++11 range based for loops.
*/
ConstFaceFaceCWRange ff_cw_range(FaceHandle _fh) const;
/**
* @return The halfedges in the face
* as a range object suitable for C++11 range based for loops.
*/
ConstHalfedgeLoopCWRange hl_cw_range(HalfedgeHandle _heh) const;
/**
* @return The vertices adjacent to the specified vertex
* as a range object suitable for C++11 range based for loops.
*/
ConstVertexVertexCCWRange vv_ccw_range(VertexHandle _vh) const;
/**
* @return The incoming halfedges incident to the specified vertex
* as a range object suitable for C++11 range based for loops.
*/
ConstVertexIHalfedgeCCWRange vih_ccw_range(VertexHandle _vh) const;
/**
* @return The incoming halfedges incident to the specified vertex
* as a range object suitable for C++11 range based for loops.
* Like vih_ccw_range(VertexHandle _heh.to()) but starts iteration at _heh
*/
ConstVertexIHalfedgeCCWRange vih_ccw_range(HalfedgeHandle _heh) const;
/**
* @return The outgoing halfedges incident to the specified vertex
* as a range object suitable for C++11 range based for loops.
*/
ConstVertexOHalfedgeCCWRange voh_ccw_range(VertexHandle _vh) const;
/**
* @return The outgoing halfedges incident to the specified vertex
* as a range object suitable for C++11 range based for loops.
* Like voh_ccw_range(VertexHandle _heh.from()) but starts iteration at _heh
*/
ConstVertexOHalfedgeCCWRange voh_ccw_range(HalfedgeHandle _heh) const;
/**
* @return The edges incident to the specified vertex
* as a range object suitable for C++11 range based for loops.
*/
ConstVertexEdgeCCWRange ve_ccw_range(VertexHandle _vh) const ;
/**
* @return The faces incident to the specified vertex
* as a range object suitable for C++11 range based for loops.
*/
ConstVertexFaceCCWRange vf_ccw_range(VertexHandle _vh) const;
/**
* @return The vertices incident to the specified face
* as a range object suitable for C++11 range based for loops.
*/
ConstFaceVertexCCWRange fv_ccw_range(FaceHandle _fh) const;
/**
* @return The halfedges incident to the specified face
* as a range object suitable for C++11 range based for loops.
*/
ConstFaceHalfedgeCCWRange fh_ccw_range(FaceHandle _fh) const;
/**
* @return The edges incident to the specified face
* as a range object suitable for C++11 range based for loops.
*/
ConstFaceEdgeCCWRange fe_ccw_range(FaceHandle _fh) const;
/**
* @return The faces adjacent to the specified face
* as a range object suitable for C++11 range based for loops.
*/
ConstFaceFaceCCWRange ff_ccw_range(FaceHandle _fh) const;
/**
* @return The halfedges in the face
* as a range object suitable for C++11 range based for loops.
*/
ConstHalfedgeLoopCCWRange hl_ccw_range(HalfedgeHandle _heh) const;
//@}
//===========================================================================

View File

@@ -43,6 +43,7 @@
#error Do not include this directly, include instead PolyConnectivity.hh
#endif // OPENMESH_POLYCONNECTIVITY_INTERFACE_INCLUDE
#include <OpenMesh/Core/Mesh/PolyConnectivity.hh> // To help some IDEs
#include <OpenMesh/Core/Mesh/IteratorsT.hh>
#include <OpenMesh/Core/Mesh/CirculatorsT.hh>
@@ -99,13 +100,23 @@ class CirculatorRange : public SmartRangeT<CirculatorRange<CirculatorRangeTraitT
CirculatorRange(
const CONTAINER_TYPE &container,
CENTER_ENTITY_TYPE center) :
container_(container), center_(center) {}
ITER_TYPE begin() const { return CirculatorRangeTraitT::begin(container_, center_); }
ITER_TYPE end() const { return CirculatorRangeTraitT::end(container_, center_); }
container_(container), heh_()
{
auto it = CirculatorRangeTraitT::begin(container_, center);
heh_ = it.heh_;
}
CirculatorRange(
const CONTAINER_TYPE &container,
HalfedgeHandle heh, int) :
container_(container), heh_(heh) {}
ITER_TYPE begin() const { return CirculatorRangeTraitT::begin(container_, heh_, 1); }
ITER_TYPE end() const { return CirculatorRangeTraitT::end(container_, heh_, 1); }
private:
const CONTAINER_TYPE &container_;
CENTER_ENTITY_TYPE center_;
HalfedgeHandle heh_;
};
@@ -136,10 +147,18 @@ inline PolyConnectivity::ConstVertexIHalfedgeRange PolyConnectivity::vih_range(V
return ConstVertexIHalfedgeRange(*this, _vh);
}
inline PolyConnectivity::ConstVertexIHalfedgeRange PolyConnectivity::vih_range(HalfedgeHandle _heh) const {
return ConstVertexIHalfedgeRange(*this, opposite_halfedge_handle(_heh), 1);
}
inline PolyConnectivity::ConstVertexOHalfedgeRange PolyConnectivity::voh_range(VertexHandle _vh) const {
return ConstVertexOHalfedgeRange(*this, _vh);
}
inline PolyConnectivity::ConstVertexOHalfedgeRange PolyConnectivity::voh_range(HalfedgeHandle _heh) const {
return ConstVertexOHalfedgeRange(*this, _heh, 1);
}
inline PolyConnectivity::ConstVertexEdgeRange PolyConnectivity::ve_range(VertexHandle _vh) const {
return ConstVertexEdgeRange(*this, _vh);
}
@@ -169,6 +188,104 @@ inline PolyConnectivity::ConstHalfedgeLoopRange PolyConnectivity::hl_range(Halfe
}
inline PolyConnectivity::ConstVertexVertexCWRange PolyConnectivity::vv_cw_range(VertexHandle _vh) const {
return ConstVertexVertexCWRange(*this, _vh);
}
inline PolyConnectivity::ConstVertexIHalfedgeCWRange PolyConnectivity::vih_cw_range(VertexHandle _vh) const {
return ConstVertexIHalfedgeCWRange(*this, _vh);
}
inline PolyConnectivity::ConstVertexIHalfedgeCWRange PolyConnectivity::vih_cw_range(HalfedgeHandle _heh) const {
return ConstVertexIHalfedgeCWRange(*this, opposite_halfedge_handle(_heh), 1);
}
inline PolyConnectivity::ConstVertexOHalfedgeCWRange PolyConnectivity::voh_cw_range(VertexHandle _vh) const {
return ConstVertexOHalfedgeCWRange(*this, _vh);
}
inline PolyConnectivity::ConstVertexOHalfedgeCWRange PolyConnectivity::voh_cw_range(HalfedgeHandle _heh) const {
return ConstVertexOHalfedgeCWRange(*this, _heh, 1);
}
inline PolyConnectivity::ConstVertexEdgeCWRange PolyConnectivity::ve_cw_range(VertexHandle _vh) const {
return ConstVertexEdgeCWRange(*this, _vh);
}
inline PolyConnectivity::ConstVertexFaceCWRange PolyConnectivity::vf_cw_range(VertexHandle _vh) const {
return ConstVertexFaceCWRange(*this, _vh);
}
inline PolyConnectivity::ConstFaceVertexCWRange PolyConnectivity::fv_cw_range(FaceHandle _fh) const {
return ConstFaceVertexCWRange(*this, _fh);
}
inline PolyConnectivity::ConstFaceHalfedgeCWRange PolyConnectivity::fh_cw_range(FaceHandle _fh) const {
return ConstFaceHalfedgeCWRange(*this, _fh);
}
inline PolyConnectivity::ConstFaceEdgeCWRange PolyConnectivity::fe_cw_range(FaceHandle _fh) const {
return ConstFaceEdgeCWRange(*this, _fh);
}
inline PolyConnectivity::ConstFaceFaceCWRange PolyConnectivity::ff_cw_range(FaceHandle _fh) const {
return ConstFaceFaceCWRange(*this, _fh);
}
inline PolyConnectivity::ConstHalfedgeLoopCWRange PolyConnectivity::hl_cw_range(HalfedgeHandle _heh) const {
return ConstHalfedgeLoopCWRange(*this, _heh);
}
inline PolyConnectivity::ConstVertexVertexCCWRange PolyConnectivity::vv_ccw_range(VertexHandle _vh) const {
return ConstVertexVertexCCWRange(*this, _vh);
}
inline PolyConnectivity::ConstVertexIHalfedgeCCWRange PolyConnectivity::vih_ccw_range(VertexHandle _vh) const {
return ConstVertexIHalfedgeCCWRange(*this, _vh);
}
inline PolyConnectivity::ConstVertexIHalfedgeCCWRange PolyConnectivity::vih_ccw_range(HalfedgeHandle _heh) const {
return ConstVertexIHalfedgeCCWRange(*this, opposite_halfedge_handle(_heh), 1);
}
inline PolyConnectivity::ConstVertexOHalfedgeCCWRange PolyConnectivity::voh_ccw_range(VertexHandle _vh) const {
return ConstVertexOHalfedgeCCWRange(*this, _vh);
}
inline PolyConnectivity::ConstVertexOHalfedgeCCWRange PolyConnectivity::voh_ccw_range(HalfedgeHandle _heh) const {
return ConstVertexOHalfedgeCCWRange(*this, _heh, 1);
}
inline PolyConnectivity::ConstVertexEdgeCCWRange PolyConnectivity::ve_ccw_range(VertexHandle _vh) const {
return ConstVertexEdgeCCWRange(*this, _vh);
}
inline PolyConnectivity::ConstVertexFaceCCWRange PolyConnectivity::vf_ccw_range(VertexHandle _vh) const {
return ConstVertexFaceCCWRange(*this, _vh);
}
inline PolyConnectivity::ConstFaceVertexCCWRange PolyConnectivity::fv_ccw_range(FaceHandle _fh) const {
return ConstFaceVertexCCWRange(*this, _fh);
}
inline PolyConnectivity::ConstFaceHalfedgeCCWRange PolyConnectivity::fh_ccw_range(FaceHandle _fh) const {
return ConstFaceHalfedgeCCWRange(*this, _fh);
}
inline PolyConnectivity::ConstFaceEdgeCCWRange PolyConnectivity::fe_ccw_range(FaceHandle _fh) const {
return ConstFaceEdgeCCWRange(*this, _fh);
}
inline PolyConnectivity::ConstFaceFaceCCWRange PolyConnectivity::ff_ccw_range(FaceHandle _fh) const {
return ConstFaceFaceCCWRange(*this, _fh);
}
inline PolyConnectivity::ConstHalfedgeLoopCCWRange PolyConnectivity::hl_ccw_range(HalfedgeHandle _heh) const {
return ConstHalfedgeLoopCCWRange(*this, _heh);
}
inline PolyConnectivity::VertexIter PolyConnectivity::vertices_begin()
@@ -776,70 +893,54 @@ inline PolyConnectivity::ConstHalfedgeLoopCCWIter PolyConnectivity::chl_ccwend(H
{ return ConstHalfedgeLoopCCWIter(*this, _heh, true); }
inline PolyConnectivity::ConstVertexFaceRange SmartVertexHandle::faces() const
{
assert(mesh() != nullptr);
return mesh()->vf_range(*this);
}
inline PolyConnectivity::ConstVertexFaceRange SmartVertexHandle::faces() const { assert(mesh() != nullptr); return mesh()->vf_range (*this); }
inline PolyConnectivity::ConstVertexFaceCWRange SmartVertexHandle::faces_cw() const { assert(mesh() != nullptr); return mesh()->vf_cw_range (*this); }
inline PolyConnectivity::ConstVertexFaceCCWRange SmartVertexHandle::faces_ccw() const { assert(mesh() != nullptr); return mesh()->vf_ccw_range(*this); }
inline PolyConnectivity::ConstVertexEdgeRange SmartVertexHandle::edges() const
{
assert(mesh() != nullptr);
return mesh()->ve_range(*this);
}
inline PolyConnectivity::ConstVertexEdgeRange SmartVertexHandle::edges() const { assert(mesh() != nullptr); return mesh()->ve_range (*this); }
inline PolyConnectivity::ConstVertexEdgeCWRange SmartVertexHandle::edges_cw() const { assert(mesh() != nullptr); return mesh()->ve_cw_range (*this); }
inline PolyConnectivity::ConstVertexEdgeCCWRange SmartVertexHandle::edges_ccw() const { assert(mesh() != nullptr); return mesh()->ve_ccw_range(*this); }
inline PolyConnectivity::ConstVertexVertexRange
SmartVertexHandle::vertices() const
{
assert(mesh() != nullptr);
return mesh()->vv_range(*this);
}
inline PolyConnectivity::ConstVertexVertexRange SmartVertexHandle::vertices() const { assert(mesh() != nullptr); return mesh()->vv_range (*this); }
inline PolyConnectivity::ConstVertexVertexCWRange SmartVertexHandle::vertices_cw() const { assert(mesh() != nullptr); return mesh()->vv_cw_range (*this); }
inline PolyConnectivity::ConstVertexVertexCCWRange SmartVertexHandle::vertices_ccw() const { assert(mesh() != nullptr); return mesh()->vv_ccw_range (*this); }
inline PolyConnectivity::ConstVertexIHalfedgeRange
SmartVertexHandle::incoming_halfedges() const
{
assert(mesh() != nullptr);
return mesh()->vih_range(*this);
}
inline PolyConnectivity::ConstVertexIHalfedgeRange SmartVertexHandle::incoming_halfedges() const { assert(mesh() != nullptr); return mesh()->vih_range (*this); }
inline PolyConnectivity::ConstVertexIHalfedgeCWRange SmartVertexHandle::incoming_halfedges_cw() const { assert(mesh() != nullptr); return mesh()->vih_cw_range (*this); }
inline PolyConnectivity::ConstVertexIHalfedgeCCWRange SmartVertexHandle::incoming_halfedges_ccw() const { assert(mesh() != nullptr); return mesh()->vih_ccw_range(*this); }
inline PolyConnectivity::ConstVertexOHalfedgeRange
SmartVertexHandle::outgoing_halfedges() const
{
assert(mesh() != nullptr);
return mesh()->voh_range(*this);
}
inline PolyConnectivity::ConstVertexIHalfedgeRange SmartVertexHandle::incoming_halfedges (HalfedgeHandle _heh) const { assert(mesh() != nullptr); return mesh()->vih_range (_heh); }
inline PolyConnectivity::ConstVertexIHalfedgeCWRange SmartVertexHandle::incoming_halfedges_cw (HalfedgeHandle _heh) const { assert(mesh() != nullptr); return mesh()->vih_cw_range (_heh); }
inline PolyConnectivity::ConstVertexIHalfedgeCCWRange SmartVertexHandle::incoming_halfedges_ccw(HalfedgeHandle _heh) const { assert(mesh() != nullptr); return mesh()->vih_ccw_range(_heh); }
inline PolyConnectivity::ConstHalfedgeLoopRange
SmartHalfedgeHandle::loop() const
{
assert(mesh() != nullptr);
return mesh()->hl_range(*this);
}
inline PolyConnectivity::ConstVertexOHalfedgeRange SmartVertexHandle::outgoing_halfedges() const { assert(mesh() != nullptr); return mesh()->voh_range (*this); }
inline PolyConnectivity::ConstVertexOHalfedgeCWRange SmartVertexHandle::outgoing_halfedges_cw() const { assert(mesh() != nullptr); return mesh()->voh_cw_range (*this); }
inline PolyConnectivity::ConstVertexOHalfedgeCCWRange SmartVertexHandle::outgoing_halfedges_ccw() const { assert(mesh() != nullptr); return mesh()->voh_ccw_range(*this); }
inline PolyConnectivity::ConstVertexOHalfedgeRange SmartVertexHandle::outgoing_halfedges (HalfedgeHandle _heh) const { assert(mesh() != nullptr); return mesh()->voh_range (_heh); }
inline PolyConnectivity::ConstVertexOHalfedgeCWRange SmartVertexHandle::outgoing_halfedges_cw (HalfedgeHandle _heh) const { assert(mesh() != nullptr); return mesh()->voh_cw_range (_heh); }
inline PolyConnectivity::ConstVertexOHalfedgeCCWRange SmartVertexHandle::outgoing_halfedges_ccw(HalfedgeHandle _heh) const { assert(mesh() != nullptr); return mesh()->voh_ccw_range(_heh); }
inline PolyConnectivity::ConstFaceVertexRange SmartFaceHandle::vertices() const
{
assert(mesh() != nullptr);
return mesh()->fv_range(*this);
}
inline PolyConnectivity::ConstHalfedgeLoopRange SmartHalfedgeHandle::loop() const { assert(mesh() != nullptr); return mesh()->hl_range (*this); }
inline PolyConnectivity::ConstHalfedgeLoopCWRange SmartHalfedgeHandle::loop_cw() const { assert(mesh() != nullptr); return mesh()->hl_cw_range (*this); }
inline PolyConnectivity::ConstHalfedgeLoopCCWRange SmartHalfedgeHandle::loop_ccw() const { assert(mesh() != nullptr); return mesh()->hl_ccw_range (*this); }
inline PolyConnectivity::ConstFaceHalfedgeRange
SmartFaceHandle::halfedges() const
{
assert(mesh() != nullptr);
return mesh()->fh_range(*this);
}
inline PolyConnectivity::ConstFaceEdgeRange SmartFaceHandle::edges() const
{
assert(mesh() != nullptr);
return mesh()->fe_range(*this);
}
inline PolyConnectivity::ConstFaceVertexRange SmartFaceHandle::vertices() const { assert(mesh() != nullptr); return mesh()->fv_range (*this); }
inline PolyConnectivity::ConstFaceVertexCWRange SmartFaceHandle::vertices_cw() const { assert(mesh() != nullptr); return mesh()->fv_cw_range (*this); }
inline PolyConnectivity::ConstFaceVertexCCWRange SmartFaceHandle::vertices_ccw() const { assert(mesh() != nullptr); return mesh()->fv_ccw_range(*this); }
inline PolyConnectivity::ConstFaceFaceRange SmartFaceHandle::faces() const
{
assert(mesh() != nullptr);
return mesh()->ff_range(*this);
}
inline PolyConnectivity::ConstFaceHalfedgeRange SmartFaceHandle::halfedges() const { assert(mesh() != nullptr); return mesh()->fh_range (*this); }
inline PolyConnectivity::ConstFaceHalfedgeCWRange SmartFaceHandle::halfedges_cw() const { assert(mesh() != nullptr); return mesh()->fh_cw_range (*this); }
inline PolyConnectivity::ConstFaceHalfedgeCCWRange SmartFaceHandle::halfedges_ccw() const { assert(mesh() != nullptr); return mesh()->fh_ccw_range(*this); }
inline PolyConnectivity::ConstFaceEdgeRange SmartFaceHandle::edges() const { assert(mesh() != nullptr); return mesh()->fe_range (*this); }
inline PolyConnectivity::ConstFaceEdgeCWRange SmartFaceHandle::edges_cw() const { assert(mesh() != nullptr); return mesh()->fe_cw_range (*this); }
inline PolyConnectivity::ConstFaceEdgeCCWRange SmartFaceHandle::edges_ccw() const { assert(mesh() != nullptr); return mesh()->fe_ccw_range(*this); }
inline PolyConnectivity::ConstFaceFaceRange SmartFaceHandle::faces() const { assert(mesh() != nullptr); return mesh()->ff_range (*this); }
inline PolyConnectivity::ConstFaceFaceCWRange SmartFaceHandle::faces_cw() const { assert(mesh() != nullptr); return mesh()->ff_cw_range (*this); }
inline PolyConnectivity::ConstFaceFaceCCWRange SmartFaceHandle::faces_ccw() const { assert(mesh() != nullptr); return mesh()->ff_ccw_range(*this); }
}//namespace OpenMesh

View File

@@ -118,15 +118,47 @@ struct OPENMESHDLLEXPORT SmartVertexHandle : public SmartBaseHandle, VertexHandl
SmartHalfedgeHandle in() const;
/// Returns a range of faces incident to the vertex (PolyConnectivity::vf_range())
PolyConnectivity::ConstVertexFaceRange faces() const;
PolyConnectivity::ConstVertexFaceRange faces() const;
/// Returns a range of faces incident to the vertex (PolyConnectivity::vf_cw_range())
PolyConnectivity::ConstVertexFaceCWRange faces_cw() const;
/// Returns a range of faces incident to the vertex (PolyConnectivity::vf_ccw_range())
PolyConnectivity::ConstVertexFaceCCWRange faces_ccw() const;
/// Returns a range of edges incident to the vertex (PolyConnectivity::ve_range())
PolyConnectivity::ConstVertexEdgeRange edges() const;
PolyConnectivity::ConstVertexEdgeRange edges() const;
/// Returns a range of edges incident to the vertex (PolyConnectivity::ve_cw_range())
PolyConnectivity::ConstVertexEdgeCWRange edges_cw() const;
/// Returns a range of edges incident to the vertex (PolyConnectivity::ve_ccw_range())
PolyConnectivity::ConstVertexEdgeCCWRange edges_ccw() const;
/// Returns a range of vertices adjacent to the vertex (PolyConnectivity::vv_range())
PolyConnectivity::ConstVertexVertexRange vertices() const;
PolyConnectivity::ConstVertexVertexRange vertices() const;
/// Returns a range of vertices adjacent to the vertex (PolyConnectivity::vv_cw_range())
PolyConnectivity::ConstVertexVertexCWRange vertices_cw() const;
/// Returns a range of vertices adjacent to the vertex (PolyConnectivity::vv_ccw_range())
PolyConnectivity::ConstVertexVertexCCWRange vertices_ccw() const;
/// Returns a range of outgoing halfedges incident to the vertex (PolyConnectivity::voh_range())
PolyConnectivity::ConstVertexIHalfedgeRange incoming_halfedges() const;
/// Returns a range of incoming halfedges incident to the vertex (PolyConnectivity::vih_range())
PolyConnectivity::ConstVertexOHalfedgeRange outgoing_halfedges() const;
PolyConnectivity::ConstVertexIHalfedgeRange incoming_halfedges() const;
/// Returns a range of outgoing halfedges incident to the vertex (PolyConnectivity::voh_cw_range())
PolyConnectivity::ConstVertexIHalfedgeCWRange incoming_halfedges_cw() const;
/// Returns a range of outgoing halfedges incident to the vertex (PolyConnectivity::voh_ccw_range())
PolyConnectivity::ConstVertexIHalfedgeCCWRange incoming_halfedges_ccw() const;
/// Returns a range of outgoing halfedges incident to the vertex (PolyConnectivity::vih_range())
PolyConnectivity::ConstVertexIHalfedgeRange incoming_halfedges(HalfedgeHandle _heh) const;
/// Returns a range of incoming halfedges incident to the vertex (PolyConnectivity::vih_cw_range())
PolyConnectivity::ConstVertexIHalfedgeCWRange incoming_halfedges_cw(HalfedgeHandle _heh) const;
/// Returns a range of incoming halfedges incident to the vertex (PolyConnectivity::vih_ccw_range())
PolyConnectivity::ConstVertexIHalfedgeCCWRange incoming_halfedges_ccw(HalfedgeHandle _heh) const;
/// Returns a range of incoming halfedges incident to the vertex (PolyConnectivity::voh_range())
PolyConnectivity::ConstVertexOHalfedgeRange outgoing_halfedges() const;
/// Returns a range of incoming halfedges incident to the vertex (PolyConnectivity::voh_cw_range())
PolyConnectivity::ConstVertexOHalfedgeCWRange outgoing_halfedges_cw() const;
/// Returns a range of incoming halfedges incident to the vertex (PolyConnectivity::voh_ccw_range())
PolyConnectivity::ConstVertexOHalfedgeCCWRange outgoing_halfedges_ccw() const;
/// Returns a range of incoming halfedges incident to the vertex (PolyConnectivity::voh_range())
PolyConnectivity::ConstVertexOHalfedgeRange outgoing_halfedges(HalfedgeHandle _heh) const;
/// Returns a range of incoming halfedges incident to the vertex (PolyConnectivity::voh_cw_range())
PolyConnectivity::ConstVertexOHalfedgeCWRange outgoing_halfedges_cw(HalfedgeHandle _heh) const;
/// Returns a range of incoming halfedges incident to the vertex (PolyConnectivity::voh_ccw_range())
PolyConnectivity::ConstVertexOHalfedgeCCWRange outgoing_halfedges_ccw(HalfedgeHandle _heh) const;
/// Returns valence of the vertex
uint valence() const;
@@ -154,7 +186,11 @@ struct OPENMESHDLLEXPORT SmartHalfedgeHandle : public SmartBaseHandle, HalfedgeH
SmartFaceHandle face() const;
/// Returns a range of halfedges in the face of the halfedge (or along the boundary) (PolyConnectivity::hl_range())
PolyConnectivity::ConstHalfedgeLoopRange loop() const;
PolyConnectivity::ConstHalfedgeLoopRange loop() const;
/// Returns a range of halfedges in the face of the halfedge (or along the boundary) (PolyConnectivity::hl_cw_range())
PolyConnectivity::ConstHalfedgeLoopCWRange loop_cw() const;
/// Returns a range of halfedges in the face of the halfedge (or along the boundary) (PolyConnectivity::hl_ccw_range())
PolyConnectivity::ConstHalfedgeLoopCCWRange loop_ccw() const;
};
struct OPENMESHDLLEXPORT SmartEdgeHandle : public SmartBaseHandle, EdgeHandle, SmartHandleStatusPredicates<SmartEdgeHandle>, SmartHandleBoundaryPredicate<SmartEdgeHandle>
@@ -187,13 +223,29 @@ struct OPENMESHDLLEXPORT SmartFaceHandle : public SmartBaseHandle, FaceHandle, S
SmartHalfedgeHandle halfedge() const;
/// Returns a range of vertices incident to the face (PolyConnectivity::fv_range())
PolyConnectivity::ConstFaceVertexRange vertices() const;
PolyConnectivity::ConstFaceVertexRange vertices() const;
/// Returns a range of vertices incident to the face (PolyConnectivity::fv_cw_range())
PolyConnectivity::ConstFaceVertexCWRange vertices_cw() const;
/// Returns a range of vertices incident to the face (PolyConnectivity::fv_ccw_range())
PolyConnectivity::ConstFaceVertexCCWRange vertices_ccw() const;
/// Returns a range of halfedges of the face (PolyConnectivity::fh_range())
PolyConnectivity::ConstFaceHalfedgeRange halfedges() const;
PolyConnectivity::ConstFaceHalfedgeRange halfedges() const;
/// Returns a range of halfedges of the face (PolyConnectivity::fh_cw_range())
PolyConnectivity::ConstFaceHalfedgeCWRange halfedges_cw() const;
/// Returns a range of halfedges of the face (PolyConnectivity::fh_ccw_range())
PolyConnectivity::ConstFaceHalfedgeCCWRange halfedges_ccw() const;
/// Returns a range of edges of the face (PolyConnectivity::fv_range())
PolyConnectivity::ConstFaceEdgeRange edges() const;
PolyConnectivity::ConstFaceEdgeRange edges() const;
/// Returns a range of edges of the face (PolyConnectivity::fv_cw_range())
PolyConnectivity::ConstFaceEdgeCWRange edges_cw() const;
/// Returns a range of edges of the face (PolyConnectivity::fv_ccw_range())
PolyConnectivity::ConstFaceEdgeCCWRange edges_ccw() const;
/// Returns a range adjacent faces of the face (PolyConnectivity::ff_range())
PolyConnectivity::ConstFaceFaceRange faces() const;
PolyConnectivity::ConstFaceFaceRange faces() const;
/// Returns a range adjacent faces of the face (PolyConnectivity::ff_cw_range())
PolyConnectivity::ConstFaceFaceCWRange faces_cw() const;
/// Returns a range adjacent faces of the face (PolyConnectivity::ff_ccw_range())
PolyConnectivity::ConstFaceFaceCCWRange faces_ccw() const;
/// Returns the valence of the face
uint valence() const;

View File

@@ -191,9 +191,9 @@ TEST_F(OpenMeshTrimeshCirculatorFaceEdge, CWAndCCWTest) {
*/
int indices[4] = {4, 1, 3, 4};
int rev_indices[4];
std::reverse_copy(indices,indices+4,rev_indices);
int indices[3] = {4, 1, 3};
int rev_indices[3];
std::reverse_copy(indices,indices+3,rev_indices);
//CCW
Mesh::FaceEdgeCCWIter fe_ccwit = mesh_.fe_ccwbegin(mesh_.face_handle(1));
@@ -243,29 +243,28 @@ TEST_F(OpenMeshTrimeshCirculatorFaceEdge, CWAndCCWTest) {
/*
* conversion properties:
* a) cw_begin == CWIter(ccw_begin())
* a) *cw_begin == *++CWIter(ccw_end())
* 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()) *
* d) *cw_begin == *++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";
EXPECT_TRUE( *fe_cwIter == *++Mesh::FaceEdgeCWIter(mesh_.fe_ccwend(mesh_.face_handle(1)))) << "ccw to cw conversion failed";
EXPECT_TRUE( *++Mesh::FaceEdgeCCWIter(fe_cwIter) == *mesh_.fe_ccwend(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)
auto fe_ccwIter = Mesh::FaceEdgeCCWIter(fe_cwIter);
EXPECT_EQ(fe_cwIter->idx(),fe_ccwIter->idx())<< "iterators dont point on the same element";
++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";
--fe_ccwIter;
EXPECT_EQ(fe_cwIter->idx(),fe_ccwIter->idx()) << "iteratoes are not equal after inc/dec";
// d)
fe_cwIter = Mesh::FaceEdgeCWIter(mesh_.fe_ccwend(mesh_.face_handle(1)));
auto fe_cwEnd = mesh_.fe_ccwend(mesh_.face_handle(1));
fe_cwIter = Mesh::FaceEdgeCWIter(fe_cwEnd);
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";
EXPECT_TRUE(*mesh_.fe_cwbegin(mesh_.face_handle(1)) == *++fe_cwIter) << "end iterators are not equal";
}

View File

@@ -267,9 +267,9 @@ TEST_F(OpenMeshTrimeshCirculatorFaceFace, CWAndCCWCheck) {
*/
int indices[4] = {2, 0, 3, 2};
int rev_indices[4];
std::reverse_copy(indices,indices+4,rev_indices);
int indices[3] = {2, 0, 3};
int rev_indices[3];
std::reverse_copy(indices,indices+3,rev_indices);
//CCW
Mesh::FaceFaceCCWIter ff_ccwit = mesh_.ff_ccwbegin(mesh_.face_handle(1));
@@ -322,26 +322,25 @@ TEST_F(OpenMeshTrimeshCirculatorFaceFace, CWAndCCWCheck) {
* 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()) *
* d) 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";
EXPECT_TRUE( *ff_cwIter == *++Mesh::FaceFaceCWIter(mesh_.ff_ccwend(mesh_.face_handle(1)))) << "ccw to cw conversion failed";
EXPECT_TRUE( *++Mesh::FaceFaceCCWIter(ff_cwIter) == *mesh_.ff_ccwend(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)
auto ff_ccwIter = Mesh::FaceFaceCCWIter(ff_cwIter);
EXPECT_EQ(ff_cwIter->idx(),ff_ccwIter->idx())<< "iterators dont point on the same element";
++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";
--ff_ccwIter;
EXPECT_EQ(ff_cwIter->idx(),ff_ccwIter->idx()) << "iteratoes are not equal after inc/dec";
// d)
ff_cwIter = Mesh::FaceFaceCWIter(mesh_.ff_ccwend(mesh_.face_handle(1)));
auto ff_cwEnd = mesh_.ff_ccwend(mesh_.face_handle(1));
ff_cwIter = Mesh::FaceFaceCWIter(ff_cwEnd);
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";
EXPECT_TRUE(*mesh_.ff_cwbegin(mesh_.face_handle(1)) == *++ff_cwIter) << "end iterators are not equal";
}

View File

@@ -189,9 +189,9 @@ TEST_F(OpenMeshTrimeshCirculatorFaceHalfEdge, CWAndCCWTest) {
*/
int indices[4] = {8, 3, 6, 8};
int rev_indices[4];
std::reverse_copy(indices,indices+4,rev_indices);
int indices[3] = {8, 3, 6};
int rev_indices[3];
std::reverse_copy(indices,indices+3,rev_indices);
//CCW
Mesh::FaceHalfedgeCCWIter fh_ccwit = mesh_.fh_ccwbegin(mesh_.face_handle(1));
@@ -248,22 +248,21 @@ TEST_F(OpenMeshTrimeshCirculatorFaceHalfEdge, CWAndCCWTest) {
*/
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";
EXPECT_TRUE( *fh_cwIter == *++Mesh::FaceHalfedgeCWIter(mesh_.fh_ccwend(mesh_.face_handle(1)))) << "ccw to cw conversion failed";
EXPECT_TRUE( *++Mesh::FaceHalfedgeCCWIter(fh_cwIter) == *mesh_.fh_ccwend(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)
auto fh_ccwIter = Mesh::FaceHalfedgeCCWIter(fh_cwIter);
EXPECT_EQ(fh_cwIter->idx(),fh_ccwIter->idx())<< "iterators dont point on the same element";
++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";
--fh_ccwIter;
EXPECT_EQ(fh_cwIter->idx(),fh_ccwIter->idx()) << "iteratoes are not equal after inc/dec";
// d)
fh_cwIter = Mesh::FaceHalfedgeCWIter(mesh_.fh_ccwend(mesh_.face_handle(1)));
auto fh_cwEnd = mesh_.fh_ccwend(mesh_.face_handle(1));
fh_cwIter = Mesh::FaceHalfedgeCWIter(fh_cwEnd);
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";
EXPECT_TRUE(*mesh_.fh_cwbegin(mesh_.face_handle(1)) == *++fh_cwIter) << "end iterators are not equal";
}

View File

@@ -261,9 +261,9 @@ TEST_F(OpenMeshTrimeshCirculatorFaceVertex, CWAndCCWCheck) {
3 ==== 4 */
int indices[4] = {0, 1, 2, 0};
int rev_indices[4];
std::reverse_copy(indices,indices+4,rev_indices);
int indices[3] = {0, 1, 2};
int rev_indices[3];
std::reverse_copy(indices,indices+3,rev_indices);
//CCW
Mesh::FaceVertexCCWIter fv_ccwit = mesh_.fv_ccwbegin(fh0);
@@ -320,22 +320,21 @@ TEST_F(OpenMeshTrimeshCirculatorFaceVertex, CWAndCCWCheck) {
*/
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";
EXPECT_TRUE( *fv_cwIter == *++Mesh::FaceVertexCWIter(mesh_.fv_ccwend(mesh_.face_handle(1)))) << "ccw to cw conversion failed";
EXPECT_TRUE( *++Mesh::FaceVertexCCWIter(fv_cwIter) == *mesh_.fv_ccwend(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)
auto fv_ccwIter = Mesh::FaceVertexCCWIter(fv_cwIter);
EXPECT_EQ(fv_cwIter->idx(),fv_ccwIter->idx())<< "iterators dont point on the same element";
++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";
--fv_ccwIter;
EXPECT_EQ(fv_cwIter->idx(),fv_ccwIter->idx()) << "iteratoes are not equal after inc/dec";
// d)
fv_cwIter = Mesh::FaceVertexCWIter(mesh_.fv_ccwend(mesh_.face_handle(1)));
auto fv_cwEnd = mesh_.fv_ccwend(mesh_.face_handle(1));
fv_cwIter = Mesh::FaceVertexCWIter(fv_cwEnd);
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";
EXPECT_TRUE(*mesh_.fv_cwbegin(mesh_.face_handle(1)) == *++fv_cwIter) << "end iterators are not equal";
}

View File

@@ -336,9 +336,9 @@ TEST_F(OpenMeshTrimeshCirculatorVertexEdge, CWAndCCWCheck) {
3 ==== 4 */
int indices[5] = {5, 1, 0, 3, 5};
int rev_indices[5];
std::reverse_copy(indices,indices+5,rev_indices);
int ccw_indices[4] = {1, 0, 3, 5};
int cw_indices[4];
std::reverse_copy(ccw_indices,ccw_indices+4,cw_indices);
Mesh::VertexHandle vh = vhandle[1];
@@ -348,7 +348,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexEdge, CWAndCCWCheck) {
size_t i = 0;
for (;ve_ccwit != ve_ccwend; ++ve_ccwit, ++i)
{
EXPECT_EQ(indices[i], ve_ccwit->idx()) << "Index wrong in VertexEdgeCCWIter";
EXPECT_EQ(ccw_indices[i], ve_ccwit->idx()) << "Index wrong in VertexEdgeCCWIter";
}
EXPECT_FALSE(ve_ccwit.is_valid()) << "Iterator invalid in VertexEdgeCCWIter at end";
@@ -360,7 +360,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexEdge, CWAndCCWCheck) {
i = 0;
for (;cve_ccwit != cve_ccwend; ++cve_ccwit, ++i)
{
EXPECT_EQ(indices[i], cve_ccwit->idx()) << "Index wrong in ConstVertexEdgeCCWIter";
EXPECT_EQ(ccw_indices[i], cve_ccwit->idx()) << "Index wrong in ConstVertexEdgeCCWIter";
}
EXPECT_FALSE(cve_ccwit.is_valid()) << "Iterator invalid in ConstVertexEdgeCCWIter at end";
@@ -372,7 +372,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexEdge, CWAndCCWCheck) {
i = 0;
for (;ve_cwit != ve_cwend; ++ve_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], ve_cwit->idx()) << "Index wrong in VertexEdgeCWIter";
EXPECT_EQ(cw_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";
@@ -383,7 +383,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexEdge, CWAndCCWCheck) {
i = 0;
for (;cve_cwit != cve_cwend; ++cve_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], cve_cwit->idx()) << "Index wrong in ConstVertexEdgeCWIter";
EXPECT_EQ(cw_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";
@@ -397,22 +397,21 @@ TEST_F(OpenMeshTrimeshCirculatorVertexEdge, CWAndCCWCheck) {
*/
Mesh::VertexEdgeCWIter ve_cwIter = mesh_.ve_cwbegin(vh);
// a)
EXPECT_TRUE( ve_cwIter == Mesh::VertexEdgeCWIter(mesh_.ve_ccwbegin(vh)) ) << "ccw to cw conversion failed";
EXPECT_TRUE( Mesh::VertexEdgeCCWIter(ve_cwIter) == mesh_.ve_ccwbegin(vh) ) << "cw to ccw conversion failed";
EXPECT_TRUE( *ve_cwIter == *++Mesh::VertexEdgeCWIter(mesh_.ve_ccwend(vh))) << "ccw to cw conversion failed";
EXPECT_TRUE( *++Mesh::VertexEdgeCCWIter(ve_cwIter) == *mesh_.ve_ccwend(vh) ) << "cw to ccw conversion failed";
// b)
EXPECT_EQ( ve_cwIter->idx(), Mesh::VertexEdgeCCWIter(ve_cwIter)->idx()) << "iterators doesnt point on the same element";
// c)
auto ve_ccwIter = Mesh::VertexEdgeCCWIter(ve_cwIter);
EXPECT_EQ(ve_cwIter->idx(),ve_ccwIter->idx())<< "iterators dont point on the same element";
++ve_cwIter;
ve_ccwend = mesh_.ve_ccwend(vh);
--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";
--ve_ccwIter;
EXPECT_EQ(ve_cwIter->idx(),ve_ccwIter->idx()) << "iteratoes are not equal after inc/dec";
// d)
ve_cwIter = Mesh::VertexEdgeCWIter(mesh_.ve_ccwend(vh));
auto ve_cwEnd = mesh_.ve_ccwend(vh);
ve_cwIter = Mesh::VertexEdgeCWIter(ve_cwEnd);
EXPECT_FALSE(ve_cwIter.is_valid()) << "end iterator is not invalid";
EXPECT_TRUE(Mesh::VertexEdgeCCWIter(mesh_.ve_cwend(vh)) == mesh_.ve_ccwend(vh)) << "end iterators are not equal";
EXPECT_TRUE(*mesh_.ve_cwbegin(vh) == *++ve_cwIter) << "end iterators are not equal";
}

View File

@@ -509,9 +509,9 @@ TEST_F(OpenMeshTrimeshCirculatorVertexFace, CWAndCCWCheck) {
3 ==== 4 */
int indices[5] = {3, 0, 2, 1, 3};
int rev_indices[5];
std::reverse_copy(indices,indices+5,rev_indices);
int ccw_indices[4] = {0, 2, 1, 3};
int cw_indices[4];
std::reverse_copy(ccw_indices,ccw_indices+4,cw_indices);
Mesh::VertexHandle vh = vhandle[1];
@@ -521,7 +521,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexFace, CWAndCCWCheck) {
size_t i = 0;
for (;vf_ccwit != vf_ccwend; ++vf_ccwit, ++i)
{
EXPECT_EQ(indices[i], vf_ccwit->idx()) << "Index wrong in VertexFaceCCWIter";
EXPECT_EQ(ccw_indices[i], vf_ccwit->idx()) << "Index wrong in VertexFaceCCWIter";
}
EXPECT_FALSE(vf_ccwit.is_valid()) << "Iterator invalid in VertexFaceCCWIter at end";
@@ -533,7 +533,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexFace, CWAndCCWCheck) {
i = 0;
for (;cvf_ccwit != cvf_ccwend; ++cvf_ccwit, ++i)
{
EXPECT_EQ(indices[i], cvf_ccwit->idx()) << "Index wrong in ConstVertexFaceCCWIter";
EXPECT_EQ(ccw_indices[i], cvf_ccwit->idx()) << "Index wrong in ConstVertexFaceCCWIter";
}
EXPECT_FALSE(cvf_ccwit.is_valid()) << "Iterator invalid in ConstVertexFaceCCWIter at end";
@@ -545,7 +545,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexFace, CWAndCCWCheck) {
i = 0;
for (;vf_cwit != vf_cwend; ++vf_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], vf_cwit->idx()) << "Index wrong in VertexFaceCWIter";
EXPECT_EQ(cw_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";
@@ -556,7 +556,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexFace, CWAndCCWCheck) {
i = 0;
for (;cvf_cwit != cvf_cwend; ++cvf_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], cvf_cwit->idx()) << "Index wrong in ConstVertexFaceCWIter";
EXPECT_EQ(cw_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";
@@ -570,22 +570,21 @@ TEST_F(OpenMeshTrimeshCirculatorVertexFace, CWAndCCWCheck) {
*/
Mesh::VertexFaceCWIter vf_cwIter = mesh_.vf_cwbegin(vh);
// a)
EXPECT_TRUE( vf_cwIter == Mesh::VertexFaceCWIter(mesh_.vf_ccwbegin(vh)) ) << "ccw to cw conversion failed";
EXPECT_TRUE( Mesh::VertexFaceCCWIter(vf_cwIter) == mesh_.vf_ccwbegin(vh) ) << "cw to ccw conversion failed";
EXPECT_TRUE( *vf_cwIter == *++Mesh::VertexFaceCWIter(mesh_.vf_ccwend(vh))) << "ccw to cw conversion failed";
EXPECT_TRUE( *++Mesh::VertexFaceCCWIter(vf_cwIter) == *mesh_.vf_ccwend(vh) ) << "cw to ccw conversion failed";
// b)
EXPECT_EQ( vf_cwIter->idx(), Mesh::VertexFaceCCWIter(vf_cwIter)->idx()) << "iterators doesnt point on the same element";
// c)
auto vf_ccwIter = Mesh::VertexFaceCCWIter(vf_cwIter);
EXPECT_EQ(vf_cwIter->idx(),vf_ccwIter->idx())<< "iterators dont point on the same element";
++vf_cwIter;
vf_ccwend = mesh_.vf_ccwend(vh);
--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";
--vf_ccwIter;
EXPECT_EQ(vf_cwIter->idx(),vf_ccwIter->idx()) << "iteratoes are not equal after inc/dec";
// d)
vf_cwIter = Mesh::VertexFaceCWIter(mesh_.vf_ccwend(vh));
auto vf_cwEnd = mesh_.vf_ccwend(vh);
vf_cwIter = Mesh::VertexFaceCWIter(vf_cwEnd);
EXPECT_FALSE(vf_cwIter.is_valid()) << "end iterator is not invalid";
EXPECT_TRUE(Mesh::VertexFaceCCWIter(mesh_.vf_cwend(vh)) == mesh_.vf_ccwend(vh)) << "end iterators are not equal";
EXPECT_TRUE(*mesh_.vf_cwbegin(vh) == *++vf_cwIter) << "end iterators are not equal";
}

View File

@@ -450,9 +450,9 @@ TEST_F(OpenMeshTrimeshCirculatorVertexIHalfEdge, CWAndCCWCheck) {
3 ==== 4 */
int indices[4] = {14, 5, 2, 14};
int rev_indices[4];
std::reverse_copy(indices,indices+4,rev_indices);
int cw_indices[3] = {14, 2, 5};
int ccw_indices[3];
std::reverse_copy(cw_indices,cw_indices+3,ccw_indices);
Mesh::VertexHandle vh = vhandle[2];
@@ -462,7 +462,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexIHalfEdge, CWAndCCWCheck) {
size_t i = 0;
for (;vih_ccwit != vih_ccwend; ++vih_ccwit, ++i)
{
EXPECT_EQ(indices[i], vih_ccwit->idx()) << "Index wrong in VertexIHalfedgeCCWIter";
EXPECT_EQ(ccw_indices[i], vih_ccwit->idx()) << "Index wrong in VertexIHalfedgeCCWIter";
}
EXPECT_FALSE(vih_ccwit.is_valid()) << "Iterator invalid in VertexIHalfedgeCCWIter at end";
@@ -474,7 +474,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexIHalfEdge, CWAndCCWCheck) {
i = 0;
for (;cvih_ccwit != cvih_ccwend; ++cvih_ccwit, ++i)
{
EXPECT_EQ(indices[i], cvih_ccwit->idx()) << "Index wrong in ConstVertexIHalfedgeCCWIter";
EXPECT_EQ(ccw_indices[i], cvih_ccwit->idx()) << "Index wrong in ConstVertexIHalfedgeCCWIter";
}
EXPECT_FALSE(cvih_ccwit.is_valid()) << "Iterator invalid in ConstVertexIHalfedgeCCWIter at end";
@@ -486,7 +486,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexIHalfEdge, CWAndCCWCheck) {
i = 0;
for (;vih_cwit != vih_cwend; ++vih_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], vih_cwit->idx()) << "Index wrong in VertexIHalfedgeCWIter";
EXPECT_EQ(cw_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";
@@ -497,7 +497,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexIHalfEdge, CWAndCCWCheck) {
i = 0;
for (;cvih_cwit != cvih_cwend; ++cvih_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], cvih_cwit->idx()) << "Index wrong in ConstVertexIHalfedgeCWIter";
EXPECT_EQ(cw_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";
@@ -511,25 +511,23 @@ TEST_F(OpenMeshTrimeshCirculatorVertexIHalfEdge, CWAndCCWCheck) {
*/
Mesh::VertexIHalfedgeCWIter vih_cwIter = mesh_.vih_cwbegin(vh);
// a)
EXPECT_TRUE( vih_cwIter == Mesh::VertexIHalfedgeCWIter(mesh_.vih_ccwbegin(vh)) ) << "ccw to cw conversion failed";
EXPECT_TRUE( Mesh::VertexIHalfedgeCCWIter(vih_cwIter) == mesh_.vih_ccwbegin(vh) ) << "cw to ccw conversion failed";
EXPECT_TRUE( *vih_cwIter == *++Mesh::VertexIHalfedgeCWIter(mesh_.vih_ccwend(vh))) << "ccw to cw conversion failed";
EXPECT_TRUE( *++Mesh::VertexIHalfedgeCCWIter(vih_cwIter) == *mesh_.vih_ccwend(vh) ) << "cw to ccw conversion failed";
// b)
EXPECT_EQ( vih_cwIter->idx(), Mesh::VertexIHalfedgeCCWIter(vih_cwIter)->idx()) << "iterators doesnt point on the same element";
// c)
auto vih_ccwIter = Mesh::VertexIHalfedgeCCWIter(vih_cwIter);
EXPECT_EQ(vih_cwIter->idx(),vih_ccwIter->idx())<< "iterators dont point on the same element";
++vih_cwIter;
vih_ccwend = mesh_.vih_ccwend(vh);
--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";
--vih_ccwIter;
EXPECT_EQ(vih_cwIter->idx(),vih_ccwIter->idx()) << "iteratoes are not equal after inc/dec";
// d)
vih_cwIter = Mesh::VertexIHalfedgeCWIter(mesh_.vih_ccwend(vh));
auto vih_cwEnd = mesh_.vih_ccwend(vh);
vih_cwIter = Mesh::VertexIHalfedgeCWIter(vih_cwEnd);
EXPECT_FALSE(vih_cwIter.is_valid()) << "end iterator is not invalid";
EXPECT_TRUE(Mesh::VertexIHalfedgeCCWIter(mesh_.vih_cwend(vh)) == mesh_.vih_ccwend(vh)) << "end iterators are not equal";
EXPECT_TRUE(*mesh_.vih_cwbegin(vh) == *++vih_cwIter) << "end iterators are not equal";
}
}

View File

@@ -450,9 +450,9 @@ TEST_F(OpenMeshTrimeshCirculatorVertexOHalfEdge, CWAndCCWCheck) {
3 ==== 4 */
int indices[5] = {11, 2, 1, 6, 11};
int rev_indices[5];
std::reverse_copy(indices,indices+5,rev_indices);
int cw_indices[4] = {11, 6, 1, 2};
int ccw_indices[4];
std::reverse_copy(cw_indices,cw_indices+4,ccw_indices);
Mesh::VertexHandle vh = vhandle[1];
@@ -462,7 +462,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexOHalfEdge, CWAndCCWCheck) {
size_t i = 0;
for (;voh_ccwit != voh_ccwend; ++voh_ccwit, ++i)
{
EXPECT_EQ(indices[i], voh_ccwit->idx()) << "Index wrong in VertexOHalfedgeCCWIter";
EXPECT_EQ(ccw_indices[i], voh_ccwit->idx()) << "Index wrong in VertexOHalfedgeCCWIter";
}
EXPECT_FALSE(voh_ccwit.is_valid()) << "Iterator invalid in VertexOHalfedgeCCWIter at end";
@@ -474,7 +474,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexOHalfEdge, CWAndCCWCheck) {
i = 0;
for (;cvoh_ccwit != cvoh_ccwend; ++cvoh_ccwit, ++i)
{
EXPECT_EQ(indices[i], cvoh_ccwit->idx()) << "Index wrong in ConstVertexOHalfedgeCCWIter";
EXPECT_EQ(ccw_indices[i], cvoh_ccwit->idx()) << "Index wrong in ConstVertexOHalfedgeCCWIter";
}
EXPECT_FALSE(cvoh_ccwit.is_valid()) << "Iterator invalid in ConstVertexOHalfedgeCCWIter at end";
@@ -486,7 +486,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexOHalfEdge, CWAndCCWCheck) {
i = 0;
for (;voh_cwit != voh_cwend; ++voh_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], voh_cwit->idx()) << "Index wrong in VertexOHalfedgeCWIter";
EXPECT_EQ(cw_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";
@@ -497,7 +497,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexOHalfEdge, CWAndCCWCheck) {
i = 0;
for (;cvoh_cwit != cvoh_cwend; ++cvoh_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], cvoh_cwit->idx()) << "Index wrong in ConstVertexOHalfedgeCWIter";
EXPECT_EQ(cw_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";
@@ -511,27 +511,23 @@ TEST_F(OpenMeshTrimeshCirculatorVertexOHalfEdge, CWAndCCWCheck) {
*/
Mesh::VertexOHalfedgeCWIter voh_cwIter = mesh_.voh_cwbegin(vh);
// a)
EXPECT_TRUE( voh_cwIter == Mesh::VertexOHalfedgeCWIter(mesh_.voh_ccwbegin(vh)) ) << "ccw to cw conversion failed";
EXPECT_TRUE( Mesh::VertexOHalfedgeCCWIter(voh_cwIter) == mesh_.voh_ccwbegin(vh) ) << "cw to ccw conversion failed";
EXPECT_TRUE( *voh_cwIter == *++Mesh::VertexOHalfedgeCWIter(mesh_.voh_ccwend(vh))) << "ccw to cw conversion failed";
EXPECT_TRUE( *++Mesh::VertexOHalfedgeCCWIter(voh_cwIter) == *mesh_.voh_ccwend(vh) ) << "cw to ccw conversion failed";
// b)
EXPECT_EQ( voh_cwIter->idx(), Mesh::VertexOHalfedgeCCWIter(voh_cwIter)->idx()) << "iterators doesnt point on the same element";
// c)
auto voh_ccwIter = Mesh::VertexOHalfedgeCCWIter(voh_cwIter);
EXPECT_EQ(voh_cwIter->idx(),voh_ccwIter->idx())<< "iterators dont point on the same element";
++voh_cwIter;
voh_ccwend = mesh_.voh_ccwend(vh);
--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";
--voh_ccwIter;
EXPECT_EQ(voh_cwIter->idx(),voh_ccwIter->idx()) << "iteratoes are not equal after inc/dec";
// d)
voh_cwIter = Mesh::VertexOHalfedgeCWIter(mesh_.voh_ccwend(vh));
auto voh_cwEnd = mesh_.voh_ccwend(vh);
voh_cwIter = Mesh::VertexOHalfedgeCWIter(voh_cwEnd);
EXPECT_FALSE(voh_cwIter.is_valid()) << "end iterator is not invalid";
EXPECT_TRUE(Mesh::VertexOHalfedgeCCWIter(mesh_.voh_cwend(vh)) == mesh_.voh_ccwend(vh)) << "end iterators are not equal";
EXPECT_TRUE(*mesh_.voh_cwbegin(vh) == *++voh_cwIter) << "end iterators are not equal";
}
}

View File

@@ -339,9 +339,9 @@ TEST_F(OpenMeshTrimeshCirculatorVertexVertex, CWAndCCWCheck) {
3 ==== 4 */
int indices[5] = {4, 2, 0, 3, 4};
int rev_indices[5];
std::reverse_copy(indices,indices+5,rev_indices);
int cw_indices[4] = {4, 3, 0, 2};
int ccw_indices[4];
std::reverse_copy(cw_indices,cw_indices+4,ccw_indices);
Mesh::VertexHandle vh = vhandle[1];
@@ -351,7 +351,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexVertex, CWAndCCWCheck) {
size_t i = 0;
for (;vv_ccwit != vv_ccwend; ++vv_ccwit, ++i)
{
EXPECT_EQ(indices[i], vv_ccwit->idx()) << "Index wrong in VertexVertexCCWIter";
EXPECT_EQ(ccw_indices[i], vv_ccwit->idx()) << "Index wrong in VertexVertexCCWIter";
}
EXPECT_FALSE(vv_ccwit.is_valid()) << "Iterator invalid in VertexVertexCCWIter at end";
@@ -363,7 +363,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexVertex, CWAndCCWCheck) {
i = 0;
for (;cvv_ccwit != cvv_ccwend; ++cvv_ccwit, ++i)
{
EXPECT_EQ(indices[i], cvv_ccwit->idx()) << "Index wrong in ConstVertexVertexCCWIter";
EXPECT_EQ(ccw_indices[i], cvv_ccwit->idx()) << "Index wrong in ConstVertexVertexCCWIter";
}
EXPECT_FALSE(cvv_ccwit.is_valid()) << "Iterator invalid in ConstVertexVertexCCWIter at end";
@@ -375,7 +375,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexVertex, CWAndCCWCheck) {
i = 0;
for (;vv_cwit != vv_cwend; ++vv_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], vv_cwit->idx()) << "Index wrong in VertexVertexCWIter";
EXPECT_EQ(cw_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";
@@ -386,7 +386,7 @@ TEST_F(OpenMeshTrimeshCirculatorVertexVertex, CWAndCCWCheck) {
i = 0;
for (;cvv_cwit != cvv_cwend; ++cvv_cwit, ++i)
{
EXPECT_EQ(rev_indices[i], cvv_cwit->idx()) << "Index wrong in ConstVertexVertexCWIter";
EXPECT_EQ(cw_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";
@@ -400,22 +400,21 @@ TEST_F(OpenMeshTrimeshCirculatorVertexVertex, CWAndCCWCheck) {
*/
Mesh::VertexVertexCWIter vv_cwIter = mesh_.vv_cwbegin(vh);
// a)
EXPECT_TRUE( vv_cwIter == Mesh::VertexVertexCWIter(mesh_.vv_ccwbegin(vh)) ) << "ccw to cw convvrsion failed";
EXPECT_TRUE( Mesh::VertexVertexCCWIter(vv_cwIter) == mesh_.vv_ccwbegin(vh) ) << "cw to ccw convvrsion failed";
EXPECT_TRUE( *vv_cwIter == *++Mesh::VertexVertexCWIter(mesh_.vv_ccwend(vh))) << "ccw to cw conversion failed";
EXPECT_TRUE( *++Mesh::VertexVertexCCWIter(vv_cwIter) == *mesh_.vv_ccwend(vh) ) << "cw to ccw conversion failed";
// b)
EXPECT_EQ( vv_cwIter->idx(), Mesh::VertexVertexCCWIter(vv_cwIter)->idx()) << "iterators doesnt point on the same element";
// c)
auto vv_ccwIter = Mesh::VertexVertexCCWIter(vv_cwIter);
EXPECT_EQ(vv_cwIter->idx(),vv_ccwIter->idx())<< "iterators dont point on the same element";
++vv_cwIter;
vv_ccwend = mesh_.vv_ccwend(vh);
--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";
--vv_ccwIter;
EXPECT_EQ(vv_cwIter->idx(),vv_ccwIter->idx()) << "iteratoes are not equal after inc/dec";
// d)
vv_cwIter = Mesh::VertexVertexCWIter(mesh_.vv_ccwend(vh));
auto vv_cwEnd = mesh_.vv_ccwend(vh);
vv_cwIter = Mesh::VertexVertexCWIter(vv_cwEnd);
EXPECT_FALSE(vv_cwIter.is_valid()) << "end iterator is not invalid";
EXPECT_TRUE(Mesh::VertexVertexCCWIter(mesh_.vv_cwend(vh)) == mesh_.vv_ccwend(vh)) << "end iterators are not equal";
EXPECT_TRUE(*mesh_.vv_cwbegin(vh) == *++vv_cwIter) << "end iterators are not equal";
}

View File

@@ -0,0 +1,384 @@
#include <gtest/gtest.h>
#include <Unittests/unittests_common.hh>
#include <OpenMesh/Core/Utils/Predicates.hh>
#include <iostream>
namespace {
class OpenMeshTrimeshRange : public OpenMeshBase {
protected:
// This function is called before each test is run
virtual void SetUp()
{
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_.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 */
}
// This function is called after all tests are through
virtual void TearDown() {
// Do some final stuff with the member data here...
}
// Member already defined in OpenMeshBase
//Mesh mesh_;
};
/*
* ====================================================================
* Define tests below
* ====================================================================
*/
template <typename RangeT1, typename RangeT2>
void compare_ranges(RangeT1&& range1, RangeT2&& range2, int offset, bool reverse)
{
auto vec1 = range1.to_vector();
auto vec2 = range2.to_vector();
ASSERT_EQ(vec1.size(), vec2.size()) << "Ranges have different number of elements";
ASSERT_GT(vec1.size(), 0) << "Ranges are empty";
size_t n = vec1.size();
std::cout << "Vec1 elements: ";
for (auto el : vec1)
std::cout << el.idx() << " ";
std::cout << std::endl;
std::cout << "Vec2 elements: ";
for (auto el : vec2)
std::cout << el.idx() << " ";
std::cout << std::endl;
for (size_t i = 0; i < n; ++i)
{
size_t id1 = (i+offset)%n;
size_t id2 = reverse ? (n-i-1)%n : i;
EXPECT_EQ(vec1[id1].idx(), vec2[id2].idx()) << "Elements are not the same with offset = " << offset << " and reverse = " << std::to_string(reverse);
}
}
TEST_F(OpenMeshTrimeshRange, VertexVertexRangeMeshVsSmartHandle)
{
for (auto vh : mesh_.vertices())
{
compare_ranges(mesh_.vv_range(vh) , vh.vertices() , 0, false);
compare_ranges(mesh_.vv_cw_range(vh) , vh.vertices_cw() , 0, false);
compare_ranges(mesh_.vv_ccw_range(vh), vh.vertices_ccw(), 0, false);
}
}
TEST_F(OpenMeshTrimeshRange, VertexVertexRangeCWVsCCW)
{
for (auto vh : mesh_.vertices())
compare_ranges(vh.vertices_cw(), vh.vertices_ccw(), 0, true);
}
TEST_F(OpenMeshTrimeshRange, VertexEdgeRangeMeshVsSmartHandle)
{
for (auto vh : mesh_.vertices())
{
compare_ranges(mesh_.ve_range(vh) , vh.edges() , 0, false);
compare_ranges(mesh_.ve_cw_range(vh) , vh.edges_cw() , 0, false);
compare_ranges(mesh_.ve_ccw_range(vh), vh.edges_ccw(), 0, false);
}
}
TEST_F(OpenMeshTrimeshRange, VertexEdgeRangeCWVsCCW)
{
for (auto vh : mesh_.vertices())
compare_ranges(vh.edges_cw(), vh.edges_ccw(), 0, true);
}
TEST_F(OpenMeshTrimeshRange, VertexFaceRangeMeshVsSmartHandle)
{
for (auto vh : mesh_.vertices())
{
compare_ranges(mesh_.vf_range(vh) , vh.faces() , 0, false);
compare_ranges(mesh_.vf_cw_range(vh) , vh.faces_cw() , 0, false);
compare_ranges(mesh_.vf_ccw_range(vh), vh.faces_ccw(), 0, false);
}
}
TEST_F(OpenMeshTrimeshRange, VertexFaceRangeCWVsCCW)
{
for (auto vh : mesh_.vertices())
compare_ranges(vh.faces_cw(), vh.faces_ccw(), 0, true);
}
TEST_F(OpenMeshTrimeshRange, VertexIncomingHalfedgesRangeMeshVsSmartHandle)
{
for (auto vh : mesh_.vertices())
{
compare_ranges(mesh_.vih_range(vh) , vh.incoming_halfedges() , 0, false);
compare_ranges(mesh_.vih_cw_range(vh) , vh.incoming_halfedges_cw() , 0, false);
compare_ranges(mesh_.vih_ccw_range(vh), vh.incoming_halfedges_ccw(), 0, false);
}
}
TEST_F(OpenMeshTrimeshRange, VertexIncomingHalfedgesRangeCWVsCCW)
{
for (auto vh : mesh_.vertices())
compare_ranges(vh.incoming_halfedges_cw(), vh.incoming_halfedges_ccw(), 0, true);
}
TEST_F(OpenMeshTrimeshRange, VertexIncomingHalfedgesRangeCustomStart)
{
const int offset = 2;
for (auto vh : mesh_.vertices())
{
// mesh vs smart handle access
auto it_cw = mesh_.vih_begin(vh);
auto it_ccw = mesh_.vih_ccwbegin(vh);
for (int i = 0; i < offset; ++i)
{
++it_cw;
++it_ccw;
}
OpenMesh::HalfedgeHandle start_heh_cw = *it_cw;
OpenMesh::HalfedgeHandle start_heh_ccw = *it_ccw;
compare_ranges(mesh_.vih_range(vh) , mesh_.vih_range(start_heh_cw) , offset, false);
compare_ranges(mesh_.vih_cw_range(vh) , mesh_.vih_cw_range(start_heh_cw) , offset, false);
compare_ranges(mesh_.vih_ccw_range(vh) , mesh_.vih_ccw_range(start_heh_ccw) , offset, false);
compare_ranges(vh.incoming_halfedges() , vh.incoming_halfedges(start_heh_cw) , offset, false);
compare_ranges(vh.incoming_halfedges_cw() , vh.incoming_halfedges_cw(start_heh_cw) , offset, false);
compare_ranges(vh.incoming_halfedges_ccw(), vh.incoming_halfedges_ccw(start_heh_ccw), offset, false);
// check that ranges with custom start actually start at that start
auto hes = vh.incoming_halfedges();
for (auto heh : hes)
{
EXPECT_EQ(heh, *vh.incoming_halfedges (heh).begin()) << "Range does not start at desired start";
EXPECT_EQ(heh, *vh.incoming_halfedges_cw (heh).begin()) << "Range does not start at desired start";
EXPECT_EQ(heh, *vh.incoming_halfedges_ccw(heh).begin()) << "Range does not start at desired start";
}
}
}
TEST_F(OpenMeshTrimeshRange, VertexIncomingHalfedgesRangeBoundaryConsistency)
{
// for boundary vertices cw iterations should start at boundary halfedge
for (auto vh : mesh_.vertices().filtered(OpenMesh::Predicates::Boundary()))
{
EXPECT_TRUE(mesh_.vih_begin(vh)->opp().is_boundary());
EXPECT_TRUE(mesh_.vih_range(vh).begin()->opp().is_boundary());
EXPECT_TRUE(mesh_.vih_cwbegin(vh)->opp().is_boundary());
EXPECT_TRUE(mesh_.vih_cw_range(vh).begin()->opp().is_boundary());
EXPECT_TRUE(mesh_.vih_ccwbegin(vh)->is_boundary());
EXPECT_TRUE(mesh_.vih_ccw_range(vh).begin()->is_boundary());
}
}
TEST_F(OpenMeshTrimeshRange, VertexOutgoingHalfedgesRangeMeshVsSmartHandle)
{
for (auto vh : mesh_.vertices())
{
compare_ranges(mesh_.voh_range(vh) , vh.outgoing_halfedges() , 0, false);
compare_ranges(mesh_.voh_cw_range(vh) , vh.outgoing_halfedges_cw() , 0, false);
compare_ranges(mesh_.voh_ccw_range(vh), vh.outgoing_halfedges_ccw(), 0, false);
}
}
TEST_F(OpenMeshTrimeshRange, VertexOutgoingHalfedgesRangeCWVsCCW)
{
for (auto vh : mesh_.vertices())
compare_ranges(vh.outgoing_halfedges_cw(), vh.outgoing_halfedges_ccw(), 0, true);
}
TEST_F(OpenMeshTrimeshRange, VertexOutgoingHalfedgesRangeCustomStart)
{
const int offset = 2;
for (auto vh : mesh_.vertices())
{
// mesh vs smart handle access
auto it_cw = mesh_.voh_begin(vh);
auto it_ccw = mesh_.voh_ccwbegin(vh);
for (int i = 0; i < offset; ++i)
{
++it_cw;
++it_ccw;
}
OpenMesh::HalfedgeHandle start_heh_cw = *it_cw;
OpenMesh::HalfedgeHandle start_heh_ccw = *it_ccw;
compare_ranges(mesh_.voh_range(vh) , mesh_.voh_range(start_heh_cw) , offset, false);
compare_ranges(mesh_.voh_cw_range(vh) , mesh_.voh_cw_range(start_heh_cw) , offset, false);
compare_ranges(mesh_.voh_ccw_range(vh) , mesh_.voh_ccw_range(start_heh_ccw) , offset, false);
compare_ranges(vh.outgoing_halfedges() , vh.outgoing_halfedges(start_heh_cw) , offset, false);
compare_ranges(vh.outgoing_halfedges_cw() , vh.outgoing_halfedges_cw(start_heh_cw) , offset, false);
compare_ranges(vh.outgoing_halfedges_ccw(), vh.outgoing_halfedges_ccw(start_heh_ccw), offset, false);
// check that ranges with custom start actually start at that start
auto hes = vh.outgoing_halfedges();
for (auto heh : hes)
{
EXPECT_EQ(heh, *vh.outgoing_halfedges (heh).begin()) << "Range does not start at desired start";
EXPECT_EQ(heh, *vh.outgoing_halfedges_cw (heh).begin()) << "Range does not start at desired start";
EXPECT_EQ(heh, *vh.outgoing_halfedges_ccw(heh).begin()) << "Range does not start at desired start";
}
}
}
TEST_F(OpenMeshTrimeshRange, VertexOutgoingHalfedgesRangeBoundaryConsistency)
{
// for boundary vertices cw iterations should start at boundary halfedge
for (auto vh : mesh_.vertices().filtered(OpenMesh::Predicates::Boundary()))
{
EXPECT_TRUE(mesh_.voh_begin(vh)->is_boundary());
EXPECT_TRUE(mesh_.voh_range(vh).begin()->is_boundary());
EXPECT_TRUE(mesh_.voh_cwbegin(vh)->is_boundary());
EXPECT_TRUE(mesh_.voh_cw_range(vh).begin()->is_boundary());
EXPECT_TRUE(mesh_.voh_ccwbegin(vh)->opp().is_boundary());
EXPECT_TRUE(mesh_.voh_ccw_range(vh).begin()->opp().is_boundary());
}
}
TEST_F(OpenMeshTrimeshRange, HalfedgeLoopRangeMeshVsSmartHandle)
{
for (auto heh : mesh_.halfedges())
{
compare_ranges(mesh_.hl_range(heh) , heh.loop() , 0, false);
compare_ranges(mesh_.hl_cw_range(heh) , heh.loop_cw() , 0, false);
compare_ranges(mesh_.hl_ccw_range(heh), heh.loop_ccw(), 0, false);
}
}
TEST_F(OpenMeshTrimeshRange, HalfedgeLoopRangeCWVsCCW)
{
// Halfedge Loops are initialized from a halfedge and always start on that halfedge
// Thus, cw and ccw ranges start on the same element. We account for that by
// setting the offset to 1 for the comparison check.
// TODO: do we want to change that behavior?
for (auto heh : mesh_.halfedges())
compare_ranges(heh.loop_cw(), heh.loop_ccw(), 1, true);
}
TEST_F(OpenMeshTrimeshRange, FaceVertexRangeMeshVsSmartHandle)
{
for (auto fh : mesh_.faces())
{
compare_ranges(mesh_.fv_range(fh) , fh.vertices() , 0, false);
compare_ranges(mesh_.fv_cw_range(fh) , fh.vertices_cw() , 0, false);
compare_ranges(mesh_.fv_ccw_range(fh), fh.vertices_ccw(), 0, false);
}
}
TEST_F(OpenMeshTrimeshRange, FaceVertexRangeCWVsCCW)
{
for (auto fh : mesh_.faces())
compare_ranges(fh.vertices_cw(), fh.vertices_ccw(), 0, true);
}
TEST_F(OpenMeshTrimeshRange, FaceEdgeRangeMeshVsSmartHandle)
{
for (auto fh : mesh_.faces())
{
compare_ranges(mesh_.fe_range(fh) , fh.edges() , 0, false);
compare_ranges(mesh_.fe_cw_range(fh) , fh.edges_cw() , 0, false);
compare_ranges(mesh_.fe_ccw_range(fh), fh.edges_ccw(), 0, false);
}
}
TEST_F(OpenMeshTrimeshRange, FaceEdgeRangeCWVsCCW)
{
for (auto fh : mesh_.faces())
compare_ranges(fh.edges_cw(), fh.edges_ccw(), 0, true);
}
TEST_F(OpenMeshTrimeshRange, FaceHalfedgeRangeMeshVsSmartHandle)
{
for (auto fh : mesh_.faces())
{
compare_ranges(mesh_.fh_range(fh) , fh.halfedges() , 0, false);
compare_ranges(mesh_.fh_cw_range(fh) , fh.halfedges_cw() , 0, false);
compare_ranges(mesh_.fh_ccw_range(fh), fh.halfedges_ccw(), 0, false);
}
}
TEST_F(OpenMeshTrimeshRange, FaceHalfedgeRangeCWVsCCW)
{
for (auto fh : mesh_.faces())
compare_ranges(fh.halfedges_cw(), fh.halfedges_ccw(), 0, true);
}
TEST_F(OpenMeshTrimeshRange, FaceFaceRangeMeshVsSmartHandle)
{
for (auto fh : mesh_.faces())
{
compare_ranges(mesh_.ff_range(fh) , fh.faces() , 0, false);
compare_ranges(mesh_.ff_cw_range(fh) , fh.faces_cw() , 0, false);
compare_ranges(mesh_.ff_ccw_range(fh), fh.faces_ccw(), 0, false);
}
}
TEST_F(OpenMeshTrimeshRange, FaceFaceRangeCWVsCCW)
{
for (auto fh : mesh_.faces())
compare_ranges(fh.faces_cw(), fh.faces_ccw(), 0, true);
}
}