From 1974da2635805a63d91bc9c118d619e94f0d2622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 19 Jan 2020 21:41:04 +0100 Subject: [PATCH] MeshTools: added a type-erased compressIndices(). Useful when consuming the indices straight from MeshData. --- doc/changelog.dox | 6 +-- src/Magnum/MeshTools/CompressIndices.cpp | 12 +++++ src/Magnum/MeshTools/CompressIndices.h | 11 +++++ .../MeshTools/Test/CompressIndicesTest.cpp | 49 +++++++++++++++++++ 4 files changed, 75 insertions(+), 3 deletions(-) diff --git a/doc/changelog.dox b/doc/changelog.dox index a9d6f36af..4a3ea2397 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -211,9 +211,9 @@ See also: @subsubsection changelog-latest-changes-meshtools MeshTools library - Added @ref MeshTools::compressIndices() that takes a - @ref Containers::StridedArrayView instead of a @ref std::vector and - additionally allows you to specify the smallest allowed type and is working - with 8- and 16-byte index types as well + @ref Corrade::Containers::StridedArrayView instead of a @ref std::vector + and additionally allows you to specify the smallest allowed type and is + working with 8- and 16-byte index types as well - 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 diff --git a/src/Magnum/MeshTools/CompressIndices.cpp b/src/Magnum/MeshTools/CompressIndices.cpp index c2b2dd3c7..1be656c4c 100644 --- a/src/Magnum/MeshTools/CompressIndices.cpp +++ b/src/Magnum/MeshTools/CompressIndices.cpp @@ -87,6 +87,18 @@ std::pair, MeshIndexType> compressIndices(const Containe return compressIndicesImplementation(indices, atLeast); } +std::pair, MeshIndexType> compressIndices(const Containers::StridedArrayView2D& indices, const MeshIndexType atLeast) { + CORRADE_ASSERT(indices.isContiguous<1>(), "MeshTools::compressIndices(): second view dimension is not contiguous", {}); + if(indices.size()[1] == 4) + return compressIndicesImplementation(Containers::arrayCast<1, const UnsignedInt>(indices), atLeast); + else if(indices.size()[1] == 2) + return compressIndicesImplementation(Containers::arrayCast<1, const UnsignedShort>(indices), atLeast); + else { + CORRADE_ASSERT(indices.size()[1] == 1, "MeshTools::compressIndices(): expected index type size 1, 2 or 4 but got" << indices.size()[1], {}); + return compressIndicesImplementation(Containers::arrayCast<1, const UnsignedByte>(indices), atLeast); + } +} + #ifdef MAGNUM_BUILD_DEPRECATED std::tuple, MeshIndexType, UnsignedInt, UnsignedInt> compressIndices(const std::vector& indices) { /** @todo Performance hint when range can be represented by smaller value? */ diff --git a/src/Magnum/MeshTools/CompressIndices.h b/src/Magnum/MeshTools/CompressIndices.h index ea2e0b658..23a4eb070 100644 --- a/src/Magnum/MeshTools/CompressIndices.h +++ b/src/Magnum/MeshTools/CompressIndices.h @@ -77,6 +77,17 @@ MAGNUM_MESHTOOLS_EXPORT std::pair, MeshIndexType> compre */ MAGNUM_MESHTOOLS_EXPORT std::pair, MeshIndexType> compressIndices(const Containers::StridedArrayView1D& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort); +/** +@brief Compress a type-erased index array +@m_since_latest + +Expects that the second dimension of @p indices is contiguous and represents +the actual 1/2/4-byte index type. Based on its size then calls one of the +@ref compressIndices(const Containers::StridedArrayView1D&, MeshIndexType) +etc. overloads. +*/ +MAGNUM_MESHTOOLS_EXPORT std::pair, MeshIndexType> compressIndices(const Containers::StridedArrayView2D& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort); + #ifdef MAGNUM_BUILD_DEPRECATED /** @brief Compress vertex indices diff --git a/src/Magnum/MeshTools/Test/CompressIndicesTest.cpp b/src/Magnum/MeshTools/Test/CompressIndicesTest.cpp index 0ed27bff5..145b8edb8 100644 --- a/src/Magnum/MeshTools/Test/CompressIndicesTest.cpp +++ b/src/Magnum/MeshTools/Test/CompressIndicesTest.cpp @@ -44,6 +44,9 @@ struct CompressIndicesTest: TestSuite::Tester { template void compressUnsignedShort(); template void compressUnsignedInt(); void compressUnsignedByteInflateToShort(); + /* No compressErased(), as that's tested in the templates above */ + void compressErasedNonContiguous(); + void compressErasedWrongIndexSize(); #ifdef MAGNUM_BUILD_DEPRECATED void compressDeprecated(); #endif @@ -59,6 +62,8 @@ CompressIndicesTest::CompressIndicesTest() { &CompressIndicesTest::compressUnsignedShort, &CompressIndicesTest::compressUnsignedInt, &CompressIndicesTest::compressUnsignedByteInflateToShort, + &CompressIndicesTest::compressErasedNonContiguous, + &CompressIndicesTest::compressErasedWrongIndexSize, #ifdef MAGNUM_BUILD_DEPRECATED &CompressIndicesTest::compressDeprecated, @@ -79,6 +84,14 @@ template void CompressIndicesTest::compressUnsignedByte() { CORRADE_COMPARE_AS(Containers::arrayCast(out.first), Containers::arrayView({1, 2, 3, 0, 4}), TestSuite::Compare::Container); + + /* Test the type-erased variant as well */ + out = compressIndices(Containers::arrayCast<2, const char>(Containers::stridedArrayView(indices)), MeshIndexType::UnsignedByte); + + CORRADE_COMPARE(out.second, MeshIndexType::UnsignedByte); + CORRADE_COMPARE_AS(Containers::arrayCast(out.first), + Containers::arrayView({1, 2, 3, 0, 4}), + TestSuite::Compare::Container); } template void CompressIndicesTest::compressUnsignedShort() { @@ -87,6 +100,14 @@ template void CompressIndicesTest::compressUnsignedShort() { const T indices[]{1, 256, 0, 5}; std::pair, MeshIndexType> out = compressIndices(indices); + CORRADE_COMPARE(out.second, MeshIndexType::UnsignedShort); + CORRADE_COMPARE_AS(Containers::arrayCast(out.first), + Containers::arrayView({1, 256, 0, 5}), + TestSuite::Compare::Container); + + /* Test the type-erased variant as well */ + out = compressIndices(Containers::arrayCast<2, const char>(Containers::stridedArrayView(indices))); + CORRADE_COMPARE(out.second, MeshIndexType::UnsignedShort); CORRADE_COMPARE_AS(Containers::arrayCast(out.first), Containers::arrayView({1, 256, 0, 5}), @@ -99,6 +120,14 @@ template void CompressIndicesTest::compressUnsignedInt() { const T indices[]{65536, 3, 2}; std::pair, MeshIndexType> out = compressIndices(indices); + CORRADE_COMPARE(out.second, MeshIndexType::UnsignedInt); + CORRADE_COMPARE_AS(Containers::arrayCast(out.first), + Containers::arrayView({65536, 3, 2}), + TestSuite::Compare::Container); + + /* Test the type-erased variant as well */ + out = compressIndices(Containers::arrayCast<2, const char>(Containers::stridedArrayView(indices))); + CORRADE_COMPARE(out.second, MeshIndexType::UnsignedInt); CORRADE_COMPARE_AS(Containers::arrayCast(out.first), Containers::arrayView({65536, 3, 2}), @@ -116,6 +145,26 @@ void CompressIndicesTest::compressUnsignedByteInflateToShort() { TestSuite::Compare::Container); } +void CompressIndicesTest::compressErasedNonContiguous() { + const char indices[6*4]{}; + + std::stringstream out; + Error redirectError{&out}; + compressIndices(Containers::StridedArrayView2D{indices, {6, 2}, {4, 2}}); + CORRADE_COMPARE(out.str(), + "MeshTools::compressIndices(): second view dimension is not contiguous\n"); +} + +void CompressIndicesTest::compressErasedWrongIndexSize() { + const char indices[6*3]{}; + + std::stringstream out; + Error redirectError{&out}; + compressIndices(Containers::StridedArrayView2D{indices, {6, 3}}.every(2)); + CORRADE_COMPARE(out.str(), + "MeshTools::compressIndices(): expected index type size 1, 2 or 4 but got 3\n"); +} + #ifdef MAGNUM_BUILD_DEPRECATED void CompressIndicesTest::compressDeprecated() { Containers::Array data;