From 77d7931df2d79eebfcfca1c8db630c5c78338413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 19 Jan 2020 15:12:49 +0100 Subject: [PATCH] MeshTools: added a STL-less subdivide(). The subdivideInPlace() alone wasn't convenient enough. --- doc/changelog.dox | 7 ++++++ src/Magnum/MeshTools/Subdivide.h | 25 +++++++++++++++++---- src/Magnum/MeshTools/Test/SubdivideTest.cpp | 15 +++++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/doc/changelog.dox b/doc/changelog.dox index 572de1d3e..b18fac2d5 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -106,6 +106,11 @@ See also: - Added @ref Math::reflect() and @ref Math::refract() (see [mosra/magnum#420](https://github.com/mosra/magnum/pull/420)) +@subsubsection changelog-latest-new-meshtools MeshTools library + +- Added @ref MeshTools::subdivideInPlace() for allocation-less mesh + subdivision + @subsubsection changelog-latest-new-platform Platform libraries - Cursor management using @ref Platform::Sdl2Application::setCursor(), @@ -205,6 +210,8 @@ See also: @subsubsection changelog-latest-changes-meshtools MeshTools library +- Added @ref MeshTools::subdivide() that operates on a (growable) + @ref Corrade::Containers::Array instead of a @ref std::vector - Added @ref MeshTools::subdivideInPlace() that operates on a partially filled array view instead of a @ref std::vector - Added @ref MeshTools::removeDuplicatesIndexedInPlace() that operates diff --git a/src/Magnum/MeshTools/Subdivide.h b/src/Magnum/MeshTools/Subdivide.h index 1796c16f4..72f94b845 100644 --- a/src/Magnum/MeshTools/Subdivide.h +++ b/src/Magnum/MeshTools/Subdivide.h @@ -30,6 +30,7 @@ */ #include +#include #include #include #include @@ -43,18 +44,34 @@ template void subdivideInPlac #endif /** -@brief Subdivide the mesh +@brief Subdivide a mesh @tparam Vertex Vertex data type @tparam Interpolator See the @p interpolator function parameter @param[in,out] indices Index array to operate on @param[in,out] vertices Vertex array to operate on @param interpolator Functor or function pointer which interpolates two adjacent vertices: @cpp Vertex interpolator(Vertex a, Vertex b) @ce +@m_since_latest -Goes through all triangle faces and subdivides them into four new. Removing -duplicate vertices in the mesh is up to the user. +Goes through all triangle faces and subdivides them into four new, enlarging +the @p indices and @p vertices arrays as appropriate. Removing duplicate +vertices in the mesh is up to the user. @see @ref subdivideInPlace(), @ref removeDuplicatesInPlace() */ +template void subdivide(Containers::Array& indices, Containers::Array& vertices, Interpolator interpolator) { + CORRADE_ASSERT(!(indices.size()%3), "MeshTools::subdivide(): index count is not divisible by 3", ); + + arrayResize(vertices, Containers::NoInit, vertices.size() + indices.size()); + arrayResize(indices, Containers::NoInit, indices.size()*4); + subdivideInPlace(Containers::stridedArrayView(indices), Containers::stridedArrayView(vertices), interpolator); +} + +/** +@brief Subdivide a mesh + +Same as @ref subdivide(Containers::Array&, Containers::Array&vertices, Interpolator), only +working on a @ref std::vector. +*/ template void subdivide(std::vector& indices, std::vector& vertices, Interpolator interpolator) { CORRADE_ASSERT(!(indices.size()%3), "MeshTools::subdivide(): index count is not divisible by 3", ); @@ -64,7 +81,7 @@ template void subdivide(std::vector void subdivideInPlace(); void subdivideInPlaceWrongIndexCount(); @@ -51,6 +52,7 @@ inline Vector1 interpolator(Vector1 a, Vector1 b) { return (a[0]+b[0])/2; } SubdivideTest::SubdivideTest() { addTests({&SubdivideTest::subdivide, + &SubdivideTest::subdivideStl, &SubdivideTest::subdivideWrongIndexCount, &SubdivideTest::subdivideInPlace, &SubdivideTest::subdivideInPlace, @@ -60,6 +62,19 @@ SubdivideTest::SubdivideTest() { } void SubdivideTest::subdivide() { + auto positions = Containers::array({0, 2, 6, 8}); + auto indices = Containers::array({0, 1, 2, 1, 2, 3}); + MeshTools::subdivide(indices, positions, interpolator); + + CORRADE_COMPARE_AS(indices, Containers::arrayView({ + 4, 5, 6, 7, 8, 9, 0, 4, 6, 4, 1, 5, 6, 5, 2, 1, 7, 9, 7, 2, 8, 9, 8, 3 + }), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(positions, Containers::arrayView({ + 0, 2, 6, 8, 1, 4, 3, 4, 7, 5 + }), TestSuite::Compare::Container); +} + +void SubdivideTest::subdivideStl() { std::vector positions{0, 2, 6, 8}; std::vector indices{0, 1, 2, 1, 2, 3}; MeshTools::subdivide(indices, positions, interpolator);