diff --git a/src/Magnum/MeshTools/Reference.cpp b/src/Magnum/MeshTools/Reference.cpp index 1f88ece16..5bf937029 100644 --- a/src/Magnum/MeshTools/Reference.cpp +++ b/src/Magnum/MeshTools/Reference.cpp @@ -32,8 +32,21 @@ namespace Magnum { namespace MeshTools { Trade::MeshData reference(const Trade::MeshData& data) { + /* Can't do just Trade::MeshIndexData{data.indices()} as that would discard + implementation-specific types. And can't do + Trade::meshIndexData{data.indexType(), view} + because asking for index type would assert on non-indexed meshes. */ + Trade::MeshIndexData indices; + if(data.isIndexed()) indices = Trade::MeshIndexData{ + data.indexType(), + Containers::StridedArrayView1D{ + data.indexData(), + data.indexData().data() + data.indexOffset(), + data.indexCount(), + data.indexStride()}}; + return Trade::MeshData{data.primitive(), - {}, data.indexData(), Trade::MeshIndexData{data.indices()}, + {}, data.indexData(), indices, {}, data.vertexData(), Trade::meshAttributeDataNonOwningArray(data.attributeData()), data.vertexCount()}; } @@ -43,8 +56,21 @@ Trade::MeshData mutableReference(Trade::MeshData& data) { "MeshTools::mutableReference(): data not mutable", (Trade::MeshData{MeshPrimitive::Points, 0})); + /* Can't do just Trade::MeshIndexData{data.indices()} as that would discard + implementation-specific types. And can't do + Trade::meshIndexData{data.indexType(), view} + because asking for index type would assert on non-indexed meshes. */ + Trade::MeshIndexData indices; + if(data.isIndexed()) indices = Trade::MeshIndexData{ + data.indexType(), + Containers::StridedArrayView1D{ + data.indexData(), + data.indexData().data() + data.indexOffset(), + data.indexCount(), + data.indexStride()}}; + return Trade::MeshData{data.primitive(), - Trade::DataFlag::Mutable, data.mutableIndexData(), Trade::MeshIndexData{data.indices()}, + Trade::DataFlag::Mutable, data.mutableIndexData(), indices, Trade::DataFlag::Mutable, data.mutableVertexData(), Trade::meshAttributeDataNonOwningArray(data.attributeData()), data.vertexCount()}; } diff --git a/src/Magnum/MeshTools/Test/ReferenceTest.cpp b/src/Magnum/MeshTools/Test/ReferenceTest.cpp index b2f153f61..1b346f93c 100644 --- a/src/Magnum/MeshTools/Test/ReferenceTest.cpp +++ b/src/Magnum/MeshTools/Test/ReferenceTest.cpp @@ -43,10 +43,12 @@ struct ReferenceTest: TestSuite::Tester { void reference(); void referenceNoIndexData(); + void referenceImplementationSpecificIndexType(); void referenceNoIndexVertexAttributeData(); void mutableReference(); void mutableReferenceNoIndexData(); + void mutableReferenceImplementationSpecificIndexType(); void mutableReferenceNoIndexVertexAttributeData(); void mutableReferenceNotMutable(); @@ -60,21 +62,34 @@ struct ReferenceTest: TestSuite::Tester { void ownedRvaluePartialPassthrough(); }; +struct { + const char* name; + MeshIndexType type; +} StridedIndicesData[]{ + {"", MeshIndexType::UnsignedShort}, + {"implementation-specific index format", meshIndexTypeWrap(0xcaca)} +}; + ReferenceTest::ReferenceTest() { addTests({&ReferenceTest::reference, &ReferenceTest::referenceNoIndexData, + &ReferenceTest::referenceImplementationSpecificIndexType, &ReferenceTest::referenceNoIndexVertexAttributeData, &ReferenceTest::mutableReference, &ReferenceTest::mutableReferenceNoIndexData, + &ReferenceTest::mutableReferenceImplementationSpecificIndexType, &ReferenceTest::mutableReferenceNoIndexVertexAttributeData, &ReferenceTest::mutableReferenceNotMutable, &ReferenceTest::owned, &ReferenceTest::ownedNoIndexData, - &ReferenceTest::ownedNoAttributeVertexData, - &ReferenceTest::ownedStridedIndices, - &ReferenceTest::ownedArrayAttribute, + &ReferenceTest::ownedNoAttributeVertexData}); + + addInstancedTests({&ReferenceTest::ownedStridedIndices}, + Containers::arraySize(StridedIndicesData)); + + addTests({&ReferenceTest::ownedArrayAttribute, &ReferenceTest::ownedImplementationSpecificVertexFormat, &ReferenceTest::ownedRvaluePassthrough, &ReferenceTest::ownedRvaluePartialPassthrough}); @@ -114,6 +129,17 @@ void ReferenceTest::referenceNoIndexData() { CORRADE_COMPARE(static_cast(reference.attributeData().data()), circle.attributeData().data()); } +void ReferenceTest::referenceImplementationSpecificIndexType() { + const UnsignedShort indices[7]{0, 3, 0, 7, 0, 15, 0}; + Trade::MeshData stuff{MeshPrimitive::Points, + {}, indices, Trade::MeshIndexData{meshIndexTypeWrap(0xcaca), Containers::stridedArrayView(indices)}, + 16}; + + /* The type should be preserved. not just dropped */ + Trade::MeshData reference = MeshTools::reference(stuff); + CORRADE_COMPARE(reference.indexType(), meshIndexTypeWrap(0xcaca)); +} + void ReferenceTest::referenceNoIndexVertexAttributeData() { Trade::MeshData fourtytwo{MeshPrimitive::Edges, 42}; @@ -161,6 +187,17 @@ void ReferenceTest::mutableReferenceNoIndexData() { CORRADE_COMPARE(static_cast(reference.attributeData().data()), circle.attributeData().data()); } +void ReferenceTest::mutableReferenceImplementationSpecificIndexType() { + UnsignedShort indices[7]{0, 3, 0, 7, 0, 15, 0}; + Trade::MeshData stuff{MeshPrimitive::Points, + Trade::DataFlag::Mutable, indices, Trade::MeshIndexData{meshIndexTypeWrap(0xcaca), Containers::stridedArrayView(indices)}, + 16}; + + /* The type should be preserved. not just dropped */ + Trade::MeshData reference = MeshTools::mutableReference(stuff); + CORRADE_COMPARE(reference.indexType(), meshIndexTypeWrap(0xcaca)); +} + void ReferenceTest::mutableReferenceNoIndexVertexAttributeData() { Trade::MeshData fourtytwo{MeshPrimitive::Edges, 42}; @@ -257,24 +294,31 @@ void ReferenceTest::ownedNoAttributeVertexData() { } void ReferenceTest::ownedStridedIndices() { + auto&& data = StridedIndicesData[testCaseInstanceId()]; + setTestCaseDescription(data.name); + const UnsignedShort indices[7]{0, 3, 0, 7, 0, 15, 0}; Trade::MeshData stuff{MeshPrimitive::Points, - {}, indices, Trade::MeshIndexData{Containers::stridedArrayView(indices).suffix(1).every(2)}, + {}, indices, Trade::MeshIndexData{data.type, Containers::stridedArrayView(indices).suffix(1).every(2)}, 16}; + /* The full index data layout including whatever format should be + preserved */ Trade::MeshData owned = MeshTools::owned(stuff); CORRADE_VERIFY(owned.isIndexed()); CORRADE_COMPARE(owned.primitive(), MeshPrimitive::Points); CORRADE_COMPARE(owned.indexDataFlags(), Trade::DataFlag::Mutable|Trade::DataFlag::Owned); CORRADE_COMPARE(owned.vertexDataFlags(), Trade::DataFlag::Mutable|Trade::DataFlag::Owned); CORRADE_COMPARE(owned.indexCount(), 3); - CORRADE_COMPARE(owned.indexType(), MeshIndexType::UnsignedShort); + CORRADE_COMPARE(owned.indexType(), data.type); CORRADE_COMPARE(owned.indexOffset(), 2); CORRADE_COMPARE(owned.indexStride(), 4); CORRADE_COMPARE(owned.vertexCount(), 16); CORRADE_COMPARE(owned.attributeCount(), 0); - CORRADE_COMPARE_AS(owned.indices(), + /* Has to do a prefix() because for an implementation-specific index type + the returned size is equal to stride */ + CORRADE_COMPARE_AS((Containers::arrayCast<1, const UnsignedShort>(owned.indices().prefix({owned.indexCount(), 2}))), Containers::arrayView({3, 7, 15}), TestSuite::Compare::Container); CORRADE_COMPARE_AS(owned.indexData(), stuff.indexData(),