From 253c9b6afa272924bc1cd7f80bbf54bed9e74e12 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 26 Sep 2019 11:14:31 +0200 Subject: [PATCH] let iterators return smart handles --- src/OpenMesh/Core/Mesh/IteratorsT.hh | 33 ++++++------ src/OpenMesh/Core/Mesh/PolyConnectivity.cc | 40 +++++++++++++++ src/OpenMesh/Core/Mesh/PolyConnectivity.hh | 33 ++++++------ src/OpenMesh/Core/Mesh/SmartHandles.hh | 5 +- src/Unittests/unittests_smart_handles.cc | 58 ++++++++++------------ 5 files changed, 97 insertions(+), 72 deletions(-) diff --git a/src/OpenMesh/Core/Mesh/IteratorsT.hh b/src/OpenMesh/Core/Mesh/IteratorsT.hh index 3ce98609..72621575 100644 --- a/src/OpenMesh/Core/Mesh/IteratorsT.hh +++ b/src/OpenMesh/Core/Mesh/IteratorsT.hh @@ -40,9 +40,7 @@ * ========================================================================= */ - -#ifndef OPENMESH_ITERATORS_HH -#define OPENMESH_ITERATORS_HH +#pragma once //============================================================================= // @@ -56,6 +54,7 @@ #include #include +#include #include #include #include @@ -89,19 +88,20 @@ class GenericIteratorT { typedef value_handle value_type; typedef std::bidirectional_iterator_tag iterator_category; typedef std::ptrdiff_t difference_type; - typedef const value_type& reference; - typedef const value_type* pointer; typedef const Mesh* mesh_ptr; typedef const Mesh& mesh_ref; + typedef decltype(make_smart(std::declval(), std::declval())) SmartHandle; + typedef const SmartHandle& reference; + typedef const SmartHandle* pointer; /// Default constructor. GenericIteratorT() - : mesh_(0), skip_bits_(0) + : hnd_(make_smart(ValueHandle(),nullptr)), skip_bits_(0) {} /// Construct with mesh and a target handle. GenericIteratorT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) - : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) + : hnd_(make_smart(_hnd, _mesh)), skip_bits_(0) { if (_skip) enable_skipping(); } @@ -139,7 +139,7 @@ class GenericIteratorT { /// Are two iterators equal? Only valid if they refer to the same mesh! bool operator==(const GenericIteratorT& _rhs) const { - return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); + return ((hnd_.mesh() == _rhs.hnd_.mesh()) && (hnd_ == _rhs.hnd_)); } /// Not equal? @@ -210,7 +210,7 @@ class GenericIteratorT { /// Turn on skipping: automatically skip deleted/hidden elements void enable_skipping() { - if (mesh_ && (mesh_->*PrimitiveStatusMember)()) { + if (hnd_.mesh() && (hnd_.mesh()->*PrimitiveStatusMember)()) { Attributes::StatusInfo status; status.set_deleted(true); status.set_hidden(true); @@ -228,21 +228,20 @@ class GenericIteratorT { private: void skip_fwd() { - assert(mesh_ && skip_bits_); - while ((hnd_.idx() < (signed) (mesh_->*PrimitiveCountMember)()) - && (mesh_->status(hnd_).bits() & skip_bits_)) + assert(hnd_.mesh() && skip_bits_); + while ((hnd_.idx() < (signed) (hnd_.mesh()->*PrimitiveCountMember)()) + && (hnd_.mesh()->status(hnd_).bits() & skip_bits_)) hnd_.__increment(); } void skip_bwd() { - assert(mesh_ && skip_bits_); - while ((hnd_.idx() >= 0) && (mesh_->status(hnd_).bits() & skip_bits_)) + assert(hnd_.mesh() && skip_bits_); + while ((hnd_.idx() >= 0) && (hnd_.mesh()->status(hnd_).bits() & skip_bits_)) hnd_.__decrement(); } protected: - mesh_ptr mesh_; - value_handle hnd_; + SmartHandle hnd_; unsigned int skip_bits_; }; @@ -250,5 +249,3 @@ class GenericIteratorT { } // namespace Iterators } // namespace OpenMesh //============================================================================= -#endif -//============================================================================= diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.cc b/src/OpenMesh/Core/Mesh/PolyConnectivity.cc index 521f00e6..27c264d5 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.cc +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.cc @@ -719,6 +719,46 @@ PolyConnectivity::ConstFaceIter PolyConnectivity::faces_end() const return ConstFaceIter(*this, FaceHandle(int(n_faces()))); } +PolyConnectivity::VertexIter PolyConnectivity::vertices_sbegin() +{ + return VertexIter(*this, VertexHandle(0), true); +} + +PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_sbegin() const +{ + return ConstVertexIter(*this, VertexHandle(0), true); +} + +PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_sbegin() +{ + return HalfedgeIter(*this, HalfedgeHandle(0), true); +} + +PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_sbegin() const +{ + return ConstHalfedgeIter(*this, HalfedgeHandle(0), true); +} + +PolyConnectivity::EdgeIter PolyConnectivity::edges_sbegin() +{ + return EdgeIter(*this, EdgeHandle(0), true); +} + +PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_sbegin() const +{ + return ConstEdgeIter(*this, EdgeHandle(0), true); +} + +PolyConnectivity::FaceIter PolyConnectivity::faces_sbegin() +{ + return FaceIter(*this, FaceHandle(0), true); +} + +PolyConnectivity::ConstFaceIter PolyConnectivity::faces_sbegin() const +{ + return ConstFaceIter(*this, FaceHandle(0), true); +} + //----------------------------------------------------------------------------- void PolyConnectivity::collapse(HalfedgeHandle _hh) { diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh index 78e8a3f9..9d6aaca0 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh @@ -45,12 +45,17 @@ #define OPENMESH_POLYCONNECTIVITY_HH #include -#include #include namespace OpenMesh { +namespace Iterators +{ + template + class GenericIteratorT; +} + /** \brief Connectivity Class for polygonal meshes */ class OPENMESHDLLEXPORT PolyConnectivity : public ArrayKernel @@ -532,32 +537,24 @@ public: //@{ /// Begin iterator for vertices - VertexIter vertices_sbegin() - { return VertexIter(*this, VertexHandle(0), true); } + VertexIter vertices_sbegin(); /// Const begin iterator for vertices - ConstVertexIter vertices_sbegin() const - { return ConstVertexIter(*this, VertexHandle(0), true); } + ConstVertexIter vertices_sbegin() const; /// Begin iterator for halfedges - HalfedgeIter halfedges_sbegin() - { return HalfedgeIter(*this, HalfedgeHandle(0), true); } + HalfedgeIter halfedges_sbegin(); /// Const begin iterator for halfedges - ConstHalfedgeIter halfedges_sbegin() const - { return ConstHalfedgeIter(*this, HalfedgeHandle(0), true); } + ConstHalfedgeIter halfedges_sbegin() const; /// Begin iterator for edges - EdgeIter edges_sbegin() - { return EdgeIter(*this, EdgeHandle(0), true); } + EdgeIter edges_sbegin(); /// Const begin iterator for edges - ConstEdgeIter edges_sbegin() const - { return ConstEdgeIter(*this, EdgeHandle(0), true); } + ConstEdgeIter edges_sbegin() const; /// Begin iterator for faces - FaceIter faces_sbegin() - { return FaceIter(*this, FaceHandle(0), true); } + FaceIter faces_sbegin(); /// Const begin iterator for faces - ConstFaceIter faces_sbegin() const - { return ConstFaceIter(*this, FaceHandle(0), true); } + ConstFaceIter faces_sbegin() const; //@} @@ -1627,4 +1624,6 @@ private: // Working storage for add_face() }//namespace OpenMesh +#include + #endif//OPENMESH_POLYCONNECTIVITY_HH diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.hh b/src/OpenMesh/Core/Mesh/SmartHandles.hh index 5c671185..5655ffe4 100644 --- a/src/OpenMesh/Core/Mesh/SmartHandles.hh +++ b/src/OpenMesh/Core/Mesh/SmartHandles.hh @@ -40,8 +40,7 @@ * ========================================================================= */ -#ifndef OPENMESH_SMARTHANDLES_HH -#define OPENMESH_SMARTHANDLES_HH +#pragma once //== INCLUDES ================================================================= @@ -401,6 +400,4 @@ inline bool SmartFaceHandle::is_boundary() const } // namespace OpenMesh //============================================================================= - -#endif // OPENMESH_SMARTHANDLES_HH //============================================================================= diff --git a/src/Unittests/unittests_smart_handles.cc b/src/Unittests/unittests_smart_handles.cc index fc7d4978..3ddb5fbe 100644 --- a/src/Unittests/unittests_smart_handles.cc +++ b/src/Unittests/unittests_smart_handles.cc @@ -162,34 +162,30 @@ TEST_F(OpenMeshSmartHandles, SimpleNavigation) { for (auto vh : mesh_.vertices()) { - auto svh = OpenMesh::make_smart(vh, mesh_); - EXPECT_EQ(mesh_.halfedge_handle(vh), svh.halfedge()) << "outgoing halfedge of vertex does not match"; + EXPECT_EQ(mesh_.halfedge_handle(vh), vh.halfedge()) << "outgoing halfedge of vertex does not match"; } for (auto heh : mesh_.halfedges()) { - auto sheh = OpenMesh::make_smart(heh, mesh_); - EXPECT_EQ(mesh_.next_halfedge_handle(heh), sheh.next()) << "next halfedge of halfedge does not match"; - EXPECT_EQ(mesh_.prev_halfedge_handle(heh), sheh.prev()) << "prevt halfedge of halfedge does not match"; - EXPECT_EQ(mesh_.opposite_halfedge_handle(heh), sheh.opp()) << "opposite halfedge of halfedge does not match"; - EXPECT_EQ(mesh_.to_vertex_handle(heh), sheh.to()) << "to vertex handle of halfedge does not match"; - EXPECT_EQ(mesh_.from_vertex_handle(heh), sheh.from()) << "from vertex handle of halfedge does not match"; - EXPECT_EQ(mesh_.face_handle(heh), sheh.face()) << "face handle of halfedge does not match"; + EXPECT_EQ(mesh_.next_halfedge_handle(heh), heh.next()) << "next halfedge of halfedge does not match"; + EXPECT_EQ(mesh_.prev_halfedge_handle(heh), heh.prev()) << "prevt halfedge of halfedge does not match"; + EXPECT_EQ(mesh_.opposite_halfedge_handle(heh), heh.opp()) << "opposite halfedge of halfedge does not match"; + EXPECT_EQ(mesh_.to_vertex_handle(heh), heh.to()) << "to vertex handle of halfedge does not match"; + EXPECT_EQ(mesh_.from_vertex_handle(heh), heh.from()) << "from vertex handle of halfedge does not match"; + EXPECT_EQ(mesh_.face_handle(heh), heh.face()) << "face handle of halfedge does not match"; } for (auto eh : mesh_.edges()) { - auto seh = OpenMesh::make_smart(eh, mesh_); - EXPECT_EQ(mesh_.halfedge_handle(eh, 0), seh.h0()) << "halfedge 0 of edge does not match"; - EXPECT_EQ(mesh_.halfedge_handle(eh, 1), seh.h1()) << "halfedge 1 of edge does not match"; - EXPECT_EQ(mesh_.from_vertex_handle(mesh_.halfedge_handle(eh, 0)), seh.v0()) << "first vertex of edge does not match"; - EXPECT_EQ(mesh_.to_vertex_handle (mesh_.halfedge_handle(eh, 0)), seh.v1()) << "second vertex 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_.from_vertex_handle(mesh_.halfedge_handle(eh, 0)), eh.v0()) << "first vertex of edge does not match"; + EXPECT_EQ(mesh_.to_vertex_handle (mesh_.halfedge_handle(eh, 0)), eh.v1()) << "second vertex of edge does not match"; } for (auto fh : mesh_.faces()) { - auto sfh = OpenMesh::make_smart(fh, mesh_); - EXPECT_EQ(mesh_.halfedge_handle(fh), sfh.halfedge()) << "halfedge of face does not match"; + EXPECT_EQ(mesh_.halfedge_handle(fh), fh.halfedge()) << "halfedge of face does not match"; } } @@ -200,13 +196,12 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) { for (auto vh : mesh_.vertices()) { - auto svh = OpenMesh::make_smart(vh, mesh_); { std::vector handles0; std::vector handles1; for (auto h : mesh_.vv_range(vh)) handles0.push_back(h); - for (auto h : svh.vertices()) + for (auto h : vh.vertices()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "vertex range of vertex does not match"; } @@ -215,7 +210,7 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) std::vector handles1; for (auto h : mesh_.voh_range(vh)) handles0.push_back(h); - for (auto h : svh.outgoing_halfedges()) + for (auto h : vh.outgoing_halfedges()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "outgoing halfedge range of vertex does not match"; } @@ -224,7 +219,7 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) std::vector handles1; for (auto h : mesh_.vih_range(vh)) handles0.push_back(h); - for (auto h : svh.incoming_halfedges()) + for (auto h : vh.incoming_halfedges()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "incoming halfedge range of vertex does not match"; } @@ -233,7 +228,7 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) std::vector handles1; for (auto h : mesh_.ve_range(vh)) handles0.push_back(h); - for (auto h : svh.edges()) + for (auto h : vh.edges()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "edge range of vertex does not match"; } @@ -242,7 +237,7 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) std::vector handles1; for (auto h : mesh_.vf_range(vh)) handles0.push_back(h); - for (auto h : svh.faces()) + for (auto h : vh.faces()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "face range of vertex does not match"; } @@ -250,13 +245,12 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) for (auto fh : mesh_.faces()) { - auto sfh = OpenMesh::make_smart(fh, mesh_); { std::vector handles0; std::vector handles1; for (auto h : mesh_.fv_range(fh)) handles0.push_back(h); - for (auto h : sfh.vertices()) + for (auto h : fh.vertices()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "vertex range of face does not match"; } @@ -265,7 +259,7 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) std::vector handles1; for (auto h : mesh_.fh_range(fh)) handles0.push_back(h); - for (auto h : sfh.halfedges()) + for (auto h : fh.halfedges()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "halfedge range of face does not match"; } @@ -274,7 +268,7 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) std::vector handles1; for (auto h : mesh_.fe_range(fh)) handles0.push_back(h); - for (auto h : sfh.edges()) + for (auto h : fh.edges()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "edge range of face does not match"; } @@ -283,7 +277,7 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) std::vector handles1; for (auto h : mesh_.ff_range(fh)) handles0.push_back(h); - for (auto h : sfh.faces()) + for (auto h : fh.faces()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "face range of face does not match"; } @@ -297,18 +291,17 @@ TEST_F(OpenMeshSmartHandles, ComplicatedNavigtaion) { for (auto vh : mesh_.vertices()) { - auto svh = OpenMesh::make_smart(vh, mesh_); EXPECT_EQ(mesh_.next_halfedge_handle( mesh_.opposite_halfedge_handle( mesh_.halfedge_handle(vh))), - svh.out().opp().next()); + vh.out().opp().next()); EXPECT_EQ(mesh_.prev_halfedge_handle( mesh_.prev_halfedge_handle( mesh_.opposite_halfedge_handle( mesh_.next_halfedge_handle( mesh_.next_halfedge_handle( mesh_.halfedge_handle(vh)))))), - svh.out().next().next().opp().prev().prev()); + vh.out().next().next().opp().prev().prev()); EXPECT_EQ(mesh_.face_handle( mesh_.opposite_halfedge_handle( mesh_.halfedge_handle( @@ -316,7 +309,7 @@ TEST_F(OpenMeshSmartHandles, ComplicatedNavigtaion) mesh_.opposite_halfedge_handle( mesh_.next_halfedge_handle( mesh_.halfedge_handle(vh))))))), - svh.out().next().opp().face().halfedge().opp().face()); + vh.out().next().opp().face().halfedge().opp().face()); } } @@ -352,8 +345,7 @@ TEST_F(OpenMeshSmartHandles, Performance) { for (auto vh : mesh_.vertices()) { - auto svh = OpenMesh::make_smart(vh, mesh_); - auto heh = svh.out().next().next().opp().prev().prev(); + auto heh = vh.out().next().next().opp().prev().prev(); if (i == 0) halfedges1.push_back(heh); }