diff --git a/src/Magnum/MeshTools/CompressIndices.cpp b/src/Magnum/MeshTools/CompressIndices.cpp index 09c1fb398..9ad23b7c3 100644 --- a/src/Magnum/MeshTools/CompressIndices.cpp +++ b/src/Magnum/MeshTools/CompressIndices.cpp @@ -51,6 +51,10 @@ template inline Containers::Array compress(const Contain } template std::pair, MeshIndexType> compressIndicesImplementation(const Containers::StridedArrayView1D& indices, const MeshIndexType atLeast, const Long offset) { + CORRADE_ASSERT(!isMeshIndexTypeImplementationSpecific(atLeast), + "MeshTools::compressIndices(): can't compress to an implementation-specific index type" << reinterpret_cast(meshIndexTypeUnwrap(atLeast)), + (std::pair, MeshIndexType>{nullptr, MeshIndexType::UnsignedInt})); + const UnsignedInt max = Math::max(indices) - offset; Containers::Array out; MeshIndexType type; @@ -144,6 +148,9 @@ Trade::MeshData compressIndices(Trade::MeshData&& data, MeshIndexType atLeast) { offset = Math::min(indices); result = compressIndicesImplementation(indices, atLeast, offset); } else { + CORRADE_ASSERT(!isMeshIndexTypeImplementationSpecific(data.indexType()), + "MeshTools::compressIndices(): mesh has an implementation-specific index type" << reinterpret_cast(meshIndexTypeUnwrap(data.indexType())), + (Trade::MeshData{MeshPrimitive{}, 0})); CORRADE_INTERNAL_ASSERT(data.indexType() == MeshIndexType::UnsignedByte); auto indices = data.indices(); offset = Math::min(indices); @@ -163,7 +170,7 @@ Trade::MeshData compressIndices(Trade::MeshData&& data, MeshIndexType atLeast) { Trade::MeshIndexData indices{result.second, result.first}; return Trade::MeshData{data.primitive(), std::move(result.first), indices, - std::move(vertexData), std::move(attributeData)}; + std::move(vertexData), std::move(attributeData), newVertexCount}; } Trade::MeshData compressIndices(const Trade::MeshData& data, MeshIndexType atLeast) { diff --git a/src/Magnum/MeshTools/CompressIndices.h b/src/Magnum/MeshTools/CompressIndices.h index c7bab3cdf..ceffa2d48 100644 --- a/src/Magnum/MeshTools/CompressIndices.h +++ b/src/Magnum/MeshTools/CompressIndices.h @@ -75,6 +75,9 @@ offsets accordingly. Example: A negative @p offset value will do an operation inverse to the above. See also @ref compressIndices(const Trade::MeshData&, MeshIndexType) that can do this operation directly on a @ref Trade::MeshData instance. + +The @p atLeast parameter is expected to not be an implementation-specific type. +@see @ref isMeshIndexTypeImplementationSpecific() */ MAGNUM_MESHTOOLS_EXPORT std::pair, MeshIndexType> compressIndices(const Containers::StridedArrayView1D& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0); @@ -125,6 +128,9 @@ 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, Long) etc. overloads. + +The @p atLeast parameter is expected to not be an implementation-specific type. +@see @ref isMeshIndexTypeImplementationSpecific() */ MAGNUM_MESHTOOLS_EXPORT std::pair, MeshIndexType> compressIndices(const Containers::StridedArrayView2D& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0); @@ -146,6 +152,10 @@ but together with adjusting vertex attribute offsets in the passed @ref Trade::MeshData instance. This function will unconditionally make a copy of all vertex data, use @ref compressIndices(Trade::MeshData&&, MeshIndexType) to avoid that copy. + +The mesh is expected to be indexed and the index type and the @p atLeast +parameter is expected to not be implementation-specific type. +@see @ref isMeshIndexTypeImplementationSpecific() */ MAGNUM_MESHTOOLS_EXPORT Trade::MeshData compressIndices(const Trade::MeshData& data, MeshIndexType atLeast = MeshIndexType::UnsignedShort); diff --git a/src/Magnum/MeshTools/Test/CompressIndicesTest.cpp b/src/Magnum/MeshTools/Test/CompressIndicesTest.cpp index 56332395f..e849e8429 100644 --- a/src/Magnum/MeshTools/Test/CompressIndicesTest.cpp +++ b/src/Magnum/MeshTools/Test/CompressIndicesTest.cpp @@ -60,6 +60,8 @@ struct CompressIndicesTest: TestSuite::Tester { template void compressMeshData(); void compressMeshDataMove(); void compressMeshDataNonIndexed(); + void compressMeshDataImplementationSpecificIndexType(); + void compressMeshDataImplementationSpecificAtLeastIndexType(); #ifdef MAGNUM_BUILD_DEPRECATED void compressAsShort(); @@ -89,6 +91,8 @@ CompressIndicesTest::CompressIndicesTest() { &CompressIndicesTest::compressMeshData, &CompressIndicesTest::compressMeshDataMove, &CompressIndicesTest::compressMeshDataNonIndexed, + &CompressIndicesTest::compressMeshDataImplementationSpecificIndexType, + &CompressIndicesTest::compressMeshDataImplementationSpecificAtLeastIndexType, #ifdef MAGNUM_BUILD_DEPRECATED &CompressIndicesTest::compressAsShort @@ -354,6 +358,40 @@ void CompressIndicesTest::compressMeshDataNonIndexed() { "MeshTools::compressIndices(): mesh data not indexed\n"); } +void CompressIndicesTest::compressMeshDataImplementationSpecificIndexType() { + #ifdef CORRADE_NO_ASSERT + CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); + #endif + + Trade::MeshData mesh{MeshPrimitive::Points, + nullptr, Trade::MeshIndexData{meshIndexTypeWrap(0xcaca), Containers::StridedArrayView1D{}}, 1}; + + /* Test both r-value and l-value overload */ + std::ostringstream out; + Error redirectError{&out}; + MeshTools::compressIndices(mesh); + MeshTools::compressIndices(std::move(mesh)); + CORRADE_COMPARE(out.str(), + "MeshTools::compressIndices(): mesh has an implementation-specific index type 0xcaca\n" + "MeshTools::compressIndices(): mesh has an implementation-specific index type 0xcaca\n"); +} + +void CompressIndicesTest::compressMeshDataImplementationSpecificAtLeastIndexType() { + #ifdef CORRADE_NO_ASSERT + CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); + #endif + + UnsignedInt indices[5]{}; + Trade::MeshData mesh{MeshPrimitive::Points, + {}, indices, Trade::MeshIndexData{indices}, 1}; + + std::ostringstream out; + Error redirectError{&out}; + MeshTools::compressIndices(mesh, meshIndexTypeWrap(0xcaca)); + CORRADE_COMPARE(out.str(), + "MeshTools::compressIndices(): can't compress to an implementation-specific index type 0xcaca\n"); +} + #ifdef MAGNUM_BUILD_DEPRECATED void CompressIndicesTest::compressAsShort() { #ifdef CORRADE_NO_ASSERT