From 1948883fd1c3d1d1032fc1964ddb092d05dbdc25 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Mon, 7 Oct 2019 13:06:15 +0200 Subject: [PATCH] update min and max functions on ranges and add minmax function --- src/OpenMesh/Core/Mesh/SmartRange.hh | 40 +++++++++++++------------ src/Unittests/unittests_smart_ranges.cc | 26 +++++++++------- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/OpenMesh/Core/Mesh/SmartRange.hh b/src/OpenMesh/Core/Mesh/SmartRange.hh index 43ab02cd..9ccc3a36 100644 --- a/src/OpenMesh/Core/Mesh/SmartRange.hh +++ b/src/OpenMesh/Core/Mesh/SmartRange.hh @@ -71,7 +71,6 @@ 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())) { @@ -130,46 +129,49 @@ struct SmartRangeT } - template - auto elem_wise_min(Functor&& f) -> typename std::remove_reference()))>::type + template + auto min(Functor&& f) -> typename std::remove_reference()))>::type { + using std::min; + auto range = static_cast(this); auto it = range->begin(); auto end = range->end(); assert(it != end); - typename std::remove_reference()))>::type min = f(*it); + typename std::remove_reference()))>::type res = f(*it); ++it; for (; it != end; ++it) - { - const auto& tmp = f(*it); - for (int i = 0; i < n; ++i) - min[i] = std::min(min[i], tmp[i]); - } + res = min(res, f(*it)); - return min; + return res; } - template - auto elem_wise_max(Functor&& f) -> typename std::remove_reference()))>::type + template + auto max(Functor&& f) -> typename std::remove_reference()))>::type { + using std::max; + auto range = static_cast(this); auto it = range->begin(); auto end = range->end(); assert(it != end); - typename std::remove_reference()))>::type max = f(*it); + typename std::remove_reference()))>::type res = f(*it); ++it; for (; it != end; ++it) - { - const auto& tmp = f(*it); - for (int i = 0; i < n; ++i) - max[i] = std::max(max[i], tmp[i]); - } + res = max(res, f(*it)); - return max; + return res; + } + + template + auto minmax(Functor&& f) -> std::pair()))>::type, + typename std::remove_reference()))>::type> + { + return std::make_pair(this->min(f), this->max(f)); } diff --git a/src/Unittests/unittests_smart_ranges.cc b/src/Unittests/unittests_smart_ranges.cc index fe613952..be5a3dc0 100644 --- a/src/Unittests/unittests_smart_ranges.cc +++ b/src/Unittests/unittests_smart_ranges.cc @@ -249,28 +249,34 @@ TEST_F(OpenMeshSmartRanges, ToArray) } } + /* Test bounding box */ TEST_F(OpenMeshSmartRanges, BoundingBox) { - auto myPos = OpenMesh::makeTemporaryProperty(mesh_); + // The custom vecs OpenMesh are tested with here do not implement a min or max function. + // Thus we convert here. + auto myPos = OpenMesh::makeTemporaryProperty(mesh_); for (auto vh : mesh_.vertices()) - myPos(vh) = mesh_.point(vh); + for (size_t i = 0; i < 3; ++i) + myPos(vh)[i] = mesh_.point(vh)[i]; + + auto bb_min = mesh_.vertices().min(myPos); + auto bb_max = mesh_.vertices().max(myPos); + auto bb = mesh_.vertices().minmax(myPos); + + EXPECT_LT(norm(bb_min - OpenMesh::Vec3f(-1,-1,-1)), 0.000001) << "Bounding box minimum seems off"; + EXPECT_LT(norm(bb_max - OpenMesh::Vec3f( 1, 1, 1)), 0.000001) << "Bounding box maximum seems off"; + auto uvs = OpenMesh::makeTemporaryProperty(mesh_); for (auto heh : mesh_.halfedges()) uvs(heh) = OpenMesh::Vec2d(heh.idx(), (heh.idx() * 13)%7); - auto bb_min = mesh_.vertices().elem_wise_min<3>(myPos); - auto bb_max = mesh_.vertices().elem_wise_max<3>(myPos); - - EXPECT_LT(norm(bb_min - Mesh::Point(-1,-1,-1)), 0.000001) << "Bounding box minimum seems off"; - EXPECT_LT(norm(bb_max - Mesh::Point( 1, 1, 1)), 0.000001) << "Bounding box maximum seems off"; - for (auto fh : mesh_.faces()) { - auto uv_bb_min = fh.halfedges().elem_wise_min<2>(uvs); - auto uv_bb_max = fh.halfedges().elem_wise_max<2>(uvs); + auto uv_bb_min = fh.halfedges().min(uvs); + auto uv_bb_max = fh.halfedges().max(uvs); } }