diff --git a/src/Magnum/MeshTools/Interleave.cpp b/src/Magnum/MeshTools/Interleave.cpp index e121ec985..5c9ec82e5 100644 --- a/src/Magnum/MeshTools/Interleave.cpp +++ b/src/Magnum/MeshTools/Interleave.cpp @@ -72,6 +72,16 @@ Containers::StridedArrayView2D interleavedData(const Trade::MeshData return *out; } +Containers::StridedArrayView2D interleavedMutableData(Trade::MeshData& data) { + Containers::StridedArrayView2D out = interleavedData(data); + CORRADE_ASSERT(data.vertexDataFlags() & Trade::DataFlag::Mutable, + "MeshTools::interleavedMutableData(): vertex data is not mutable", {}); + return Containers::StridedArrayView2D{ + {nullptr, ~std::size_t{}}, /* to sidestep the range assertions */ + const_cast(reinterpret_cast(out.data())), + out.size(), out.stride()}; +} + namespace Implementation { Containers::Array interleavedLayout(Trade::MeshData&& data, const Containers::ArrayView extra) { diff --git a/src/Magnum/MeshTools/Interleave.h b/src/Magnum/MeshTools/Interleave.h index ccf8ec0ff..a4b9e7009 100644 --- a/src/Magnum/MeshTools/Interleave.h +++ b/src/Magnum/MeshTools/Interleave.h @@ -215,6 +215,16 @@ that the mesh is interleaved. */ MAGNUM_MESHTOOLS_EXPORT Containers::StridedArrayView2D interleavedData(const Trade::MeshData& data); +/** +@brief Mutable type-erased view on interleaved mesh data +@m_since_latest + +Same as @ref interleavedData(), but returns a mutable view. Expects that the +mesh is interleaved and vertex data is mutable. +@see @ref isInterleaved(), @ref Trade::MeshData::vertexDataFlags() +*/ +MAGNUM_MESHTOOLS_EXPORT Containers::StridedArrayView2D interleavedMutableData(Trade::MeshData& data); + /** @brief Create an interleaved mesh layout @m_since_latest diff --git a/src/Magnum/MeshTools/Test/InterleaveTest.cpp b/src/Magnum/MeshTools/Test/InterleaveTest.cpp index 86d40ef06..7c058c8ba 100644 --- a/src/Magnum/MeshTools/Test/InterleaveTest.cpp +++ b/src/Magnum/MeshTools/Test/InterleaveTest.cpp @@ -66,6 +66,7 @@ struct InterleaveTest: Corrade::TestSuite::Tester { void interleavedDataNoVertices(); void interleavedDataNotInterleaved(); void interleavedDataVertexDataWholeMemory(); + void interleavedMutableDataNotMutable(); void interleavedLayout(); void interleavedLayoutExtra(); @@ -116,6 +117,7 @@ InterleaveTest::InterleaveTest() { &InterleaveTest::interleavedDataNoVertices, &InterleaveTest::interleavedDataNotInterleaved, &InterleaveTest::interleavedDataVertexDataWholeMemory, + &InterleaveTest::interleavedMutableDataNotMutable, &InterleaveTest::interleavedLayout, &InterleaveTest::interleavedLayoutExtra, @@ -398,6 +400,13 @@ void InterleaveTest::interleavedData() { CORRADE_COMPARE(interleaved.size()[1], 31); CORRADE_COMPARE(interleaved.stride()[0], 40); CORRADE_COMPARE(interleaved.stride()[1], 1); + + Containers::StridedArrayView2D interleavedMutable = MeshTools::interleavedMutableData(data); + CORRADE_COMPARE(interleavedMutable.data(), positions.data()); + CORRADE_COMPARE(interleavedMutable.size()[0], 3); + CORRADE_COMPARE(interleavedMutable.size()[1], 31); + CORRADE_COMPARE(interleavedMutable.stride()[0], 40); + CORRADE_COMPARE(interleavedMutable.stride()[1], 1); } void InterleaveTest::interleavedDataNoAttributes() { @@ -484,6 +493,21 @@ void InterleaveTest::interleavedDataVertexDataWholeMemory() { CORRADE_COMPARE(interleaved.stride()[1], 1); } +void InterleaveTest::interleavedMutableDataNotMutable() { + #ifdef CORRADE_NO_ASSERT + CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); + #endif + + char a[1]; + Trade::MeshData data{MeshPrimitive::Lines, {}, a, {}, 15}; + CORRADE_VERIFY(MeshTools::isInterleaved(data)); + + std::ostringstream out; + Error redirectError{&out}; + MeshTools::interleavedMutableData(data); + CORRADE_COMPARE(out.str(), "MeshTools::interleavedMutableData(): vertex data is not mutable\n"); +} + void InterleaveTest::interleavedLayout() { Containers::Array indexData{6}; Containers::Array vertexData{3*20};