diff --git a/src/OpenMesh/Core/Mesh/SmartRange.hh b/src/OpenMesh/Core/Mesh/SmartRange.hh index fdb2b15b..f6bac807 100644 --- a/src/OpenMesh/Core/Mesh/SmartRange.hh +++ b/src/OpenMesh/Core/Mesh/SmartRange.hh @@ -59,7 +59,7 @@ struct SmartRangeT // TODO: Someone with better c++ knowledge may improve the code below. template - auto sum(Functor f) -> decltype (f(std::declval())+f(std::declval())) + auto sum(Functor&& f) -> decltype (f(std::declval())+f(std::declval())) { auto range = static_cast(this); auto begin = range->begin(); @@ -73,6 +73,27 @@ struct SmartRangeT return sum; } + template + auto avg(Functor&& f) -> decltype (1.0 * (f(std::declval())+f(std::declval()))) + { + auto range = static_cast(this); + auto begin = range->begin(); + auto end = range->end(); + assert(begin != end); + decltype (f(*begin) + f(*begin)) sum = f(*begin); + auto it = begin; + ++it; + int n_elements = 1; + for (; it != end; ++it) + { + sum += f(*it); + ++n_elements; + } + return (1.0 / n_elements) * sum; + } + + + }; diff --git a/src/OpenMesh/Core/Utils/PropertyManager.hh b/src/OpenMesh/Core/Utils/PropertyManager.hh index fb3860f5..0feb3aa5 100644 --- a/src/OpenMesh/Core/Utils/PropertyManager.hh +++ b/src/OpenMesh/Core/Utils/PropertyManager.hh @@ -380,6 +380,30 @@ class PropertyManager { return mesh_->property(prop_, handle); } + /** + * Enables convenient access to the encapsulated property. + * + * For a usage example see this class' documentation. + * + * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.) + */ + template + inline typename PROPTYPE::reference operator() (const HandleType &handle) { + return mesh_->property(prop_, handle); + } + + /** + * Enables convenient access to the encapsulated property. + * + * For a usage example see this class' documentation. + * + * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.) + */ + template + inline typename PROPTYPE::const_reference operator() (const HandleType &handle) const { + return mesh_->property(prop_, handle); + } + /** * Conveniently set the property for an entire range of values. * diff --git a/src/Unittests/unittests_smart_ranges.cc b/src/Unittests/unittests_smart_ranges.cc index e817bc07..15b7da3f 100644 --- a/src/Unittests/unittests_smart_ranges.cc +++ b/src/Unittests/unittests_smart_ranges.cc @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -192,5 +193,25 @@ TEST_F(OpenMeshSmartRanges, Sum) } +/* Test if Property Manager can be used in smart ranges + */ +TEST_F(OpenMeshSmartRanges, PropertyManagerAsFunctor) +{ + auto myPos = OpenMesh::makeTemporaryProperty(mesh_); + + for (auto vh : mesh_.vertices()) + myPos(vh) = mesh_.point(vh); + + Mesh::Point cog(0,0,0); + for (auto vh : mesh_.vertices()) + cog += mesh_.point(vh); + cog /= mesh_.n_vertices(); + + auto cog2 = mesh_.vertices().avg(myPos); + + EXPECT_LT(norm(cog - cog2), 0.00001) << "Computed center of gravities are significantly different."; +} + + }