From 7c804acef17638a0873cc15f2a99a0cbfd5fa9b3 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Fri, 27 Sep 2019 17:08:09 +0200 Subject: [PATCH] for the cost of adding SmartHandles.cc with weird include order make smart ranges smarter by letting them know their smart handle types --- src/OpenMesh/Core/Mesh/PolyConnectivity.hh | 51 ++++----- src/OpenMesh/Core/Mesh/SmartHandles.cc | 115 +++++++++++++++++++++ src/OpenMesh/Core/Mesh/SmartHandles.hh | 63 ++--------- src/Unittests/unittests_smart_ranges.cc | 4 +- 4 files changed, 153 insertions(+), 80 deletions(-) create mode 100644 src/OpenMesh/Core/Mesh/SmartHandles.cc diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh index d8adcd15..85cfa102 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh @@ -82,6 +82,9 @@ struct RangeTraitT }; +template +class CirculatorRange; + template< typename CONTAINER_T, typename ITER_T, @@ -1098,29 +1101,6 @@ public: ConstFaceRange all_faces() const; - /// Generic class for iterator ranges. - template - class CirculatorRange : public SmartRangeT, typename CirculatorRangeTraitT::TO_ENTITYE_TYPE>{ - public: - typedef typename CirculatorRangeTraitT::ITER_TYPE ITER_TYPE; - typedef typename CirculatorRangeTraitT::CENTER_ENTITY_TYPE CENTER_ENTITY_TYPE; - typedef typename CirculatorRangeTraitT::CONTAINER_TYPE CONTAINER_TYPE; - typedef ITER_TYPE iterator; - typedef ITER_TYPE const_iterator; - - 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_); } - - private: - const CONTAINER_TYPE &container_; - CENTER_ENTITY_TYPE center_; - }; - - typedef CirculatorRange -class EntityRange : public SmartRangeT, typename RangeTraitT::ITER_TYPE::value_handle> { +class EntityRange : public SmartRangeT, typename RangeTraitT::ITER_TYPE::SmartHandle> { public: typedef typename RangeTraitT::ITER_TYPE iterator; typedef typename RangeTraitT::ITER_TYPE const_iterator; @@ -1520,6 +1500,29 @@ class EntityRange : public SmartRangeT, typename RangeT typename RangeTraitT::CONTAINER_TYPE &container_; }; +/// Generic class for iterator ranges. +template +//class CirculatorRange : public SmartRangeT, decltype (make_smart(std::declval(), std::declval()))>{ +class CirculatorRange : public SmartRangeT, typename SmartHandle::type>{ + public: + typedef typename CirculatorRangeTraitT::ITER_TYPE ITER_TYPE; + typedef typename CirculatorRangeTraitT::CENTER_ENTITY_TYPE CENTER_ENTITY_TYPE; + typedef typename CirculatorRangeTraitT::CONTAINER_TYPE CONTAINER_TYPE; + typedef ITER_TYPE iterator; + typedef ITER_TYPE const_iterator; + + 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_); } + + private: + const CONTAINER_TYPE &container_; + CENTER_ENTITY_TYPE center_; +}; + inline PolyConnectivity::ConstVertexRangeSkipping PolyConnectivity::vertices() const { return ConstVertexRangeSkipping(*this); } inline PolyConnectivity::ConstVertexRange PolyConnectivity::all_vertices() const { return ConstVertexRange(*this); } diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.cc b/src/OpenMesh/Core/Mesh/SmartHandles.cc new file mode 100644 index 00000000..a9156aa3 --- /dev/null +++ b/src/OpenMesh/Core/Mesh/SmartHandles.cc @@ -0,0 +1,115 @@ +/* ========================================================================= * + * * + * OpenMesh * + * Copyright (c) 2001-2019, RWTH-Aachen University * + * Department of Computer Graphics and Multimedia * + * All rights reserved. * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + *---------------------------------------------------------------------------* + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * 1. Redistributions of source code must retain the above copyright notice, * + * this list of conditions and the following disclaimer. * + * * + * 2. Redistributions in binary form must reproduce the above copyright * + * notice, this list of conditions and the following disclaimer in the * + * documentation and/or other materials provided with the distribution. * + * * + * 3. Neither the name of the copyright holder nor the names of its * + * contributors may be used to endorse or promote products derived from * + * this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * * + * ========================================================================= */ + + +//== INCLUDES ================================================================= + +#include +#include "SmartHandles.hh" + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { + +//TODO: I was not able to leave those in the header. If you find a way to do that, please do. + +PolyConnectivity::ConstVertexFaceRange SmartVertexHandle::faces() const +{ + assert(mesh() != nullptr); + return mesh()->vf_range(*this); +} + +PolyConnectivity::ConstVertexEdgeRange SmartVertexHandle::edges() const +{ + assert(mesh() != nullptr); + return mesh()->ve_range(*this); +} + +PolyConnectivity::ConstVertexVertexRange SmartVertexHandle::vertices() const +{ + assert(mesh() != nullptr); + return mesh()->vv_range(*this); +} + +PolyConnectivity::ConstVertexIHalfedgeRange SmartVertexHandle::incoming_halfedges() const +{ + assert(mesh() != nullptr); + return mesh()->vih_range(*this); +} + +PolyConnectivity::ConstVertexOHalfedgeRange SmartVertexHandle::outgoing_halfedges() const +{ + assert(mesh() != nullptr); + return mesh()->voh_range(*this); +} + + +PolyConnectivity::ConstFaceVertexRange SmartFaceHandle::vertices() const +{ + assert(mesh() != nullptr); + return mesh()->fv_range(*this); +} + +PolyConnectivity::ConstFaceHalfedgeRange SmartFaceHandle::halfedges() const +{ + assert(mesh() != nullptr); + return mesh()->fh_range(*this); +} + +PolyConnectivity::ConstFaceEdgeRange SmartFaceHandle::edges() const +{ + assert(mesh() != nullptr); + return mesh()->fe_range(*this); +} + +PolyConnectivity::ConstFaceFaceRange SmartFaceHandle::faces() const +{ + assert(mesh() != nullptr); + return mesh()->ff_range(*this); +} + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= + +//============================================================================= diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.hh b/src/OpenMesh/Core/Mesh/SmartHandles.hh index 5655ffe4..b444e1d7 100644 --- a/src/OpenMesh/Core/Mesh/SmartHandles.hh +++ b/src/OpenMesh/Core/Mesh/SmartHandles.hh @@ -198,6 +198,15 @@ inline SmartEdgeHandle make_smart(EdgeHandle _eh, const PolyConnectivity inline SmartFaceHandle make_smart(FaceHandle _fh, const PolyConnectivity& _mesh) { return SmartFaceHandle (_fh.idx(), &_mesh); } +// helper to convert Handle Types to Smarthandle Types +template +struct SmartHandle; + +template <> struct SmartHandle { using type = SmartVertexHandle; }; +template <> struct SmartHandle { using type = SmartHalfedgeHandle; }; +template <> struct SmartHandle { using type = SmartEdgeHandle; }; +template <> struct SmartHandle { using type = SmartFaceHandle; }; + inline SmartHalfedgeHandle SmartVertexHandle::out() const { @@ -215,36 +224,6 @@ inline SmartHalfedgeHandle SmartVertexHandle::in() const return out().opp(); } -inline PolyConnectivity::ConstVertexFaceRange SmartVertexHandle::faces() const -{ - assert(mesh() != nullptr); - return mesh()->vf_range(*this); -} - -inline PolyConnectivity::ConstVertexEdgeRange SmartVertexHandle::edges() const -{ - assert(mesh() != nullptr); - return mesh()->ve_range(*this); -} - -inline PolyConnectivity::ConstVertexVertexRange SmartVertexHandle::vertices() const -{ - assert(mesh() != nullptr); - return mesh()->vv_range(*this); -} - -inline PolyConnectivity::ConstVertexIHalfedgeRange SmartVertexHandle::incoming_halfedges() const -{ - assert(mesh() != nullptr); - return mesh()->vih_range(*this); -} - -inline PolyConnectivity::ConstVertexOHalfedgeRange SmartVertexHandle::outgoing_halfedges() const -{ - assert(mesh() != nullptr); - return mesh()->voh_range(*this); -} - inline uint SmartVertexHandle::valence() const { assert(mesh() != nullptr); @@ -358,30 +337,6 @@ inline SmartHalfedgeHandle SmartFaceHandle::halfedge() const return make_smart(mesh()->halfedge_handle(*this), mesh()); } -inline PolyConnectivity::ConstFaceVertexRange SmartFaceHandle::vertices() const -{ - assert(mesh() != nullptr); - return mesh()->fv_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::ConstFaceFaceRange SmartFaceHandle::faces() const -{ - assert(mesh() != nullptr); - return mesh()->ff_range(*this); -} - inline uint SmartFaceHandle::valence() const { assert(mesh() != nullptr); diff --git a/src/Unittests/unittests_smart_ranges.cc b/src/Unittests/unittests_smart_ranges.cc index 892c0c73..fe613952 100644 --- a/src/Unittests/unittests_smart_ranges.cc +++ b/src/Unittests/unittests_smart_ranges.cc @@ -224,8 +224,8 @@ TEST_F(OpenMeshSmartRanges, ToVector) { auto tri_uvs = fh.halfedges().to_vector(uvs); auto heh_handles = fh.halfedges().to_vector(); -// for (auto heh : heh_handles) -// auto n = heh.next(); + for (auto heh : heh_handles) + auto n = heh.next(); } auto vertex_vec = mesh_.vertices().to_vector();