From c23d410cb0479b9d36ca5702ece5ff4280a031d8 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Mon, 9 Mar 2020 18:43:09 +0100 Subject: [PATCH 1/4] add arg min and arg max methods to smart ranges --- src/OpenMesh/Core/Mesh/SmartRange.hh | 63 ++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/OpenMesh/Core/Mesh/SmartRange.hh b/src/OpenMesh/Core/Mesh/SmartRange.hh index 06e5192b..b827137a 100644 --- a/src/OpenMesh/Core/Mesh/SmartRange.hh +++ b/src/OpenMesh/Core/Mesh/SmartRange.hh @@ -250,6 +250,37 @@ struct SmartRangeT return res; } + /** @brief Compute minimal element. + * + * Computes the element that minimizes \p f. + * + * @param f Functor that is applied to all elements before comparing. + */ + template + auto argmin(Functor&& f) -> HandleT + { + auto range = static_cast(this); + auto it = range->begin(); + auto min_it = it; + auto end = range->end(); + assert(it != end); + + typename std::decay()))>::type curr_min = f(*it); + ++it; + + for (; it != end; ++it) + { + auto val = f(*it); + if (val < curr_min) + { + curr_min = val; + min_it = it; + } + } + + return *min_it; + } + /** @brief Compute maximum. * * Computes the maximum of all objects returned by functor \p f. @@ -275,6 +306,38 @@ struct SmartRangeT return res; } + + /** @brief Compute maximal element. + * + * Computes the element that maximizes \p f. + * + * @param f Functor that is applied to all elements before comparing. + */ + template + auto argmax(Functor&& f) -> HandleT + { + auto range = static_cast(this); + auto it = range->begin(); + auto max_it = it; + auto end = range->end(); + assert(it != end); + + typename std::decay()))>::type curr_max = f(*it); + ++it; + + for (; it != end; ++it) + { + auto val = f(*it); + if (val > curr_max) + { + curr_max = val; + max_it = it; + } + } + + return *max_it; + } + /** @brief Computes minimum and maximum. * * Computes the minimum and maximum of all objects returned by functor \p f. Result is returned as std::pair From 6c392fd18f84b84c48f589476754b622f988ecb4 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Mon, 9 Mar 2020 18:43:21 +0100 Subject: [PATCH 2/4] add count_if to smart ranges --- src/OpenMesh/Core/Mesh/SmartRange.hh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/OpenMesh/Core/Mesh/SmartRange.hh b/src/OpenMesh/Core/Mesh/SmartRange.hh index b827137a..5518878e 100644 --- a/src/OpenMesh/Core/Mesh/SmartRange.hh +++ b/src/OpenMesh/Core/Mesh/SmartRange.hh @@ -353,7 +353,16 @@ struct SmartRangeT } - + template + auto count_if(Functor&& f) -> int + { + int count = 0; + auto range = static_cast(this); + for (const auto& e : *range) + if (f(e)) + ++count; + return count; + } }; From cce116d8232fcebd28a47e313fca0d1584261257 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 12 Mar 2020 09:38:20 +0100 Subject: [PATCH 3/4] add documentation to count_if method --- src/OpenMesh/Core/Mesh/SmartRange.hh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/OpenMesh/Core/Mesh/SmartRange.hh b/src/OpenMesh/Core/Mesh/SmartRange.hh index 5518878e..0c2ceaad 100644 --- a/src/OpenMesh/Core/Mesh/SmartRange.hh +++ b/src/OpenMesh/Core/Mesh/SmartRange.hh @@ -353,6 +353,12 @@ struct SmartRangeT } + /** @brief Compute number of elements that satisfy a given predicate. + * + * Computes the numer of elements which satisfy functor \p f. + * + * @param f Predicate that elements have to satisfy in order to be counted. + */ template auto count_if(Functor&& f) -> int { From f1543cdbf024a545d4abcb85b512f2661541671c Mon Sep 17 00:00:00 2001 From: Patrick Schmidt Date: Tue, 17 Mar 2020 17:11:27 +0100 Subject: [PATCH 4/4] Fix inline implementation of opposite_face_handle() (linker error) --- src/OpenMesh/Core/Mesh/PolyConnectivity.cc | 7 ------- src/OpenMesh/Core/Mesh/PolyConnectivity.hh | 8 +++----- src/OpenMesh/Core/Mesh/PolyConnectivity_inline_impl.hh | 5 +++-- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.cc b/src/OpenMesh/Core/Mesh/PolyConnectivity.cc index 59d3c590..e2eaf45c 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.cc +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.cc @@ -99,13 +99,6 @@ bool PolyConnectivity::is_manifold(VertexHandle _vh) const //----------------------------------------------------------------------------- -SmartFaceHandle PolyConnectivity::opposite_face_handle(HalfedgeHandle _heh) const -{ - return face_handle(make_smart(opposite_halfedge_handle(_heh), this)); -} - -//----------------------------------------------------------------------------- - void PolyConnectivity::adjust_outgoing_halfedge(VertexHandle _vh) { for (ConstVertexOHalfedgeIter vh_it=cvoh_iter(_vh); vh_it.is_valid(); ++vh_it) diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh index d4d0736d..000f6218 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh @@ -611,6 +611,9 @@ public: inline SmartEdgeHandle edge_handle(SmartHalfedgeHandle _heh) const; inline SmartFaceHandle face_handle(SmartHalfedgeHandle _heh) const; + /// returns the face handle of the opposite halfedge + inline SmartFaceHandle opposite_face_handle(HalfedgeHandle _heh) const; + //@} /** \name Begin and end iterators @@ -1354,11 +1357,6 @@ public: bool is_manifold(VertexHandle _vh) const; /** @} */ - - // --- shortcuts --- - - /// returns the face handle of the opposite halfedge - inline SmartFaceHandle opposite_face_handle(HalfedgeHandle _heh) const; // --- misc --- diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity_inline_impl.hh b/src/OpenMesh/Core/Mesh/PolyConnectivity_inline_impl.hh index bde8f4cf..4bf8aeda 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity_inline_impl.hh +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity_inline_impl.hh @@ -58,8 +58,8 @@ inline SmartHalfedgeHandle PolyConnectivity::opposite_halfedge_handle(SmartHalfe inline SmartHalfedgeHandle PolyConnectivity::ccw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(ccw_rotated_halfedge_handle(HalfedgeHandle(_heh)), *this); } inline SmartHalfedgeHandle PolyConnectivity::cw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(cw_rotated_halfedge_handle(HalfedgeHandle(_heh)), *this); } -inline SmartHalfedgeHandle PolyConnectivity::s_halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) { return make_smart(ArrayKernel::s_halfedge_handle(EdgeHandle(_eh), _i), _eh.mesh()); } -inline SmartEdgeHandle PolyConnectivity::s_edge_handle(SmartHalfedgeHandle _heh) { return make_smart(ArrayKernel::s_edge_handle(HalfedgeHandle(_heh)), _heh.mesh()); } +inline SmartHalfedgeHandle PolyConnectivity::s_halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) { return make_smart(ArrayKernel::s_halfedge_handle(EdgeHandle(_eh), _i), _eh.mesh()); } +inline SmartEdgeHandle PolyConnectivity::s_edge_handle(SmartHalfedgeHandle _heh) { return make_smart(ArrayKernel::s_edge_handle(HalfedgeHandle(_heh)), _heh.mesh()); } inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) const { return make_smart(halfedge_handle(EdgeHandle(_eh), _i), *this); } inline SmartEdgeHandle PolyConnectivity::edge_handle(SmartHalfedgeHandle _heh) const { return make_smart(edge_handle(HalfedgeHandle(_heh)), *this); } @@ -68,6 +68,7 @@ inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartVertexHandle _ inline SmartFaceHandle PolyConnectivity::face_handle(SmartHalfedgeHandle _heh) const { return make_smart(face_handle(HalfedgeHandle(_heh)), *this); } +inline SmartFaceHandle PolyConnectivity::opposite_face_handle(HalfedgeHandle _heh) const { return make_smart(face_handle(opposite_halfedge_handle(_heh)), *this); } /// Generic class for vertex/halfedge/edge/face ranges.