diff --git a/src/Magnum/MeshTools/Combine.cpp b/src/Magnum/MeshTools/Combine.cpp index f860f4056..9212f4a51 100644 --- a/src/Magnum/MeshTools/Combine.cpp +++ b/src/Magnum/MeshTools/Combine.cpp @@ -210,4 +210,23 @@ Trade::MeshData combineFaceAttributes(const Trade::MeshData& mesh, const Trade:: })); } +Trade::MeshData combineFaceAttributes(const Trade::MeshData& mesh, Containers::ArrayView faceAttributes) { + #ifndef CORRADE_NO_ASSERT + for(std::size_t i = 0; i != faceAttributes.size(); ++i) + CORRADE_ASSERT(!faceAttributes[i].isOffsetOnly(), + "MeshTools::combineFaceAttributes(): face attribute" << i << "is offset-only, which is not supported", + (Trade::MeshData{MeshPrimitive::Triangles, 0})); + #endif + + return combineFaceAttributes(mesh, Trade::MeshData{MeshPrimitive::Faces, + /* Supply a vertex data view spanning the whole memory. It's not used + directly and this shuts off asserts for attribute bounds */ + {}, {nullptr, ~std::size_t{}}, + Trade::meshAttributeDataNonOwningArray(faceAttributes)}); +} + +Trade::MeshData combineFaceAttributes(const Trade::MeshData& mesh, std::initializer_list faceAttributes) { + return combineFaceAttributes(mesh, Containers::arrayView(faceAttributes)); +} + }} diff --git a/src/Magnum/MeshTools/Combine.h b/src/Magnum/MeshTools/Combine.h index 45f68cf36..e9dac4c5c 100644 --- a/src/Magnum/MeshTools/Combine.h +++ b/src/Magnum/MeshTools/Combine.h @@ -108,6 +108,24 @@ be interleaved. */ MAGNUM_MESHTOOLS_EXPORT Trade::MeshData combineFaceAttributes(const Trade::MeshData& mesh, const Trade::MeshData& faceAttributes); +/** +@overload +@m_since_latest + +Same as above with @p faceAttributes wrapped in a @ref Trade::MeshData with +@ref MeshPrimitive::Faces and no index buffer. Same as in the above case, +@p faceAttributes is expected to be interleaved. Note that offset-only +@ref Trade::MeshAttributeData instances are not supported in the +@p faceAttributes array. +*/ +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData combineFaceAttributes(const Trade::MeshData& mesh, Containers::ArrayView faceAttributes); + +/** + * @overload + * @m_since_latest + */ +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData combineFaceAttributes(const Trade::MeshData& mesh, std::initializer_list faceAttributes); + }} #endif diff --git a/src/Magnum/MeshTools/Test/CombineTest.cpp b/src/Magnum/MeshTools/Test/CombineTest.cpp index 3d6b8f0e6..622ffcff1 100644 --- a/src/Magnum/MeshTools/Test/CombineTest.cpp +++ b/src/Magnum/MeshTools/Test/CombineTest.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -51,6 +52,7 @@ struct CombineTest: TestSuite::Tester { void combineFaceAttributesUnexpectedPrimitive(); void combineFaceAttributesUnexpectedFaceCount(); void combineFaceAttributesFacesNotInterleaved(); + void combineFaceAttributesFaceAttributeOffsetOnly(); }; constexpr struct { @@ -76,7 +78,8 @@ CombineTest::CombineTest() { addTests({&CombineTest::combineFaceAttributesMeshNotIndexed, &CombineTest::combineFaceAttributesUnexpectedPrimitive, &CombineTest::combineFaceAttributesUnexpectedFaceCount, - &CombineTest::combineFaceAttributesFacesNotInterleaved}); + &CombineTest::combineFaceAttributesFacesNotInterleaved, + &CombineTest::combineFaceAttributesFaceAttributeOffsetOnly}); } void CombineTest::combineIndexedAttributes() { @@ -256,15 +259,6 @@ void CombineTest::combineFaceAttributes() { Trade::MeshAttributeData{Trade::MeshAttribute::Position, Containers::arrayView(positions)} }}; - const Trade::MeshData faceAttributes{MeshPrimitive::Faces, - {}, faceData, { - Trade::MeshAttributeData{Trade::MeshAttribute::Color, - Containers::StridedArrayView1D{faceData, - &faceData[0].color, 4, sizeof(FaceData)}}, - Trade::MeshAttributeData{Trade::meshAttributeCustom(25), - Containers::StridedArrayView1D{faceData, - &faceData[0].id, 4, sizeof(FaceData)}}, - }}; const Trade::MeshData faceAttributesIndexed{MeshPrimitive::Faces, {}, faceIndices, Trade::MeshIndexData{faceIndices}, {}, faceDataIndexed, { @@ -276,19 +270,31 @@ void CombineTest::combineFaceAttributes() { &faceDataIndexed[0].id, 3, sizeof(FaceData)}}, }}; - Trade::MeshData combined = data.indexed ? - MeshTools::combineFaceAttributes(mesh, faceAttributesIndexed) : - MeshTools::combineFaceAttributes(mesh, faceAttributes); - CORRADE_COMPARE(combined.attributeCount(), 3); - CORRADE_COMPARE(combined.indexType(), MeshIndexType::UnsignedInt); - CORRADE_COMPARE_AS(combined.indices(), + /* For a non-indexed variant test the overload that takes the attributes + directly, not wrapped in a MeshData */ + Containers::Optional combined; + if(data.indexed) + combined = MeshTools::combineFaceAttributes(mesh, faceAttributesIndexed); + else + combined = MeshTools::combineFaceAttributes(mesh, { + Trade::MeshAttributeData{Trade::MeshAttribute::Color, + Containers::StridedArrayView1D{faceData, + &faceData[0].color, 4, sizeof(FaceData)}}, + Trade::MeshAttributeData{Trade::meshAttributeCustom(25), + Containers::StridedArrayView1D{faceData, + &faceData[0].id, 4, sizeof(FaceData)}} + }); + + CORRADE_COMPARE(combined->attributeCount(), 3); + CORRADE_COMPARE(combined->indexType(), MeshIndexType::UnsignedInt); + CORRADE_COMPARE_AS(combined->indices(), Containers::arrayView({ 0, 1, 2, 3, 4, 5, 3, 5, 6, 7, 8, 9 }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(combined.attribute(Trade::MeshAttribute::Position), + CORRADE_COMPARE_AS(combined->attribute(Trade::MeshAttribute::Position), Containers::arrayView({ {0.0f, 0.0f}, {1.0f, 0.0f}, @@ -301,13 +307,13 @@ void CombineTest::combineFaceAttributes() { {1.0f, 2.0f}, {0.0f, 2.0f} }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(combined.attribute(Trade::MeshAttribute::Color), + CORRADE_COMPARE_AS(combined->attribute(Trade::MeshAttribute::Color), Containers::arrayView({ 0xaaaaaa_rgbf, 0xaaaaaa_rgbf, 0xaaaaaa_rgbf, 0xbbbbbb_rgbf, 0xbbbbbb_rgbf, 0xbbbbbb_rgbf, 0xbbbbbb_rgbf, 0xcccccc_rgbf, 0xcccccc_rgbf, 0xcccccc_rgbf }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(combined.attribute(Trade::meshAttributeCustom(25)), + CORRADE_COMPARE_AS(combined->attribute(Trade::meshAttributeCustom(25)), Containers::arrayView({ 'A', 'A', 'A', 'B', 'B', 'B', 'B', @@ -385,6 +391,19 @@ void CombineTest::combineFaceAttributesFacesNotInterleaved() { "MeshTools::combineFaceAttributes(): face attributes are not interleaved\n"); } +void CombineTest::combineFaceAttributesFaceAttributeOffsetOnly() { + std::ostringstream out; + Error redirectError{&out}; + MeshTools::combineFaceAttributes(Trade::MeshData{MeshPrimitive::Triangles, 0}, { + Trade::MeshAttributeData{Trade::MeshAttribute::ObjectId, + Containers::ArrayView{}}, + Trade::MeshAttributeData{Trade::MeshAttribute::Color, + VertexFormat::Vector4, 0, 5, 16} + }); + CORRADE_COMPARE(out.str(), + "MeshTools::combineFaceAttributes(): face attribute 1 is offset-only, which is not supported\n"); +} + }}}} CORRADE_TEST_MAIN(Magnum::MeshTools::Test::CombineTest)