diff --git a/src/Magnum/Trade/MeshData.cpp b/src/Magnum/Trade/MeshData.cpp index 79c693610..ed68f5443 100644 --- a/src/Magnum/Trade/MeshData.cpp +++ b/src/Magnum/Trade/MeshData.cpp @@ -32,9 +32,10 @@ namespace Magnum { namespace Trade { -MeshIndexData::MeshIndexData(const MeshIndexType type, const Containers::ArrayView data) noexcept: type{type}, data{reinterpret_cast&>(data)} { - CORRADE_ASSERT(!data.empty(), - "Trade::MeshIndexData: index array can't be empty, create a non-indexed mesh instead", ); +MeshIndexData::MeshIndexData(const MeshIndexType type, const Containers::ArrayView data) noexcept: MeshIndexData{type, data, nullptr} { + /* Yes, this calls into a constexpr function defined in the header -- + because I feel that makes more sense than duplicating the full assert + logic */ CORRADE_ASSERT(data.size()%meshIndexTypeSize(type) == 0, "Trade::MeshIndexData: view size" << data.size() << "does not correspond to" << type, ); } @@ -63,7 +64,7 @@ Containers::Array meshAttributeDataNonOwningArray(const Conta return Containers::Array{const_cast(view.data()), view.size(), reinterpret_cast(Trade::Implementation::nonOwnedArrayDeleter)}; } -MeshData::MeshData(const MeshPrimitive primitive, Containers::Array&& indexData, const MeshIndexData& indices, Containers::Array&& vertexData, Containers::Array&& attributes, const void* const importerState) noexcept: _indexType{indices.type}, _primitive{primitive}, _indexDataFlags{DataFlag::Owned|DataFlag::Mutable}, _vertexDataFlags{DataFlag::Owned|DataFlag::Mutable}, _importerState{importerState}, _indexData{std::move(indexData)}, _vertexData{std::move(vertexData)}, _attributes{std::move(attributes)}, _indices{indices.data} { +MeshData::MeshData(const MeshPrimitive primitive, Containers::Array&& indexData, const MeshIndexData& indices, Containers::Array&& vertexData, Containers::Array&& attributes, const void* const importerState) noexcept: _indexType{indices.type}, _primitive{primitive}, _indexDataFlags{DataFlag::Owned|DataFlag::Mutable}, _vertexDataFlags{DataFlag::Owned|DataFlag::Mutable}, _importerState{importerState}, _indexData{std::move(indexData)}, _vertexData{std::move(vertexData)}, _attributes{std::move(attributes)}, _indices{Containers::arrayCast(indices.data)} { /* Save vertex count. It's a strided array view, so the size is not depending on type. */ if(_attributes.empty()) { diff --git a/src/Magnum/Trade/MeshData.h b/src/Magnum/Trade/MeshData.h index e5ac1865b..1df7d111c 100644 --- a/src/Magnum/Trade/MeshData.h +++ b/src/Magnum/Trade/MeshData.h @@ -177,19 +177,27 @@ class MAGNUM_TRADE_EXPORT MeshIndexData { explicit MeshIndexData(MeshIndexType type, Containers::ArrayView data) noexcept; /** @brief Construct with unsigned byte indices */ - explicit MeshIndexData(Containers::ArrayView data) noexcept: MeshIndexData{MeshIndexType::UnsignedByte, data} {} + constexpr explicit MeshIndexData(Containers::ArrayView data) noexcept: MeshIndexData{MeshIndexType::UnsignedByte, data, nullptr} {} /** @brief Construct with unsigned short indices */ - explicit MeshIndexData(Containers::ArrayView data) noexcept: MeshIndexData{MeshIndexType::UnsignedShort, data} {} + constexpr explicit MeshIndexData(Containers::ArrayView data) noexcept: MeshIndexData{MeshIndexType::UnsignedShort, data, nullptr} {} /** @brief Construct with unsigned int indices */ - explicit MeshIndexData(Containers::ArrayView data) noexcept: MeshIndexData{MeshIndexType::UnsignedInt, data} {} + constexpr explicit MeshIndexData(Containers::ArrayView data) noexcept: MeshIndexData{MeshIndexType::UnsignedInt, data, nullptr} {} private: + /* Contains an assert common for all constexpr constructor, nullptr_t + to disambiguate from the public constructor of the same signature -- + can't delegate into that one, because it checks against + meshIndexTypeSize() that's not constexpr, and since we come from a + template, we don't need that check anyway */ + constexpr explicit MeshIndexData(MeshIndexType type, Containers::ArrayView data, std::nullptr_t); + /* Not prefixed with _ because we use them like public in MeshData */ friend MeshData; MeshIndexType type; - Containers::ArrayView data; + /* Void so the constructors can be constexpr */ + Containers::ArrayView data; }; /** @@ -1016,6 +1024,9 @@ namespace Implementation { } #endif +constexpr MeshIndexData::MeshIndexData(MeshIndexType type, Containers::ArrayView data, std::nullptr_t): + type{type}, data{(CORRADE_CONSTEXPR_ASSERT(!data.empty(), "Trade::MeshIndexData: index array can't be empty, create a non-indexed mesh instead"), data)} {} + template MeshAttributeData::MeshAttributeData(MeshAttribute name, const Containers::StridedArrayView1D& data) noexcept: MeshAttributeData{name, Implementation::vertexFormatFor::type>(), Containers::arrayCast(data)} {} template Containers::ArrayView MeshData::indices() const { diff --git a/src/Magnum/Trade/Test/MeshDataTest.cpp b/src/Magnum/Trade/Test/MeshDataTest.cpp index 7f6a0caac..bce1be59b 100644 --- a/src/Magnum/Trade/Test/MeshDataTest.cpp +++ b/src/Magnum/Trade/Test/MeshDataTest.cpp @@ -250,6 +250,10 @@ void MeshDataTest::debugAttributeName() { using namespace Math::Literals; +constexpr UnsignedByte IndexBytes[]{25, 132, 3}; +constexpr UnsignedShort IndexShorts[]{2575, 13224, 3}; +constexpr UnsignedInt IndexInts[]{2110122, 132257, 3}; + void MeshDataTest::constructIndex() { { Containers::Array indexData{3*1}; @@ -260,6 +264,12 @@ void MeshDataTest::constructIndex() { CORRADE_COMPARE(data.indexType(), MeshIndexType::UnsignedByte); CORRADE_COMPARE(static_cast(data.indices().data()), indexView.data()); CORRADE_COMPARE(data.indexCount(), 3); + + constexpr MeshIndexData cindices{IndexBytes}; + MeshData cdata{MeshPrimitive::Points, {}, IndexBytes, cindices}; + CORRADE_COMPARE(cdata.indexType(), MeshIndexType::UnsignedByte); + CORRADE_COMPARE(static_cast(cdata.indices().data()), IndexBytes); + CORRADE_COMPARE(data.indexCount(), 3); } { Containers::Array indexData{3*2}; auto indexView = Containers::arrayCast(indexData); @@ -269,6 +279,12 @@ void MeshDataTest::constructIndex() { CORRADE_COMPARE(data.indexType(), MeshIndexType::UnsignedShort); CORRADE_COMPARE(static_cast(data.indices().data()), indexView.data()); CORRADE_COMPARE(data.indexCount(), 3); + + constexpr MeshIndexData cindices{IndexShorts}; + MeshData cdata{MeshPrimitive::Points, {}, IndexShorts, cindices}; + CORRADE_COMPARE(cdata.indexType(), MeshIndexType::UnsignedShort); + CORRADE_COMPARE(static_cast(cdata.indices().data()), IndexShorts); + CORRADE_COMPARE(data.indexCount(), 3); } { Containers::Array indexData{3*4}; auto indexView = Containers::arrayCast(indexData); @@ -278,6 +294,12 @@ void MeshDataTest::constructIndex() { CORRADE_COMPARE(data.indexType(), MeshIndexType::UnsignedInt); CORRADE_COMPARE(static_cast(data.indices().data()), indexView.data()); CORRADE_COMPARE(data.indexCount(), 3); + + constexpr MeshIndexData cindices{IndexInts}; + MeshData cdata{MeshPrimitive::Points, {}, IndexInts, cindices}; + CORRADE_COMPARE(cdata.indexType(), MeshIndexType::UnsignedInt); + CORRADE_COMPARE(static_cast(cdata.indices().data()), IndexInts); + CORRADE_COMPARE(data.indexCount(), 3); } }