From 476497952f07bbe25896c0bbd4b03bef76b75911 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 12 Jan 2020 19:46:41 +0100 Subject: [PATCH] Trade: make it possible to construct a "padding" MeshAttributeData. Will be used in MeshTools algorithms. Also harden the MeshData constructor to reject such instances. --- src/Magnum/Trade/MeshData.cpp | 3 +++ src/Magnum/Trade/MeshData.h | 10 ++++++++++ src/Magnum/Trade/Test/MeshDataTest.cpp | 26 ++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/Magnum/Trade/MeshData.cpp b/src/Magnum/Trade/MeshData.cpp index 1217cb87f..4d5524630 100644 --- a/src/Magnum/Trade/MeshData.cpp +++ b/src/Magnum/Trade/MeshData.cpp @@ -88,6 +88,9 @@ MeshData::MeshData(const MeshPrimitive primitive, Containers::Array&& inde constructors */ for(std::size_t i = 0; i != _attributes.size(); ++i) { const MeshAttributeData& attribute = _attributes[i]; + CORRADE_ASSERT(attribute._format != VertexFormat{}, + "Trade::MeshData: attribute" << i << "doesn't specify anything", ); + const Containers::StridedArrayView1D data = Containers::arrayCast(attribute._data); CORRADE_ASSERT(data.size() == _vertexCount, "Trade::MeshData: attribute" << i << "has" << data.size() << "vertices but" << _vertexCount << "expected", ); diff --git a/src/Magnum/Trade/MeshData.h b/src/Magnum/Trade/MeshData.h index dfa820923..ec854f501 100644 --- a/src/Magnum/Trade/MeshData.h +++ b/src/Magnum/Trade/MeshData.h @@ -261,6 +261,16 @@ class MAGNUM_TRADE_EXPORT MeshAttributeData { /** @overload */ template constexpr explicit MeshAttributeData(MeshAttribute name, const Containers::ArrayView& data) noexcept: MeshAttributeData{name, Containers::stridedArrayView(data)} {} + /** + * @brief Construct a pad value + * + * Usable in various @ref MeshTools algorithms to insert padding + * between interleaved attributes. Negative values can be used to alias + * multiple different attributes onto each other. Not meant to be + * passed to @ref MeshData. + */ + constexpr explicit MeshAttributeData(Int padding): _name{}, _format{}, _data{nullptr, 0, padding} {} + /** @brief Attribute name */ constexpr MeshAttribute name() const { return _name; } diff --git a/src/Magnum/Trade/Test/MeshDataTest.cpp b/src/Magnum/Trade/Test/MeshDataTest.cpp index dffb068e5..cf192eedf 100644 --- a/src/Magnum/Trade/Test/MeshDataTest.cpp +++ b/src/Magnum/Trade/Test/MeshDataTest.cpp @@ -55,6 +55,7 @@ struct MeshDataTest: TestSuite::Tester { void constructAttributeTypeErased(); void constructAttributeTypeErasedWrongStride(); void constructAttributeNullptr(); + void constructAttributePadding(); void constructAttributeNonOwningArray(); void construct(); @@ -83,6 +84,7 @@ struct MeshDataTest: TestSuite::Tester { void constructVerticesNotOwnedFlagOwned(); void constructIndexlessNotOwnedFlagOwned(); void constructAttributelessNotOwnedFlagOwned(); + void constructInvalidAttributeData(); void constructCopy(); void constructMove(); @@ -150,6 +152,7 @@ MeshDataTest::MeshDataTest() { &MeshDataTest::constructAttributeTypeErased, &MeshDataTest::constructAttributeTypeErasedWrongStride, &MeshDataTest::constructAttributeNullptr, + &MeshDataTest::constructAttributePadding, &MeshDataTest::constructAttributeNonOwningArray, &MeshDataTest::construct, @@ -180,6 +183,7 @@ MeshDataTest::MeshDataTest() { &MeshDataTest::constructVerticesNotOwnedFlagOwned, &MeshDataTest::constructIndexlessNotOwnedFlagOwned, &MeshDataTest::constructAttributelessNotOwnedFlagOwned, + &MeshDataTest::constructInvalidAttributeData, &MeshDataTest::constructCopy, &MeshDataTest::constructMove, @@ -418,6 +422,15 @@ void MeshDataTest::constructAttributeNullptr() { CORRADE_VERIFY(!positions.data().data()); } +void MeshDataTest::constructAttributePadding() { + MeshAttributeData padding{-35}; + CORRADE_COMPARE(padding.name(), MeshAttribute{}); + CORRADE_COMPARE(padding.format(), VertexFormat{}); + CORRADE_COMPARE(padding.data().size(), 0); + CORRADE_COMPARE(padding.data().stride(), -35); + CORRADE_VERIFY(!padding.data()); +} + void MeshDataTest::constructAttributeNonOwningArray() { const MeshAttributeData data[3]; Containers::Array array = meshAttributeDataNonOwningArray(data); @@ -1080,6 +1093,19 @@ void MeshDataTest::constructAttributelessNotOwnedFlagOwned() { "Trade::MeshData: can't construct with non-owned index data but Trade::DataFlag::Owned\n"); } +void MeshDataTest::constructInvalidAttributeData() { + MeshAttributeData a; + MeshAttributeData b{3}; + + std::ostringstream out; + Error redirectError{&out}; + MeshData{MeshPrimitive::Triangles, nullptr, {a}}; + MeshData{MeshPrimitive::Triangles, nullptr, {b}}; + CORRADE_COMPARE(out.str(), + "Trade::MeshData: attribute 0 doesn't specify anything\n" + "Trade::MeshData: attribute 0 doesn't specify anything\n"); +} + void MeshDataTest::constructCopy() { CORRADE_VERIFY(!(std::is_constructible{})); CORRADE_VERIFY(!(std::is_assignable{}));