Merge branch 'born/edge-circulators' into 'master'
Add Edge circulators See merge request OpenMesh/OpenMesh!339
This commit is contained in:
@@ -32,3 +32,16 @@ FaceEdgeIter OpenMesh::PolyConnectivity::fe_iter (FaceHandle _fh);
|
|||||||
|
|
||||||
// Get the face-face circulator of face _fh
|
// Get the face-face circulator of face _fh
|
||||||
FaceFaceIter OpenMesh::PolyConnectivity::ff_iter (FaceHandle _fh);
|
FaceFaceIter OpenMesh::PolyConnectivity::ff_iter (FaceHandle _fh);
|
||||||
|
|
||||||
|
/**************************************************
|
||||||
|
* Edge circulators
|
||||||
|
**************************************************/
|
||||||
|
|
||||||
|
// Get the edge-vertex circulator of edge _eh
|
||||||
|
EdgeVertexIter OpenMesh::PolyConnectivity::ev_iter (EdgeHandle _eh);
|
||||||
|
|
||||||
|
// Get the edge-halfedge circulator of edge _eh
|
||||||
|
EdgeHalfedgeIter OpenMesh::PolyConnectivity::eh_iter (EdgeHandle _eh);
|
||||||
|
|
||||||
|
// Get the edge-face circulator of of edge _eh
|
||||||
|
EdgeFaceIter OpenMesh::PolyConnectivity::ef_iter (EdgeHandle _eh);
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
<li>legacy vector min max now take const args to avoid matching std implementations</li>
|
<li>legacy vector min max now take const args to avoid matching std implementations</li>
|
||||||
<li>Fixed several warnings</li>
|
<li>Fixed several warnings</li>
|
||||||
<li>Make Previous Halfedge Attribute optional again </li>
|
<li>Make Previous Halfedge Attribute optional again </li>
|
||||||
|
<li>Added edge-halfedge, edge-vertex, and edge-face circulators</li>
|
||||||
|
<li>Added default argument: mesh.halfedge_handle(eh) is now equivalent to mesh.halfedge_handle(eh, 0)</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<b>Tools</b>
|
<b>Tools</b>
|
||||||
|
|||||||
@@ -899,6 +899,12 @@ The circulators around a face are:
|
|||||||
\arg \c FaceEdgeIter: iterate over the face's edges.
|
\arg \c FaceEdgeIter: iterate over the face's edges.
|
||||||
\arg \c FaceFaceIter: iterate over all edge-neighboring faces.
|
\arg \c FaceFaceIter: iterate over all edge-neighboring faces.
|
||||||
|
|
||||||
|
The circulators around an edge are:
|
||||||
|
|
||||||
|
\arg \c EdgeVertexIter: iterate over the edge's incident vertices.
|
||||||
|
\arg \c EdgeHalfedgeIter: iterate over the edge's halfedges.
|
||||||
|
\arg \c EdgeFaceIter: iterate over the edge's incident faces.
|
||||||
|
|
||||||
Other circulators:
|
Other circulators:
|
||||||
\arg \c HalfedgeLoopIter: iterate over a sequence of Halfedges. (all Halfedges over a face or a hole)
|
\arg \c HalfedgeLoopIter: iterate over a sequence of Halfedges. (all Halfedges over a face or a hole)
|
||||||
|
|
||||||
|
|||||||
@@ -471,7 +471,7 @@ public:
|
|||||||
{ return next_halfedge_handle(opposite_halfedge_handle(_heh)); }
|
{ return next_halfedge_handle(opposite_halfedge_handle(_heh)); }
|
||||||
|
|
||||||
// --- edge connectivity ---
|
// --- edge connectivity ---
|
||||||
static HalfedgeHandle s_halfedge_handle(EdgeHandle _eh, unsigned int _i)
|
static HalfedgeHandle s_halfedge_handle(EdgeHandle _eh, unsigned int _i = 0)
|
||||||
{
|
{
|
||||||
assert(_i<=1);
|
assert(_i<=1);
|
||||||
return HalfedgeHandle((_eh.idx() << 1) + _i);
|
return HalfedgeHandle((_eh.idx() << 1) + _i);
|
||||||
@@ -480,7 +480,7 @@ public:
|
|||||||
static EdgeHandle s_edge_handle(HalfedgeHandle _heh)
|
static EdgeHandle s_edge_handle(HalfedgeHandle _heh)
|
||||||
{ return EdgeHandle(_heh.idx() >> 1); }
|
{ return EdgeHandle(_heh.idx() >> 1); }
|
||||||
|
|
||||||
HalfedgeHandle halfedge_handle(EdgeHandle _eh, unsigned int _i) const
|
HalfedgeHandle halfedge_handle(EdgeHandle _eh, unsigned int _i = 0) const
|
||||||
{
|
{
|
||||||
return s_halfedge_handle(_eh, _i);
|
return s_halfedge_handle(_eh, _i);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
//
|
//
|
||||||
// Vertex and Face circulators for PolyMesh/TriMesh
|
// Vertex, Face, and Edge circulators for PolyMesh/TriMesh
|
||||||
//
|
//
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
@@ -98,6 +98,19 @@ class GenericCirculator_CenterEntityFnsT<Mesh, typename Mesh::FaceHandle, true>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class Mesh, bool CW>
|
||||||
|
class GenericCirculator_CenterEntityFnsT<Mesh, typename Mesh::EdgeHandle, CW> {
|
||||||
|
public:
|
||||||
|
inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, const typename Mesh::HalfedgeHandle &start, int &lap_counter) {
|
||||||
|
heh = mesh->opposite_halfedge_handle(heh);
|
||||||
|
if (heh == start) ++lap_counter;
|
||||||
|
}
|
||||||
|
inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, const typename Mesh::HalfedgeHandle &start, int &lap_counter) {
|
||||||
|
if (heh == start) --lap_counter;
|
||||||
|
heh = mesh->opposite_halfedge_handle(heh);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
// CCW
|
// CCW
|
||||||
|
|
||||||
@@ -150,6 +163,14 @@ class GenericCirculator_DereferenciabilityCheckT<Mesh, typename Mesh::VertexHand
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class Mesh>
|
||||||
|
class GenericCirculator_DereferenciabilityCheckT<Mesh, typename Mesh::EdgeHandle, typename Mesh::FaceHandle> {
|
||||||
|
public:
|
||||||
|
inline static bool isDereferenciable(const Mesh *mesh, const typename Mesh::HalfedgeHandle &heh) {
|
||||||
|
return mesh->face_handle(heh).is_valid();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<class Mesh, class CenterEntityHandle, class ValueHandle, bool CW = true>
|
template<class Mesh, class CenterEntityHandle, class ValueHandle, bool CW = true>
|
||||||
class GenericCirculator_ValueHandleFnsT {
|
class GenericCirculator_ValueHandleFnsT {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -379,6 +379,53 @@ public:
|
|||||||
typedef FaceFaceCWIter ConstFaceFaceCWIter;
|
typedef FaceFaceCWIter ConstFaceFaceCWIter;
|
||||||
typedef FaceFaceCCWIter ConstFaceFaceCCWIter;
|
typedef FaceFaceCCWIter ConstFaceFaceCCWIter;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Edge-centered circulators
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct EdgeVertexTraits
|
||||||
|
{
|
||||||
|
using Mesh = This;
|
||||||
|
using CenterEntityHandle = This::EdgeHandle;
|
||||||
|
using ValueHandle = This::VertexHandle;
|
||||||
|
static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return static_cast<const ArrayKernel*>(_mesh)->from_vertex_handle(_heh); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumerate vertices incident to an edge.
|
||||||
|
*/
|
||||||
|
typedef Iterators::GenericCirculatorT_DEPRECATED<EdgeVertexTraits> EdgeVertexIter;
|
||||||
|
|
||||||
|
struct EdgeHalfedgeTraits
|
||||||
|
{
|
||||||
|
using Mesh = This;
|
||||||
|
using CenterEntityHandle = This::EdgeHandle;
|
||||||
|
using ValueHandle = This::HalfedgeHandle;
|
||||||
|
static ValueHandle toHandle(const Mesh* const /* _mesh */, This::HalfedgeHandle _heh) { return _heh; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumerate the halfedges of an edge.
|
||||||
|
*/
|
||||||
|
typedef Iterators::GenericCirculatorT_DEPRECATED<EdgeHalfedgeTraits> EdgeHalfedgeIter;
|
||||||
|
|
||||||
|
struct EdgeFaceTraits
|
||||||
|
{
|
||||||
|
using Mesh = This;
|
||||||
|
using CenterEntityHandle = This::EdgeHandle;
|
||||||
|
using ValueHandle = This::FaceHandle;
|
||||||
|
static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return static_cast<const ArrayKernel*>(_mesh)->face_handle(_heh); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumerate faces incident to an edge.
|
||||||
|
*/
|
||||||
|
typedef Iterators::GenericCirculatorT_DEPRECATED<EdgeFaceTraits> EdgeFaceIter;
|
||||||
|
|
||||||
|
typedef EdgeVertexIter ConstEdgeVertexIter;
|
||||||
|
typedef EdgeHalfedgeIter ConstEdgeHalfedgeIter;
|
||||||
|
typedef EdgeFaceIter ConstEdgeFaceIter;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Halfedge circulator
|
* Halfedge circulator
|
||||||
*/
|
*/
|
||||||
@@ -435,6 +482,9 @@ public:
|
|||||||
typedef FaceEdgeCWIter FECWIter;
|
typedef FaceEdgeCWIter FECWIter;
|
||||||
typedef FaceEdgeCCWIter FECWWIter;
|
typedef FaceEdgeCCWIter FECWWIter;
|
||||||
typedef FaceFaceIter FFIter;
|
typedef FaceFaceIter FFIter;
|
||||||
|
typedef EdgeVertexIter EVIter;
|
||||||
|
typedef EdgeHalfedgeIter EHIter;
|
||||||
|
typedef EdgeFaceIter EFIter;
|
||||||
|
|
||||||
typedef ConstVertexVertexIter CVVIter;
|
typedef ConstVertexVertexIter CVVIter;
|
||||||
typedef ConstVertexVertexCWIter CVVCWIter;
|
typedef ConstVertexVertexCWIter CVVCWIter;
|
||||||
@@ -463,6 +513,9 @@ public:
|
|||||||
typedef ConstFaceFaceIter CFFIter;
|
typedef ConstFaceFaceIter CFFIter;
|
||||||
typedef ConstFaceFaceCWIter CFFCWIter;
|
typedef ConstFaceFaceCWIter CFFCWIter;
|
||||||
typedef ConstFaceFaceCCWIter CFFCCWIter;
|
typedef ConstFaceFaceCCWIter CFFCCWIter;
|
||||||
|
typedef ConstEdgeVertexIter CEVIter;
|
||||||
|
typedef ConstEdgeHalfedgeIter CEHIter;
|
||||||
|
typedef ConstEdgeFaceIter CEFIter;
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -600,14 +653,14 @@ public:
|
|||||||
using ArrayKernel::s_halfedge_handle;
|
using ArrayKernel::s_halfedge_handle;
|
||||||
using ArrayKernel::s_edge_handle;
|
using ArrayKernel::s_edge_handle;
|
||||||
|
|
||||||
static SmartHalfedgeHandle s_halfedge_handle(SmartEdgeHandle _eh, unsigned int _i);
|
static SmartHalfedgeHandle s_halfedge_handle(SmartEdgeHandle _eh, unsigned int _i = 0);
|
||||||
static SmartEdgeHandle s_edge_handle(SmartHalfedgeHandle _heh);
|
static SmartEdgeHandle s_edge_handle(SmartHalfedgeHandle _heh);
|
||||||
|
|
||||||
using ArrayKernel::halfedge_handle;
|
using ArrayKernel::halfedge_handle;
|
||||||
using ArrayKernel::edge_handle;
|
using ArrayKernel::edge_handle;
|
||||||
using ArrayKernel::face_handle;
|
using ArrayKernel::face_handle;
|
||||||
|
|
||||||
inline SmartHalfedgeHandle halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) const;
|
inline SmartHalfedgeHandle halfedge_handle(SmartEdgeHandle _eh, unsigned int _i = 0) const;
|
||||||
inline SmartHalfedgeHandle halfedge_handle(SmartFaceHandle _fh) const;
|
inline SmartHalfedgeHandle halfedge_handle(SmartFaceHandle _fh) const;
|
||||||
inline SmartHalfedgeHandle halfedge_handle(SmartVertexHandle _vh) const;
|
inline SmartHalfedgeHandle halfedge_handle(SmartVertexHandle _vh) const;
|
||||||
inline SmartEdgeHandle edge_handle(SmartHalfedgeHandle _heh) const;
|
inline SmartEdgeHandle edge_handle(SmartHalfedgeHandle _heh) const;
|
||||||
@@ -688,7 +741,7 @@ public:
|
|||||||
|
|
||||||
//--- circulators ---
|
//--- circulators ---
|
||||||
|
|
||||||
/** \name Vertex and Face circulators
|
/** \name Vertex, Face, and Edge circulators
|
||||||
*/
|
*/
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
@@ -804,6 +857,20 @@ public:
|
|||||||
/// const face - face circulator
|
/// const face - face circulator
|
||||||
ConstFaceFaceCCWIter cff_ccwiter(FaceHandle _fh) const;
|
ConstFaceFaceCCWIter cff_ccwiter(FaceHandle _fh) const;
|
||||||
|
|
||||||
|
/// edge - vertex circulator
|
||||||
|
EdgeVertexIter ev_iter(EdgeHandle _eh);
|
||||||
|
/// edge - halfedge circulator
|
||||||
|
EdgeHalfedgeIter eh_iter(EdgeHandle _eh);
|
||||||
|
/// edge - face circulator
|
||||||
|
EdgeFaceIter ef_iter(EdgeHandle _eh);
|
||||||
|
|
||||||
|
/// const edge - vertex circulator
|
||||||
|
ConstEdgeVertexIter cev_iter(EdgeHandle _eh) const;
|
||||||
|
/// const edge - halfedge circulator
|
||||||
|
ConstEdgeHalfedgeIter ceh_iter(EdgeHandle _eh) const;
|
||||||
|
/// const edge - face circulator
|
||||||
|
ConstEdgeFaceIter cef_iter(EdgeHandle _eh) const;
|
||||||
|
|
||||||
// 'begin' circulators
|
// 'begin' circulators
|
||||||
|
|
||||||
/// vertex - vertex circulator
|
/// vertex - vertex circulator
|
||||||
@@ -931,6 +998,20 @@ public:
|
|||||||
/// const halfedge circulator ccw
|
/// const halfedge circulator ccw
|
||||||
ConstHalfedgeLoopCCWIter chl_ccwbegin(HalfedgeHandle _heh) const;
|
ConstHalfedgeLoopCCWIter chl_ccwbegin(HalfedgeHandle _heh) const;
|
||||||
|
|
||||||
|
/// edge - vertex circulator
|
||||||
|
EdgeVertexIter ev_begin(EdgeHandle _eh);
|
||||||
|
/// edge - halfedge circulator
|
||||||
|
EdgeHalfedgeIter eh_begin(EdgeHandle _eh);
|
||||||
|
/// edge - face circulator
|
||||||
|
EdgeFaceIter ef_begin(EdgeHandle _eh);
|
||||||
|
|
||||||
|
/// const edge - vertex circulator
|
||||||
|
ConstEdgeVertexIter cev_begin(EdgeHandle _eh) const;
|
||||||
|
/// const edge - halfedge circulator
|
||||||
|
ConstEdgeHalfedgeIter ceh_begin(EdgeHandle _eh) const;
|
||||||
|
/// const edge - face circulator
|
||||||
|
ConstEdgeFaceIter cef_begin(EdgeHandle _eh) const;
|
||||||
|
|
||||||
// 'end' circulators
|
// 'end' circulators
|
||||||
|
|
||||||
/// vertex - vertex circulator
|
/// vertex - vertex circulator
|
||||||
@@ -1056,6 +1137,21 @@ public:
|
|||||||
ConstHalfedgeLoopCWIter chl_cwend(HalfedgeHandle _heh) const;
|
ConstHalfedgeLoopCWIter chl_cwend(HalfedgeHandle _heh) const;
|
||||||
/// const face - face circulator ccw
|
/// const face - face circulator ccw
|
||||||
ConstHalfedgeLoopCCWIter chl_ccwend(HalfedgeHandle _heh) const;
|
ConstHalfedgeLoopCCWIter chl_ccwend(HalfedgeHandle _heh) const;
|
||||||
|
|
||||||
|
/// edge - vertex circulator
|
||||||
|
EdgeVertexIter ev_end(EdgeHandle _eh);
|
||||||
|
/// edge - halfedge circulator
|
||||||
|
EdgeHalfedgeIter eh_end(EdgeHandle _eh);
|
||||||
|
/// edge - face circulator
|
||||||
|
EdgeFaceIter ef_end(EdgeHandle _eh);
|
||||||
|
|
||||||
|
/// const edge - vertex circulator
|
||||||
|
ConstEdgeVertexIter cev_end(EdgeHandle _eh) const;
|
||||||
|
/// const edge - halfedge circulator
|
||||||
|
ConstEdgeHalfedgeIter ceh_end(EdgeHandle _eh) const;
|
||||||
|
/// const edge - face circulator
|
||||||
|
ConstEdgeFaceIter cef_end(EdgeHandle _eh) const;
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name Range based iterators and circulators */
|
/** @name Range based iterators and circulators */
|
||||||
@@ -1178,6 +1274,9 @@ public:
|
|||||||
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstFaceHalfedgeIter , FaceHandle , HalfedgeHandle, &PolyConnectivity::cfh_begin , &PolyConnectivity::cfh_end >> ConstFaceHalfedgeRange;
|
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, 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, ConstFaceFaceIter , FaceHandle , FaceHandle , &PolyConnectivity::cff_begin , &PolyConnectivity::cff_end >> ConstFaceFaceRange;
|
||||||
|
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstEdgeVertexIter , EdgeHandle , VertexHandle , &PolyConnectivity::cev_begin , &PolyConnectivity::cev_end >> ConstEdgeVertexRange;
|
||||||
|
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstEdgeHalfedgeIter , EdgeHandle , HalfedgeHandle, &PolyConnectivity::ceh_begin , &PolyConnectivity::ceh_end >> ConstEdgeHalfedgeRange;
|
||||||
|
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstEdgeFaceIter , EdgeHandle , FaceHandle, &PolyConnectivity::cef_begin , &PolyConnectivity::cef_end >> ConstEdgeFaceRange;
|
||||||
typedef CirculatorRange<CirculatorRangeTraitT<PolyConnectivity, ConstHalfedgeLoopIter , HalfedgeHandle, HalfedgeHandle, &PolyConnectivity::chl_begin , &PolyConnectivity::chl_end >> ConstHalfedgeLoopRange;
|
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, ConstVertexVertexCWIter , VertexHandle , VertexHandle , &PolyConnectivity::cvv_cwbegin , &PolyConnectivity::cvv_cwend >> ConstVertexVertexCWRange;
|
||||||
@@ -1270,6 +1369,31 @@ public:
|
|||||||
*/
|
*/
|
||||||
ConstFaceFaceRange ff_range(FaceHandle _fh) const;
|
ConstFaceFaceRange ff_range(FaceHandle _fh) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The vertices incident to the specified edge
|
||||||
|
* as a range object suitable for C++11 range based for loops.
|
||||||
|
*/
|
||||||
|
ConstEdgeVertexRange ev_range(EdgeHandle _eh) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The halfedges of the specified edge
|
||||||
|
* as a range object suitable for C++11 range based for loops.
|
||||||
|
*/
|
||||||
|
ConstEdgeHalfedgeRange eh_range(EdgeHandle _eh) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The halfedges of the specified edge
|
||||||
|
* as a range object suitable for C++11 range based for loops.
|
||||||
|
* Like eh_range(_heh.edge()) but starts iteration at _heh
|
||||||
|
*/
|
||||||
|
ConstEdgeHalfedgeRange eh_range(HalfedgeHandle _heh) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The faces incident to the specified edge
|
||||||
|
* as a range object suitable for C++11 range based for loops.
|
||||||
|
*/
|
||||||
|
ConstEdgeFaceRange ef_range(EdgeHandle _eh) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The halfedges in the face
|
* @return The halfedges in the face
|
||||||
* as a range object suitable for C++11 range based for loops.
|
* as a range object suitable for C++11 range based for loops.
|
||||||
@@ -1313,7 +1437,7 @@ public:
|
|||||||
* @return The edges incident to the specified vertex
|
* @return The edges incident to the specified vertex
|
||||||
* as a range object suitable for C++11 range based for loops.
|
* as a range object suitable for C++11 range based for loops.
|
||||||
*/
|
*/
|
||||||
ConstVertexEdgeCWRange ve_cw_range(VertexHandle _vh) const ;
|
ConstVertexEdgeCWRange ve_cw_range(VertexHandle _vh) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The faces incident to the specified vertex
|
* @return The faces incident to the specified vertex
|
||||||
@@ -1420,6 +1544,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
ConstFaceFaceCCWRange ff_ccw_range(FaceHandle _fh) const;
|
ConstFaceFaceCCWRange ff_ccw_range(FaceHandle _fh) const;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The halfedges in the face
|
* @return The halfedges in the face
|
||||||
* as a range object suitable for C++11 range based for loops.
|
* as a range object suitable for C++11 range based for loops.
|
||||||
|
|||||||
@@ -183,6 +183,22 @@ inline PolyConnectivity::ConstFaceFaceRange PolyConnectivity::ff_range(FaceHandl
|
|||||||
return ConstFaceFaceRange(*this, _fh);
|
return ConstFaceFaceRange(*this, _fh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline PolyConnectivity::ConstEdgeVertexRange PolyConnectivity::ev_range(EdgeHandle _eh) const {
|
||||||
|
return ConstEdgeVertexRange(*this, _eh);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline PolyConnectivity::ConstEdgeHalfedgeRange PolyConnectivity::eh_range(EdgeHandle _eh) const {
|
||||||
|
return ConstEdgeHalfedgeRange(*this, _eh);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline PolyConnectivity::ConstEdgeHalfedgeRange PolyConnectivity::eh_range(HalfedgeHandle _heh) const {
|
||||||
|
return ConstEdgeHalfedgeRange(*this, _heh, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline PolyConnectivity::ConstEdgeFaceRange PolyConnectivity::ef_range(EdgeHandle _eh) const {
|
||||||
|
return ConstEdgeFaceRange(*this, _eh);
|
||||||
|
}
|
||||||
|
|
||||||
inline PolyConnectivity::ConstHalfedgeLoopRange PolyConnectivity::hl_range(HalfedgeHandle _heh) const {
|
inline PolyConnectivity::ConstHalfedgeLoopRange PolyConnectivity::hl_range(HalfedgeHandle _heh) const {
|
||||||
return ConstHalfedgeLoopRange(*this, _heh);
|
return ConstHalfedgeLoopRange(*this, _heh);
|
||||||
}
|
}
|
||||||
@@ -282,6 +298,7 @@ inline PolyConnectivity::ConstFaceFaceCCWRange PolyConnectivity::ff_ccw_range(Fa
|
|||||||
return ConstFaceFaceCCWRange(*this, _fh);
|
return ConstFaceFaceCCWRange(*this, _fh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline PolyConnectivity::ConstHalfedgeLoopCCWRange PolyConnectivity::hl_ccw_range(HalfedgeHandle _heh) const {
|
inline PolyConnectivity::ConstHalfedgeLoopCCWRange PolyConnectivity::hl_ccw_range(HalfedgeHandle _heh) const {
|
||||||
return ConstHalfedgeLoopCCWRange(*this, _heh);
|
return ConstHalfedgeLoopCCWRange(*this, _heh);
|
||||||
}
|
}
|
||||||
@@ -523,6 +540,24 @@ inline PolyConnectivity::ConstFaceFaceCWIter PolyConnectivity::cff_cwiter(ArrayK
|
|||||||
inline PolyConnectivity::ConstFaceFaceCCWIter PolyConnectivity::cff_ccwiter(ArrayKernel::FaceHandle _fh) const
|
inline PolyConnectivity::ConstFaceFaceCCWIter PolyConnectivity::cff_ccwiter(ArrayKernel::FaceHandle _fh) const
|
||||||
{ return ConstFaceFaceCCWIter(*this, _fh); }
|
{ return ConstFaceFaceCCWIter(*this, _fh); }
|
||||||
|
|
||||||
|
inline PolyConnectivity::EdgeVertexIter PolyConnectivity::ev_iter(ArrayKernel::EdgeHandle _eh)
|
||||||
|
{ return EdgeVertexIter(*this, _eh); }
|
||||||
|
|
||||||
|
inline PolyConnectivity::EdgeHalfedgeIter PolyConnectivity::eh_iter(ArrayKernel::EdgeHandle _eh)
|
||||||
|
{ return EdgeHalfedgeIter(*this, _eh); }
|
||||||
|
|
||||||
|
inline PolyConnectivity::EdgeFaceIter PolyConnectivity::ef_iter(ArrayKernel::EdgeHandle _eh)
|
||||||
|
{ return EdgeFaceIter(*this, _eh); }
|
||||||
|
|
||||||
|
inline PolyConnectivity::ConstEdgeVertexIter PolyConnectivity::cev_iter(ArrayKernel::EdgeHandle _eh) const
|
||||||
|
{ return ConstEdgeVertexIter(*this, _eh); }
|
||||||
|
|
||||||
|
inline PolyConnectivity::ConstEdgeHalfedgeIter PolyConnectivity::ceh_iter(ArrayKernel::EdgeHandle _eh) const
|
||||||
|
{ return ConstEdgeHalfedgeIter(*this, _eh); }
|
||||||
|
|
||||||
|
inline PolyConnectivity::ConstEdgeFaceIter PolyConnectivity::cef_iter(ArrayKernel::EdgeHandle _eh) const
|
||||||
|
{ return ConstEdgeFaceIter(*this, _eh); }
|
||||||
|
|
||||||
|
|
||||||
inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_begin(VertexHandle _vh)
|
inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_begin(VertexHandle _vh)
|
||||||
{ return VertexVertexIter(*this, _vh); }
|
{ return VertexVertexIter(*this, _vh); }
|
||||||
@@ -707,6 +742,27 @@ inline PolyConnectivity::ConstHalfedgeLoopCWIter PolyConnectivity::chl_cwbegin(H
|
|||||||
inline PolyConnectivity::ConstHalfedgeLoopCCWIter PolyConnectivity::chl_ccwbegin(HalfedgeHandle _heh) const
|
inline PolyConnectivity::ConstHalfedgeLoopCCWIter PolyConnectivity::chl_ccwbegin(HalfedgeHandle _heh) const
|
||||||
{ return ConstHalfedgeLoopCCWIter(*this, _heh); }
|
{ return ConstHalfedgeLoopCCWIter(*this, _heh); }
|
||||||
|
|
||||||
|
|
||||||
|
inline PolyConnectivity::EdgeVertexIter PolyConnectivity::ev_begin(EdgeHandle _eh)
|
||||||
|
{ return EdgeVertexIter(*this, _eh); }
|
||||||
|
|
||||||
|
inline PolyConnectivity::EdgeHalfedgeIter PolyConnectivity::eh_begin(EdgeHandle _eh)
|
||||||
|
{ return EdgeHalfedgeIter(*this, _eh); }
|
||||||
|
|
||||||
|
inline PolyConnectivity::EdgeFaceIter PolyConnectivity::ef_begin(EdgeHandle _eh)
|
||||||
|
{ return EdgeFaceIter(*this, _eh); }
|
||||||
|
|
||||||
|
|
||||||
|
inline PolyConnectivity::ConstEdgeVertexIter PolyConnectivity::cev_begin(EdgeHandle _eh) const
|
||||||
|
{ return ConstEdgeVertexIter(*this, _eh); }
|
||||||
|
|
||||||
|
inline PolyConnectivity::ConstEdgeHalfedgeIter PolyConnectivity::ceh_begin(EdgeHandle _eh) const
|
||||||
|
{ return ConstEdgeHalfedgeIter(*this, _eh); }
|
||||||
|
|
||||||
|
inline PolyConnectivity::ConstEdgeFaceIter PolyConnectivity::cef_begin(EdgeHandle _eh) const
|
||||||
|
{ return ConstEdgeFaceIter(*this, _eh); }
|
||||||
|
|
||||||
|
|
||||||
// 'end' circulators
|
// 'end' circulators
|
||||||
|
|
||||||
inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_end(VertexHandle _vh)
|
inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_end(VertexHandle _vh)
|
||||||
@@ -893,6 +949,26 @@ inline PolyConnectivity::ConstHalfedgeLoopCCWIter PolyConnectivity::chl_ccwend(H
|
|||||||
{ return ConstHalfedgeLoopCCWIter(*this, _heh, true); }
|
{ return ConstHalfedgeLoopCCWIter(*this, _heh, true); }
|
||||||
|
|
||||||
|
|
||||||
|
inline PolyConnectivity::EdgeVertexIter PolyConnectivity::ev_end(EdgeHandle _eh)
|
||||||
|
{ return EdgeVertexIter(*this, _eh, true); }
|
||||||
|
|
||||||
|
inline PolyConnectivity::EdgeHalfedgeIter PolyConnectivity::eh_end(EdgeHandle _eh)
|
||||||
|
{ return EdgeHalfedgeIter(*this, _eh, true); }
|
||||||
|
|
||||||
|
inline PolyConnectivity::EdgeFaceIter PolyConnectivity::ef_end(EdgeHandle _eh)
|
||||||
|
{ return EdgeFaceIter(*this, _eh, true); }
|
||||||
|
|
||||||
|
|
||||||
|
inline PolyConnectivity::ConstEdgeVertexIter PolyConnectivity::cev_end(EdgeHandle _eh) const
|
||||||
|
{ return ConstEdgeVertexIter(*this, _eh, true); }
|
||||||
|
|
||||||
|
inline PolyConnectivity::ConstEdgeHalfedgeIter PolyConnectivity::ceh_end(EdgeHandle _eh) const
|
||||||
|
{ return ConstEdgeHalfedgeIter(*this, _eh, true); }
|
||||||
|
|
||||||
|
inline PolyConnectivity::ConstEdgeFaceIter PolyConnectivity::cef_end(EdgeHandle _eh) const
|
||||||
|
{ return ConstEdgeFaceIter(*this, _eh, 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::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::ConstVertexFaceCCWRange SmartVertexHandle::faces_ccw() const { assert(mesh() != nullptr); return mesh()->vf_ccw_range(*this); }
|
||||||
@@ -943,4 +1019,13 @@ inline PolyConnectivity::ConstFaceFaceRange SmartFaceHandle::faces()
|
|||||||
inline PolyConnectivity::ConstFaceFaceCWRange SmartFaceHandle::faces_cw() const { assert(mesh() != nullptr); return mesh()->ff_cw_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); }
|
inline PolyConnectivity::ConstFaceFaceCCWRange SmartFaceHandle::faces_ccw() const { assert(mesh() != nullptr); return mesh()->ff_ccw_range(*this); }
|
||||||
|
|
||||||
|
|
||||||
|
inline PolyConnectivity::ConstEdgeVertexRange SmartEdgeHandle::vertices() const { assert(mesh() != nullptr); return mesh()->ev_range (*this); }
|
||||||
|
|
||||||
|
inline PolyConnectivity::ConstEdgeHalfedgeRange SmartEdgeHandle::halfedges() const { assert(mesh() != nullptr); return mesh()->eh_range (*this); }
|
||||||
|
|
||||||
|
inline PolyConnectivity::ConstEdgeHalfedgeRange SmartEdgeHandle::halfedges(HalfedgeHandle _heh) const { assert(mesh() != nullptr); return mesh()->eh_range (_heh); }
|
||||||
|
|
||||||
|
inline PolyConnectivity::ConstEdgeFaceRange SmartEdgeHandle::faces() const { assert(mesh() != nullptr); return mesh()->ef_range (*this); }
|
||||||
|
|
||||||
}//namespace OpenMesh
|
}//namespace OpenMesh
|
||||||
|
|||||||
@@ -213,6 +213,15 @@ struct OPENMESHDLLEXPORT SmartEdgeHandle : public SmartBaseHandle, EdgeHandle, S
|
|||||||
SmartVertexHandle v0() const;
|
SmartVertexHandle v0() const;
|
||||||
/// Shorthand for vertex(1)
|
/// Shorthand for vertex(1)
|
||||||
SmartVertexHandle v1() const;
|
SmartVertexHandle v1() const;
|
||||||
|
|
||||||
|
/// Returns a range of vertices incident to the edge (PolyConnectivity::ev_range())
|
||||||
|
PolyConnectivity::ConstEdgeVertexRange vertices() const;
|
||||||
|
/// Returns a range of halfedges of the edge (PolyConnectivity::eh_range())
|
||||||
|
PolyConnectivity::ConstEdgeHalfedgeRange halfedges() const;
|
||||||
|
/// Returns a range of halfedges of the edge (PolyConnectivity::eh_range())
|
||||||
|
PolyConnectivity::ConstEdgeHalfedgeRange halfedges(HalfedgeHandle _heh) const;
|
||||||
|
/// Returns a range of faces incident to the edge (PolyConnectivity::ef_range())
|
||||||
|
PolyConnectivity::ConstEdgeFaceRange faces() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OPENMESHDLLEXPORT SmartFaceHandle : public SmartBaseHandle, FaceHandle, SmartHandleStatusPredicates<SmartFaceHandle>, SmartHandleBoundaryPredicate<SmartFaceHandle>
|
struct OPENMESHDLLEXPORT SmartFaceHandle : public SmartBaseHandle, FaceHandle, SmartHandleStatusPredicates<SmartFaceHandle>, SmartHandleBoundaryPredicate<SmartFaceHandle>
|
||||||
@@ -415,13 +424,13 @@ inline SmartFaceHandle SmartHalfedgeHandle::face() const
|
|||||||
return make_smart(mesh()->face_handle(*this), mesh());
|
return make_smart(mesh()->face_handle(*this), mesh());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline SmartHalfedgeHandle SmartEdgeHandle::halfedge(unsigned int _i) const
|
inline SmartHalfedgeHandle SmartEdgeHandle::halfedge(unsigned int _i = 0) const
|
||||||
{
|
{
|
||||||
assert(mesh() != nullptr);
|
assert(mesh() != nullptr);
|
||||||
return make_smart(mesh()->halfedge_handle(*this, _i), mesh());
|
return make_smart(mesh()->halfedge_handle(*this, _i), mesh());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline SmartHalfedgeHandle SmartEdgeHandle::h(unsigned int _i) const
|
inline SmartHalfedgeHandle SmartEdgeHandle::h(unsigned int _i = 0) const
|
||||||
{
|
{
|
||||||
return halfedge(_i);
|
return halfedge(_i);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,8 +38,11 @@ unittests_sr_binary.cc
|
|||||||
unittests_stripifier.cc
|
unittests_stripifier.cc
|
||||||
unittests_subdivider_adaptive.cc
|
unittests_subdivider_adaptive.cc
|
||||||
unittests_subdivider_uniform.cc
|
unittests_subdivider_uniform.cc
|
||||||
unittests_trimesh_circulator_current_halfedge_handle_replacement.cc
|
|
||||||
unittests_traits.cc
|
unittests_traits.cc
|
||||||
|
unittests_trimesh_circulator_current_halfedge_handle_replacement.cc
|
||||||
|
unittests_trimesh_circulator_edge_face.cc
|
||||||
|
unittests_trimesh_circulator_edge_halfedge.cc
|
||||||
|
unittests_trimesh_circulator_edge_vertex.cc
|
||||||
unittests_trimesh_circulator_face_edge.cc
|
unittests_trimesh_circulator_face_edge.cc
|
||||||
unittests_trimesh_circulator_face_face.cc
|
unittests_trimesh_circulator_face_face.cc
|
||||||
unittests_trimesh_circulator_face_halfedge.cc
|
unittests_trimesh_circulator_face_halfedge.cc
|
||||||
@@ -53,6 +56,7 @@ unittests_trimesh_circulator_vertex_vertex.cc
|
|||||||
unittests_trimesh_collapse.cc
|
unittests_trimesh_collapse.cc
|
||||||
unittests_trimesh_garbage_collection.cc
|
unittests_trimesh_garbage_collection.cc
|
||||||
unittests_trimesh_iterators.cc
|
unittests_trimesh_iterators.cc
|
||||||
|
unittests_trimesh_navigation.cc
|
||||||
unittests_trimesh_others.cc
|
unittests_trimesh_others.cc
|
||||||
unittests_trimesh_ranges.cc
|
unittests_trimesh_ranges.cc
|
||||||
unittests_trimesh_split.cc
|
unittests_trimesh_split.cc
|
||||||
|
|||||||
@@ -177,6 +177,10 @@ TEST_F(OpenMeshSmartHandles, SimpleNavigation)
|
|||||||
|
|
||||||
for (auto eh : mesh_.edges())
|
for (auto eh : mesh_.edges())
|
||||||
{
|
{
|
||||||
|
EXPECT_EQ(mesh_.halfedge_handle(eh), eh.halfedge()) << "halfedge of edge does not match";
|
||||||
|
EXPECT_EQ(mesh_.halfedge_handle(eh, 0), eh.halfedge(0)) << "halfedge 0 of edge does not match";
|
||||||
|
EXPECT_EQ(mesh_.halfedge_handle(eh, 1), eh.halfedge(1)) << "halfedge 1 of edge does not match";
|
||||||
|
EXPECT_EQ(mesh_.halfedge_handle(eh), eh.h()) << "halfedge of edge does not match";
|
||||||
EXPECT_EQ(mesh_.halfedge_handle(eh, 0), eh.h0()) << "halfedge 0 of edge does not match";
|
EXPECT_EQ(mesh_.halfedge_handle(eh, 0), eh.h0()) << "halfedge 0 of edge does not match";
|
||||||
EXPECT_EQ(mesh_.halfedge_handle(eh, 1), eh.h1()) << "halfedge 1 of edge does not match";
|
EXPECT_EQ(mesh_.halfedge_handle(eh, 1), eh.h1()) << "halfedge 1 of edge does not match";
|
||||||
EXPECT_EQ(mesh_.from_vertex_handle(mesh_.halfedge_handle(eh, 0)), eh.v0()) << "first vertex of edge does not match";
|
EXPECT_EQ(mesh_.from_vertex_handle(mesh_.halfedge_handle(eh, 0)), eh.v0()) << "first vertex of edge does not match";
|
||||||
|
|||||||
62
src/Unittests/unittests_trimesh_circulator_edge.hh
Normal file
62
src/Unittests/unittests_trimesh_circulator_edge.hh
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#include <Unittests/unittests_common.hh>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class OpenMeshTrimeshCirculatorEdge : public OpenMeshBase {
|
||||||
|
public:
|
||||||
|
using VH = OpenMesh::VertexHandle;
|
||||||
|
using FH = OpenMesh::FaceHandle;
|
||||||
|
using EH = OpenMesh::EdgeHandle;
|
||||||
|
using HEH = OpenMesh::HalfedgeHandle;
|
||||||
|
|
||||||
|
// This function is called before each test is run.
|
||||||
|
void SetUp() override {
|
||||||
|
std::vector<VH> vh;
|
||||||
|
|
||||||
|
// 3----2 5
|
||||||
|
// | /| |
|
||||||
|
// | / | |
|
||||||
|
// | / | |
|
||||||
|
// |/ | |
|
||||||
|
// 0----1 4
|
||||||
|
|
||||||
|
// A quad consisting of two triangles.
|
||||||
|
vh.push_back(mesh_.add_vertex({0.0, 0.0, 0.0})); // vh[0]
|
||||||
|
vh.push_back(mesh_.add_vertex({1.0, 0.0, 0.0})); // vh[1]
|
||||||
|
vh.push_back(mesh_.add_vertex({1.0, 1.0, 0.0})); // vh[2]
|
||||||
|
vh.push_back(mesh_.add_vertex({0.0, 1.0, 0.0})); // vh[3]
|
||||||
|
mesh_.add_face(vh[0], vh[1], vh[2]);
|
||||||
|
mesh_.add_face(vh[0], vh[2], vh[3]);
|
||||||
|
|
||||||
|
// An isolated edge.
|
||||||
|
vh.push_back(mesh_.add_vertex({2.0, 0.0, 0.0})); // vh[4]
|
||||||
|
vh.push_back(mesh_.add_vertex({2.0, 1.0, 0.0})); // vh[5]
|
||||||
|
auto heh = mesh_.new_edge(vh[4], vh[5]);
|
||||||
|
auto heh_opp = mesh_.opposite_halfedge_handle(heh);
|
||||||
|
mesh_.set_halfedge_handle(vh[4], heh);
|
||||||
|
mesh_.set_halfedge_handle(vh[5], heh_opp);
|
||||||
|
|
||||||
|
InteriorEdge = Edge(0, 2);
|
||||||
|
BoundaryEdge = Edge(0, 1);
|
||||||
|
IsolatedEdge = Edge(4, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to quickly retrieve edges from their endpoint vertex IDs.
|
||||||
|
EH Edge(int _vh0_idx, int _vh1_idx) {
|
||||||
|
VH vh0(_vh0_idx);
|
||||||
|
VH vh1(_vh1_idx);
|
||||||
|
HEH heh = mesh_.find_halfedge(vh0, vh1);
|
||||||
|
if (!heh.is_valid())
|
||||||
|
return EH();
|
||||||
|
return mesh_.edge_handle(heh);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles of some interesting edges.
|
||||||
|
EH InteriorEdge;
|
||||||
|
EH BoundaryEdge;
|
||||||
|
EH IsolatedEdge;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
142
src/Unittests/unittests_trimesh_circulator_edge_face.cc
Normal file
142
src/Unittests/unittests_trimesh_circulator_edge_face.cc
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
#include "unittests_trimesh_circulator_edge.hh"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <Unittests/unittests_common.hh>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class OpenMeshTrimeshCirculatorEdgeFace : public OpenMeshTrimeshCirculatorEdge {
|
||||||
|
public:
|
||||||
|
// Check that the _visited faces comply with the expected iteration order on _eh.
|
||||||
|
void CheckIteration(EH _eh, const std::vector<FH>& _visited) {
|
||||||
|
// Up to 2 elements, depending on whether incident faces exist.
|
||||||
|
ASSERT_TRUE(mesh_.is_valid_handle(_eh));
|
||||||
|
const auto eh = make_smart(_eh, mesh_);
|
||||||
|
std::vector<FH> expected;
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
const auto fh = eh.halfedge(i).face();
|
||||||
|
if (fh.is_valid()) {
|
||||||
|
expected.push_back(fh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Elements must have been visited in the expected order.
|
||||||
|
ASSERT_EQ(_visited.size(), expected.size());
|
||||||
|
for (size_t i = 0; i < _visited.size(); ++i) {
|
||||||
|
EXPECT_EQ(_visited[i], expected[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mutable mesh.
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeFace, Iter) {
|
||||||
|
for (auto eh : mesh_.edges()) {
|
||||||
|
std::vector<FH> visited;
|
||||||
|
for (auto it = mesh_.ef_iter(eh); it.is_valid(); ++it) {
|
||||||
|
visited.push_back(*it);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeFace, BeginEnd) {
|
||||||
|
for (auto eh : mesh_.edges()) {
|
||||||
|
std::vector<FH> visited;
|
||||||
|
for (auto it = mesh_.ef_begin(eh), end = mesh_.ef_end(eh); it != end; ++it) {
|
||||||
|
visited.push_back(*it);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeFace, Range) {
|
||||||
|
for (auto eh : mesh_.edges()) {
|
||||||
|
std::vector<FH> visited;
|
||||||
|
for (auto fh : mesh_.ef_range(eh)) {
|
||||||
|
visited.push_back(fh);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeFace, SmartHandleRange) {
|
||||||
|
for (auto eh : mesh_.edges()) {
|
||||||
|
std::vector<FH> visited;
|
||||||
|
auto smart_eh = make_smart(eh, mesh_);
|
||||||
|
for (auto fh : smart_eh.faces()) {
|
||||||
|
visited.push_back(fh);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// const mesh.
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeFace, ConstIter) {
|
||||||
|
const auto& const_mesh = mesh_;
|
||||||
|
for (auto eh : const_mesh.edges()) {
|
||||||
|
std::vector<FH> visited;
|
||||||
|
for (auto it = const_mesh.cef_iter(eh); it.is_valid(); ++it) {
|
||||||
|
visited.push_back(*it);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeFace, ConstBeginEnd) {
|
||||||
|
const auto& const_mesh = mesh_;
|
||||||
|
for (auto eh : const_mesh.edges()) {
|
||||||
|
std::vector<FH> visited;
|
||||||
|
for (auto it = const_mesh.cef_begin(eh), end = const_mesh.cef_end(eh); it != end; ++it) {
|
||||||
|
visited.push_back(*it);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeFace, ConstRange) {
|
||||||
|
const auto& const_mesh = mesh_;
|
||||||
|
for (auto eh : const_mesh.edges()) {
|
||||||
|
std::vector<FH> visited;
|
||||||
|
for (auto fh : const_mesh.ef_range(eh)) {
|
||||||
|
visited.push_back(fh);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeFace, ConstSmartHandleRange) {
|
||||||
|
const auto& const_mesh = mesh_;
|
||||||
|
for (auto eh : const_mesh.edges()) {
|
||||||
|
std::vector<FH> visited;
|
||||||
|
auto smart_eh = make_smart(eh, const_mesh);
|
||||||
|
for (auto fh : smart_eh.faces()) {
|
||||||
|
visited.push_back(fh);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expected number of faces for interior, boundary, isolated edges.
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeFace, ExpectedNumber) {
|
||||||
|
std::vector<std::pair<EH, int>> pairs = {
|
||||||
|
{ InteriorEdge, 2 },
|
||||||
|
{ BoundaryEdge, 1 },
|
||||||
|
{ IsolatedEdge, 0 },
|
||||||
|
};
|
||||||
|
for (const auto& pair : pairs) {
|
||||||
|
const auto& eh = pair.first;
|
||||||
|
const auto& expected_faces = pair.second;
|
||||||
|
int visited_faces = 0;
|
||||||
|
for (auto fh : mesh_.ef_range(eh)) {
|
||||||
|
(void)fh; // Unused
|
||||||
|
++visited_faces;
|
||||||
|
}
|
||||||
|
EXPECT_EQ(visited_faces, expected_faces);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
184
src/Unittests/unittests_trimesh_circulator_edge_halfedge.cc
Normal file
184
src/Unittests/unittests_trimesh_circulator_edge_halfedge.cc
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
#include "unittests_trimesh_circulator_edge.hh"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <Unittests/unittests_common.hh>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class OpenMeshTrimeshCirculatorEdgeHalfedge : public OpenMeshTrimeshCirculatorEdge {
|
||||||
|
public:
|
||||||
|
// Check that the _visited halfedges comply with the expected iteration order on _eh.
|
||||||
|
void CheckIteration(EH _eh, const std::vector<HEH>& _visited) {
|
||||||
|
ASSERT_TRUE(mesh_.is_valid_handle(_eh));
|
||||||
|
const auto eh = make_smart(_eh, mesh_);
|
||||||
|
std::vector<HEH> expected;
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
expected.push_back(eh.halfedge(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Elements must have been visited in the expected order.
|
||||||
|
ASSERT_EQ(_visited.size(), expected.size());
|
||||||
|
for (size_t i = 0; i < _visited.size(); ++i) {
|
||||||
|
EXPECT_EQ(_visited[i], expected[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that the _visited halfedges comply with the expected iteration order on _heh.edge(), starting at _heh.
|
||||||
|
void CheckIteration(HEH _heh, const std::vector<HEH>& _visited) {
|
||||||
|
// Always exactly 2 elements.
|
||||||
|
ASSERT_TRUE(mesh_.is_valid_handle(_heh));
|
||||||
|
std::vector<HEH> expected;
|
||||||
|
expected.push_back(_heh);
|
||||||
|
expected.push_back(mesh_.opposite_halfedge_handle(_heh));
|
||||||
|
|
||||||
|
// Elements must have been visited in the expected order.
|
||||||
|
ASSERT_EQ(_visited.size(), expected.size());
|
||||||
|
for (size_t i = 0; i < _visited.size(); ++i) {
|
||||||
|
EXPECT_EQ(_visited[i], expected[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mutable mesh.
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeHalfedge, Iter) {
|
||||||
|
for (auto eh : mesh_.edges()) {
|
||||||
|
std::vector<HEH> visited;
|
||||||
|
for (auto it = mesh_.eh_iter(eh); it.is_valid(); ++it) {
|
||||||
|
visited.push_back(*it);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeHalfedge, BeginEnd) {
|
||||||
|
for (auto eh : mesh_.edges()) {
|
||||||
|
std::vector<HEH> visited;
|
||||||
|
for (auto it = mesh_.eh_begin(eh), end = mesh_.eh_end(eh); it != end; ++it) {
|
||||||
|
visited.push_back(*it);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeHalfedge, Range) {
|
||||||
|
for (auto eh : mesh_.edges()) {
|
||||||
|
std::vector<HEH> visited;
|
||||||
|
for (auto vh : mesh_.eh_range(eh)) {
|
||||||
|
visited.push_back(vh);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeHalfedge, SmartHandleRange) {
|
||||||
|
for (auto eh : mesh_.edges()) {
|
||||||
|
std::vector<HEH> visited;
|
||||||
|
auto smart_eh = make_smart(eh, mesh_);
|
||||||
|
for (auto vh : smart_eh.halfedges()) {
|
||||||
|
visited.push_back(vh);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// const mesh.
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeHalfedge, ConstIter) {
|
||||||
|
const auto& const_mesh = mesh_;
|
||||||
|
for (auto eh : const_mesh.edges()) {
|
||||||
|
std::vector<HEH> visited;
|
||||||
|
for (auto it = const_mesh.ceh_iter(eh); it.is_valid(); ++it) {
|
||||||
|
visited.push_back(*it);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeHalfedge, ConstBeginEnd) {
|
||||||
|
const auto& const_mesh = mesh_;
|
||||||
|
for (auto eh : const_mesh.edges()) {
|
||||||
|
std::vector<HEH> visited;
|
||||||
|
for (auto it = const_mesh.ceh_begin(eh), end = const_mesh.ceh_end(eh); it != end; ++it) {
|
||||||
|
visited.push_back(*it);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeHalfedge, ConstRange) {
|
||||||
|
const auto& const_mesh = mesh_;
|
||||||
|
for (auto eh : const_mesh.edges()) {
|
||||||
|
std::vector<HEH> visited;
|
||||||
|
for (auto vh : const_mesh.eh_range(eh)) {
|
||||||
|
visited.push_back(vh);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeHalfedge, ConstSmartHandleRange) {
|
||||||
|
const auto& const_mesh = mesh_;
|
||||||
|
for (auto eh : const_mesh.edges()) {
|
||||||
|
std::vector<HEH> visited;
|
||||||
|
auto smart_eh = make_smart(eh, const_mesh);
|
||||||
|
for (auto vh : smart_eh.halfedges()) {
|
||||||
|
visited.push_back(vh);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutable mesh, with given start halfedge.
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeHalfedge, InitializedRange) {
|
||||||
|
for (auto start_heh : mesh_.halfedges()) {
|
||||||
|
std::vector<HEH> visited;
|
||||||
|
for (auto vh : mesh_.eh_range(start_heh)) {
|
||||||
|
visited.push_back(vh);
|
||||||
|
}
|
||||||
|
CheckIteration(start_heh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeHalfedge, InitializedSmartHandleRange) {
|
||||||
|
for (auto start_heh : mesh_.halfedges()) {
|
||||||
|
std::vector<HEH> visited;
|
||||||
|
auto smart_start_heh = make_smart(start_heh, mesh_);
|
||||||
|
auto smart_start_eh = smart_start_heh.edge();
|
||||||
|
for (auto vh : smart_start_eh.halfedges(smart_start_heh)) {
|
||||||
|
visited.push_back(vh);
|
||||||
|
}
|
||||||
|
CheckIteration(start_heh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// const mesh, with given start halfedge.
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeHalfedge, ConstInitializedRange) {
|
||||||
|
const auto& const_mesh = mesh_;
|
||||||
|
for (auto start_heh : const_mesh.halfedges()) {
|
||||||
|
std::vector<HEH> visited;
|
||||||
|
for (auto vh : mesh_.eh_range(start_heh)) {
|
||||||
|
visited.push_back(vh);
|
||||||
|
}
|
||||||
|
CheckIteration(start_heh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeHalfedge, ConstInitializedSmartHandleRange) {
|
||||||
|
const auto& const_mesh = mesh_;
|
||||||
|
for (auto start_heh : const_mesh.halfedges()) {
|
||||||
|
std::vector<HEH> visited;
|
||||||
|
auto smart_start_heh = make_smart(start_heh, const_mesh);
|
||||||
|
auto smart_start_eh = smart_start_heh.edge();
|
||||||
|
for (auto vh : smart_start_eh.halfedges(smart_start_heh)) {
|
||||||
|
visited.push_back(vh);
|
||||||
|
}
|
||||||
|
CheckIteration(start_heh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
119
src/Unittests/unittests_trimesh_circulator_edge_vertex.cc
Normal file
119
src/Unittests/unittests_trimesh_circulator_edge_vertex.cc
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
#include "unittests_trimesh_circulator_edge.hh"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <Unittests/unittests_common.hh>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class OpenMeshTrimeshCirculatorEdgeVertex : public OpenMeshTrimeshCirculatorEdge {
|
||||||
|
public:
|
||||||
|
// Check that the _visited vertices comply with the expected iteration order on _eh.
|
||||||
|
void CheckIteration(EH _eh, const std::vector<VH>& _visited) {
|
||||||
|
ASSERT_TRUE(mesh_.is_valid_handle(_eh));
|
||||||
|
const auto eh = make_smart(_eh, mesh_);
|
||||||
|
std::vector<VH> expected;
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
expected.push_back(eh.vertex(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Elements must have been visited in the expected order.
|
||||||
|
ASSERT_EQ(_visited.size(), expected.size());
|
||||||
|
for (size_t i = 0; i < _visited.size(); ++i) {
|
||||||
|
EXPECT_EQ(_visited[i], expected[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mutable mesh.
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeVertex, Iter) {
|
||||||
|
for (auto eh : mesh_.edges()) {
|
||||||
|
std::vector<VH> visited;
|
||||||
|
for (auto it = mesh_.ev_iter(eh); it.is_valid(); ++it) {
|
||||||
|
visited.push_back(*it);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeVertex, BeginEnd) {
|
||||||
|
for (auto eh : mesh_.edges()) {
|
||||||
|
std::vector<VH> visited;
|
||||||
|
for (auto it = mesh_.ev_begin(eh), end = mesh_.ev_end(eh); it != end; ++it) {
|
||||||
|
visited.push_back(*it);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeVertex, Range) {
|
||||||
|
for (auto eh : mesh_.edges()) {
|
||||||
|
std::vector<VH> visited;
|
||||||
|
for (auto vh : mesh_.ev_range(eh)) {
|
||||||
|
visited.push_back(vh);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeVertex, SmartHandleRange) {
|
||||||
|
for (auto eh : mesh_.edges()) {
|
||||||
|
std::vector<VH> visited;
|
||||||
|
auto smart_eh = make_smart(eh, mesh_);
|
||||||
|
for (auto vh : smart_eh.vertices()) {
|
||||||
|
visited.push_back(vh);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// const mesh.
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeVertex, ConstIter) {
|
||||||
|
const auto& const_mesh = mesh_;
|
||||||
|
for (auto eh : const_mesh.edges()) {
|
||||||
|
std::vector<VH> visited;
|
||||||
|
for (auto it = const_mesh.cev_iter(eh); it.is_valid(); ++it) {
|
||||||
|
visited.push_back(*it);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeVertex, ConstBeginEnd) {
|
||||||
|
const auto& const_mesh = mesh_;
|
||||||
|
for (auto eh : const_mesh.edges()) {
|
||||||
|
std::vector<VH> visited;
|
||||||
|
for (auto it = const_mesh.cev_begin(eh), end = const_mesh.cev_end(eh); it != end; ++it) {
|
||||||
|
visited.push_back(*it);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeVertex, ConstRange) {
|
||||||
|
const auto& const_mesh = mesh_;
|
||||||
|
for (auto eh : const_mesh.edges()) {
|
||||||
|
std::vector<VH> visited;
|
||||||
|
for (auto vh : const_mesh.ev_range(eh)) {
|
||||||
|
visited.push_back(vh);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshCirculatorEdgeVertex, ConstSmartHandleRange) {
|
||||||
|
const auto& const_mesh = mesh_;
|
||||||
|
for (auto eh : const_mesh.edges()) {
|
||||||
|
std::vector<VH> visited;
|
||||||
|
auto smart_eh = make_smart(eh, const_mesh);
|
||||||
|
for (auto vh : smart_eh.vertices()) {
|
||||||
|
visited.push_back(vh);
|
||||||
|
}
|
||||||
|
CheckIteration(eh, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
42
src/Unittests/unittests_trimesh_navigation.cc
Normal file
42
src/Unittests/unittests_trimesh_navigation.cc
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#include <Unittests/unittests_common.hh>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class OpenMeshTrimeshNavigation : public OpenMeshBase {
|
||||||
|
public:
|
||||||
|
using VH = OpenMesh::VertexHandle;
|
||||||
|
using FH = OpenMesh::FaceHandle;
|
||||||
|
using EH = OpenMesh::EdgeHandle;
|
||||||
|
using HEH = OpenMesh::HalfedgeHandle;
|
||||||
|
|
||||||
|
// This function is called before each test is run.
|
||||||
|
void SetUp() override {
|
||||||
|
std::vector<VH> vh;
|
||||||
|
|
||||||
|
// 3----2
|
||||||
|
// | /|
|
||||||
|
// | / |
|
||||||
|
// | / |
|
||||||
|
// |/ |
|
||||||
|
// 0----1
|
||||||
|
|
||||||
|
vh.push_back(mesh_.add_vertex({0.0, 0.0, 0.0})); // vh[0]
|
||||||
|
vh.push_back(mesh_.add_vertex({1.0, 0.0, 0.0})); // vh[1]
|
||||||
|
vh.push_back(mesh_.add_vertex({1.0, 1.0, 0.0})); // vh[2]
|
||||||
|
vh.push_back(mesh_.add_vertex({0.0, 1.0, 0.0})); // vh[3]
|
||||||
|
mesh_.add_face(vh[0], vh[1], vh[2]);
|
||||||
|
mesh_.add_face(vh[0], vh[2], vh[3]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(OpenMeshTrimeshNavigation, EdgeHalfedgeDefault) {
|
||||||
|
for (EH eh : mesh_.edges()) {
|
||||||
|
EXPECT_EQ(mesh_.halfedge_handle(eh), mesh_.halfedge_handle(eh, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user