Browse Source

MeshTools: added a STL-less subdivide().

The subdivideInPlace() alone wasn't convenient enough.
pull/371/head
Vladimír Vondruš 6 years ago
parent
commit
77d7931df2
  1. 7
      doc/changelog.dox
  2. 25
      src/Magnum/MeshTools/Subdivide.h
  3. 15
      src/Magnum/MeshTools/Test/SubdivideTest.cpp

7
doc/changelog.dox

@ -106,6 +106,11 @@ See also:
- Added @ref Math::reflect() and @ref Math::refract() (see - Added @ref Math::reflect() and @ref Math::refract() (see
[mosra/magnum#420](https://github.com/mosra/magnum/pull/420)) [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 @subsubsection changelog-latest-new-platform Platform libraries
- Cursor management using @ref Platform::Sdl2Application::setCursor(), - Cursor management using @ref Platform::Sdl2Application::setCursor(),
@ -205,6 +210,8 @@ See also:
@subsubsection changelog-latest-changes-meshtools MeshTools library @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 - Added @ref MeshTools::subdivideInPlace() that operates on a partially
filled array view instead of a @ref std::vector filled array view instead of a @ref std::vector
- Added @ref MeshTools::removeDuplicatesIndexedInPlace() that operates - Added @ref MeshTools::removeDuplicatesIndexedInPlace() that operates

25
src/Magnum/MeshTools/Subdivide.h

@ -30,6 +30,7 @@
*/ */
#include <vector> #include <vector>
#include <Corrade/Containers/GrowableArray.h>
#include <Corrade/Containers/ArrayViewStl.h> #include <Corrade/Containers/ArrayViewStl.h>
#include <Corrade/Containers/StridedArrayView.h> #include <Corrade/Containers/StridedArrayView.h>
#include <Corrade/Utility/Assert.h> #include <Corrade/Utility/Assert.h>
@ -43,18 +44,34 @@ template<class IndexType, class Vertex, class Interpolator> void subdivideInPlac
#endif #endif
/** /**
@brief Subdivide the mesh @brief Subdivide a mesh
@tparam Vertex Vertex data type @tparam Vertex Vertex data type
@tparam Interpolator See the @p interpolator function parameter @tparam Interpolator See the @p interpolator function parameter
@param[in,out] indices Index array to operate on @param[in,out] indices Index array to operate on
@param[in,out] vertices Vertex array to operate on @param[in,out] vertices Vertex array to operate on
@param interpolator Functor or function pointer which interpolates @param interpolator Functor or function pointer which interpolates
two adjacent vertices: @cpp Vertex interpolator(Vertex a, Vertex b) @ce 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 Goes through all triangle faces and subdivides them into four new, enlarging
duplicate vertices in the mesh is up to the user. 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() @see @ref subdivideInPlace(), @ref removeDuplicatesInPlace()
*/ */
template<class IndexType, class Vertex, class Interpolator> void subdivide(Containers::Array<IndexType>& indices, Containers::Array<Vertex>& 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<IndexType>&, Containers::Array<Vertex>&vertices, Interpolator), only
working on a @ref std::vector.
*/
template<class Vertex, class Interpolator> void subdivide(std::vector<UnsignedInt>& indices, std::vector<Vertex>& vertices, Interpolator interpolator) { template<class Vertex, class Interpolator> void subdivide(std::vector<UnsignedInt>& indices, std::vector<Vertex>& vertices, Interpolator interpolator) {
CORRADE_ASSERT(!(indices.size()%3), "MeshTools::subdivide(): index count is not divisible by 3", ); CORRADE_ASSERT(!(indices.size()%3), "MeshTools::subdivide(): index count is not divisible by 3", );
@ -64,7 +81,7 @@ template<class Vertex, class Interpolator> void subdivide(std::vector<UnsignedIn
} }
/** /**
@brief Subdivide the mesh in-place @brief Subdivide a mesh in-place
@tparam Vertex Vertex data type @tparam Vertex Vertex data type
@tparam Interpolator See the @p interpolator function parameter @tparam Interpolator See the @p interpolator function parameter
@param[in,out] indices Index array to operate on @param[in,out] indices Index array to operate on

15
src/Magnum/MeshTools/Test/SubdivideTest.cpp

@ -37,6 +37,7 @@ struct SubdivideTest: TestSuite::Tester {
explicit SubdivideTest(); explicit SubdivideTest();
void subdivide(); void subdivide();
void subdivideStl();
void subdivideWrongIndexCount(); void subdivideWrongIndexCount();
template<class T> void subdivideInPlace(); template<class T> void subdivideInPlace();
void subdivideInPlaceWrongIndexCount(); void subdivideInPlaceWrongIndexCount();
@ -51,6 +52,7 @@ inline Vector1 interpolator(Vector1 a, Vector1 b) { return (a[0]+b[0])/2; }
SubdivideTest::SubdivideTest() { SubdivideTest::SubdivideTest() {
addTests({&SubdivideTest::subdivide, addTests({&SubdivideTest::subdivide,
&SubdivideTest::subdivideStl,
&SubdivideTest::subdivideWrongIndexCount, &SubdivideTest::subdivideWrongIndexCount,
&SubdivideTest::subdivideInPlace<UnsignedByte>, &SubdivideTest::subdivideInPlace<UnsignedByte>,
&SubdivideTest::subdivideInPlace<UnsignedShort>, &SubdivideTest::subdivideInPlace<UnsignedShort>,
@ -60,6 +62,19 @@ SubdivideTest::SubdivideTest() {
} }
void SubdivideTest::subdivide() { void SubdivideTest::subdivide() {
auto positions = Containers::array<Vector1>({0, 2, 6, 8});
auto indices = Containers::array<UnsignedInt>({0, 1, 2, 1, 2, 3});
MeshTools::subdivide(indices, positions, interpolator);
CORRADE_COMPARE_AS(indices, Containers::arrayView<UnsignedInt>({
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<Vector1>({
0, 2, 6, 8, 1, 4, 3, 4, 7, 5
}), TestSuite::Compare::Container);
}
void SubdivideTest::subdivideStl() {
std::vector<Vector1> positions{0, 2, 6, 8}; std::vector<Vector1> positions{0, 2, 6, 8};
std::vector<UnsignedInt> indices{0, 1, 2, 1, 2, 3}; std::vector<UnsignedInt> indices{0, 1, 2, 1, 2, 3};
MeshTools::subdivide(indices, positions, interpolator); MeshTools::subdivide(indices, positions, interpolator);

Loading…
Cancel
Save