diff --git a/src/Magnum/MeshTools/Duplicate.cpp b/src/Magnum/MeshTools/Duplicate.cpp index 7ba68fe30..7e4fcb997 100644 --- a/src/Magnum/MeshTools/Duplicate.cpp +++ b/src/Magnum/MeshTools/Duplicate.cpp @@ -80,6 +80,20 @@ void duplicateInto(const Containers::StridedArrayView2D& indices, co Trade::MeshData duplicate(const Trade::MeshData& data, const Containers::ArrayView extra) { CORRADE_ASSERT(data.isIndexed(), "MeshTools::duplicate(): mesh data not indexed", (Trade::MeshData{MeshPrimitive::Triangles, 0})); + #ifndef CORRADE_NO_ASSERT + for(std::size_t i = 0; i != data.attributeCount(); ++i) { + const VertexFormat format = data.attributeFormat(i); + CORRADE_ASSERT(!isVertexFormatImplementationSpecific(format), + "MeshTools::duplicate(): attribute" << i << "has an implementation-specific format" << reinterpret_cast(vertexFormatUnwrap(format)), + (Trade::MeshData{MeshPrimitive::Points, 0})); + } + for(std::size_t i = 0; i != extra.size(); ++i) { + const VertexFormat format = extra[i].format(); + CORRADE_ASSERT(!isVertexFormatImplementationSpecific(format), + "MeshTools::duplicate(): extra attribute" << i << "has an implementation-specific format" << reinterpret_cast(vertexFormatUnwrap(format)), + (Trade::MeshData{MeshPrimitive::Points, 0})); + } + #endif /* Calculate the layout */ Trade::MeshData layout = interleavedLayout(data, data.indexCount(), extra); diff --git a/src/Magnum/MeshTools/Duplicate.h b/src/Magnum/MeshTools/Duplicate.h index bb537e3f5..7a1e7a808 100644 --- a/src/Magnum/MeshTools/Duplicate.h +++ b/src/Magnum/MeshTools/Duplicate.h @@ -146,8 +146,10 @@ instances are not supported in the @p extra array. Expects that @p data is indexed and each attribute in @p extra has either the same amount of elements as @p data vertex count (*not* index count) or has -none. -@see @ref Trade::MeshData::attributeData() +none. All attributes are expected to not have an implementation-specific +format. +@see @ref isVertexFormatImplementationSpecific(), + @ref Trade::MeshData::attributeData() */ MAGNUM_MESHTOOLS_EXPORT Trade::MeshData duplicate(const Trade::MeshData& data, Containers::ArrayView extra = {}); diff --git a/src/Magnum/MeshTools/Test/DuplicateTest.cpp b/src/Magnum/MeshTools/Test/DuplicateTest.cpp index 108128e9f..1b53ebe00 100644 --- a/src/Magnum/MeshTools/Test/DuplicateTest.cpp +++ b/src/Magnum/MeshTools/Test/DuplicateTest.cpp @@ -59,10 +59,12 @@ struct DuplicateTest: TestSuite::Tester { template void duplicateMeshData(); void duplicateMeshDataNotIndexed(); + void duplicateMeshDataImplementationSpecificVertexFormat(); void duplicateMeshDataExtra(); void duplicateMeshDataExtraEmpty(); void duplicateMeshDataExtraWrongCount(); void duplicateMeshDataExtraOffsetOnly(); + void duplicateMeshDataExtraImplementationSpecificVertexFormat(); void duplicateMeshDataNoAttributes(); }; @@ -92,10 +94,12 @@ DuplicateTest::DuplicateTest() { &DuplicateTest::duplicateMeshData, &DuplicateTest::duplicateMeshData, &DuplicateTest::duplicateMeshDataNotIndexed, + &DuplicateTest::duplicateMeshDataImplementationSpecificVertexFormat, &DuplicateTest::duplicateMeshDataExtra, &DuplicateTest::duplicateMeshDataExtraEmpty, &DuplicateTest::duplicateMeshDataExtraWrongCount, &DuplicateTest::duplicateMeshDataExtraOffsetOnly, + &DuplicateTest::duplicateMeshDataExtraImplementationSpecificVertexFormat, &DuplicateTest::duplicateMeshDataNoAttributes}); } @@ -326,6 +330,28 @@ void DuplicateTest::duplicateMeshDataNotIndexed() { CORRADE_COMPARE(out.str(), "MeshTools::duplicate(): mesh data not indexed\n"); } +void DuplicateTest::duplicateMeshDataImplementationSpecificVertexFormat() { + #ifdef CORRADE_NO_ASSERT + CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); + #endif + + Trade::MeshData a{MeshPrimitive::Lines, + nullptr, Trade::MeshIndexData{MeshIndexType::UnsignedShort, nullptr}, + nullptr, { + Trade::MeshAttributeData{Trade::MeshAttribute::Position, + VertexFormat::Vector3, nullptr}, + Trade::MeshAttributeData{Trade::MeshAttribute::Position, + VertexFormat::Vector3, nullptr}, + Trade::MeshAttributeData{Trade::MeshAttribute::Color, + vertexFormatWrap(0xcaca), nullptr} + }}; + + std::ostringstream out; + Error redirectError{&out}; + MeshTools::duplicate(a); + CORRADE_COMPARE(out.str(), "MeshTools::duplicate(): attribute 2 has an implementation-specific format 0xcaca\n"); +} + void DuplicateTest::duplicateMeshDataExtra() { UnsignedByte indices[]{0, 1, 2, 2, 1, 0}; Vector2 positions[]{{1.3f, 0.3f}, {0.87f, 1.1f}, {1.0f, -0.5f}}; @@ -431,6 +457,29 @@ void DuplicateTest::duplicateMeshDataExtraOffsetOnly() { CORRADE_COMPARE(out.str(), "MeshTools::duplicate(): extra attribute 1 is offset-only, which is not supported\n"); } +void DuplicateTest::duplicateMeshDataExtraImplementationSpecificVertexFormat() { + #ifdef CORRADE_NO_ASSERT + CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); + #endif + + Trade::MeshData a{MeshPrimitive::Lines, + nullptr, Trade::MeshIndexData{MeshIndexType::UnsignedShort, nullptr}, + nullptr, { + Trade::MeshAttributeData{Trade::MeshAttribute::Position, + VertexFormat::Vector3, nullptr}, + }}; + + std::ostringstream out; + Error redirectError{&out}; + MeshTools::duplicate(a, { + Trade::MeshAttributeData{Trade::MeshAttribute::Position, + VertexFormat::Vector3, nullptr}, + Trade::MeshAttributeData{Trade::MeshAttribute::Color, + vertexFormatWrap(0xcaca), nullptr} + }); + CORRADE_COMPARE(out.str(), "MeshTools::duplicate(): extra attribute 1 has an implementation-specific format 0xcaca\n"); +} + void DuplicateTest::duplicateMeshDataNoAttributes() { UnsignedByte indices[]{0, 1, 2, 2, 1, 0}; Trade::MeshData data{MeshPrimitive::Lines,