update min and max functions on ranges and add minmax function
This commit is contained in:
@@ -71,7 +71,6 @@ struct SmartRangeT
|
|||||||
// TODO: Someone with better c++ knowledge may improve the code below.
|
// TODO: Someone with better c++ knowledge may improve the code below.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Functor>
|
template <typename Functor>
|
||||||
auto sum(Functor&& f) -> decltype (f(std::declval<HandleT>())+f(std::declval<HandleT>()))
|
auto sum(Functor&& f) -> decltype (f(std::declval<HandleT>())+f(std::declval<HandleT>()))
|
||||||
{
|
{
|
||||||
@@ -130,46 +129,49 @@ struct SmartRangeT
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <int n, typename Functor>
|
template <typename Functor>
|
||||||
auto elem_wise_min(Functor&& f) -> typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type
|
auto min(Functor&& f) -> typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type
|
||||||
{
|
{
|
||||||
|
using std::min;
|
||||||
|
|
||||||
auto range = static_cast<const RangeT*>(this);
|
auto range = static_cast<const RangeT*>(this);
|
||||||
auto it = range->begin();
|
auto it = range->begin();
|
||||||
auto end = range->end();
|
auto end = range->end();
|
||||||
assert(it != end);
|
assert(it != end);
|
||||||
|
|
||||||
typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type min = f(*it);
|
typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type res = f(*it);
|
||||||
++it;
|
++it;
|
||||||
|
|
||||||
for (; it != end; ++it)
|
for (; it != end; ++it)
|
||||||
{
|
res = min(res, f(*it));
|
||||||
const auto& tmp = f(*it);
|
|
||||||
for (int i = 0; i < n; ++i)
|
|
||||||
min[i] = std::min(min[i], tmp[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return min;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int n, typename Functor>
|
template <typename Functor>
|
||||||
auto elem_wise_max(Functor&& f) -> typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type
|
auto max(Functor&& f) -> typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type
|
||||||
{
|
{
|
||||||
|
using std::max;
|
||||||
|
|
||||||
auto range = static_cast<const RangeT*>(this);
|
auto range = static_cast<const RangeT*>(this);
|
||||||
auto it = range->begin();
|
auto it = range->begin();
|
||||||
auto end = range->end();
|
auto end = range->end();
|
||||||
assert(it != end);
|
assert(it != end);
|
||||||
|
|
||||||
typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type max = f(*it);
|
typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type res = f(*it);
|
||||||
++it;
|
++it;
|
||||||
|
|
||||||
for (; it != end; ++it)
|
for (; it != end; ++it)
|
||||||
{
|
res = max(res, f(*it));
|
||||||
const auto& tmp = f(*it);
|
|
||||||
for (int i = 0; i < n; ++i)
|
|
||||||
max[i] = std::max(max[i], tmp[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return max;
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Functor>
|
||||||
|
auto minmax(Functor&& f) -> std::pair<typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type,
|
||||||
|
typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type>
|
||||||
|
{
|
||||||
|
return std::make_pair(this->min(f), this->max(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -249,28 +249,34 @@ TEST_F(OpenMeshSmartRanges, ToArray)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Test bounding box
|
/* Test bounding box
|
||||||
*/
|
*/
|
||||||
TEST_F(OpenMeshSmartRanges, BoundingBox)
|
TEST_F(OpenMeshSmartRanges, BoundingBox)
|
||||||
{
|
{
|
||||||
auto myPos = OpenMesh::makeTemporaryProperty<OpenMesh::VertexHandle, Mesh::Point>(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<OpenMesh::VertexHandle, OpenMesh::Vec3f>(mesh_);
|
||||||
for (auto vh : mesh_.vertices())
|
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<OpenMesh::HalfedgeHandle, OpenMesh::Vec2d>(mesh_);
|
auto uvs = OpenMesh::makeTemporaryProperty<OpenMesh::HalfedgeHandle, OpenMesh::Vec2d>(mesh_);
|
||||||
for (auto heh : mesh_.halfedges())
|
for (auto heh : mesh_.halfedges())
|
||||||
uvs(heh) = OpenMesh::Vec2d(heh.idx(), (heh.idx() * 13)%7);
|
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())
|
for (auto fh : mesh_.faces())
|
||||||
{
|
{
|
||||||
auto uv_bb_min = fh.halfedges().elem_wise_min<2>(uvs);
|
auto uv_bb_min = fh.halfedges().min(uvs);
|
||||||
auto uv_bb_max = fh.halfedges().elem_wise_max<2>(uvs);
|
auto uv_bb_max = fh.halfedges().max(uvs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user