From d06ac097c1fe2d62d6697b391f8f6cbf22d23241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 12 Apr 2023 18:56:13 +0200 Subject: [PATCH] MeshTools: unify naming of MeshData arguments. --- src/Magnum/MeshTools/Combine.cpp | 40 ++--- src/Magnum/MeshTools/Combine.h | 8 +- src/Magnum/MeshTools/Compile.cpp | 54 +++--- src/Magnum/MeshTools/Compile.h | 18 +- src/Magnum/MeshTools/CompressIndices.cpp | 48 +++--- src/Magnum/MeshTools/CompressIndices.h | 4 +- src/Magnum/MeshTools/Duplicate.cpp | 30 ++-- src/Magnum/MeshTools/Duplicate.h | 12 +- src/Magnum/MeshTools/FilterAttributes.cpp | 148 ++++++++-------- src/Magnum/MeshTools/FilterAttributes.h | 30 ++-- src/Magnum/MeshTools/GenerateIndices.cpp | 66 ++++---- src/Magnum/MeshTools/GenerateIndices.h | 4 +- src/Magnum/MeshTools/Interleave.cpp | 162 +++++++++--------- src/Magnum/MeshTools/Interleave.h | 46 ++--- src/Magnum/MeshTools/Reference.cpp | 90 +++++----- src/Magnum/MeshTools/Reference.h | 14 +- src/Magnum/MeshTools/RemoveDuplicates.cpp | 20 +-- src/Magnum/MeshTools/RemoveDuplicates.h | 4 +- src/Magnum/MeshTools/Transform.cpp | 196 +++++++++++----------- src/Magnum/MeshTools/Transform.h | 18 +- 20 files changed, 506 insertions(+), 506 deletions(-) diff --git a/src/Magnum/MeshTools/Combine.cpp b/src/Magnum/MeshTools/Combine.cpp index 7721ac396..0bd33af44 100644 --- a/src/Magnum/MeshTools/Combine.cpp +++ b/src/Magnum/MeshTools/Combine.cpp @@ -43,20 +43,20 @@ Trade::MeshData combineIndexedImplementation( #ifndef CORRADE_NO_ASSERT const char* assertPrefix, #endif - const MeshPrimitive primitive, Containers::Array& combinedIndices, const UnsignedInt indexCount, const UnsignedInt indexStride, const Containers::Iterable& data) + const MeshPrimitive primitive, Containers::Array& combinedIndices, const UnsignedInt indexCount, const UnsignedInt indexStride, const Containers::Iterable& meshes) { /* Calculate attribute count and vertex stride */ UnsignedInt attributeCount = 0; UnsignedInt vertexStride = 0; - for(std::size_t i = 0; i != data.size(); ++i) { - attributeCount += data[i].attributeCount(); - for(UnsignedInt j = 0; j != data[i].attributeCount(); ++j) { - const VertexFormat format = data[i].attributeFormat(j); + for(std::size_t i = 0; i != meshes.size(); ++i) { + attributeCount += meshes[i].attributeCount(); + for(UnsignedInt j = 0; j != meshes[i].attributeCount(); ++j) { + const VertexFormat format = meshes[i].attributeFormat(j); CORRADE_ASSERT(!isVertexFormatImplementationSpecific(format), assertPrefix << "attribute" << j << "of mesh" << i << "has an implementation-specific format" << reinterpret_cast(vertexFormatUnwrap(format)), (Trade::MeshData{MeshPrimitive::Points, 0})); - vertexStride += vertexFormatSize(format)*Math::max(data[i].attributeArraySize(j), UnsignedShort{1}); + vertexStride += vertexFormatSize(format)*Math::max(meshes[i].attributeArraySize(j), UnsignedShort{1}); } } @@ -75,7 +75,7 @@ Trade::MeshData combineIndexedImplementation( std::size_t indexOffset = 0; std::size_t attributeOffset = 0; std::size_t vertexOffset = 0; - for(const Trade::MeshData& mesh: data) { + for(const Trade::MeshData& mesh: meshes) { const UnsignedInt indexSize = mesh.isIndexed() ? meshIndexTypeSize(mesh.indexType()) : 4; Containers::StridedArrayView2D indices{combinedIndices, @@ -110,8 +110,8 @@ Trade::MeshData combineIndexedImplementation( } -Trade::MeshData combineIndexedAttributes(const Containers::Iterable& data) { - CORRADE_ASSERT(!data.isEmpty(), +Trade::MeshData combineIndexedAttributes(const Containers::Iterable& meshes) { + CORRADE_ASSERT(!meshes.isEmpty(), "MeshTools::combineIndexedAttributes(): no meshes passed", (Trade::MeshData{MeshPrimitive{}, 0})); @@ -122,22 +122,22 @@ Trade::MeshData combineIndexedAttributes(const Containers::Iterable(meshIndexTypeUnwrap(indexType)), (Trade::MeshData{MeshPrimitive{}, 0})); if(i == 0) { - primitive = data[i].primitive(); - indexCount = data[i].indexCount(); + primitive = meshes[i].primitive(); + indexCount = meshes[i].indexCount(); } else { - CORRADE_ASSERT(data[i].primitive() == primitive, - "MeshTools::combineIndexedAttributes(): data" << i << "is" << data[i].primitive() << "but expected" << primitive, (Trade::MeshData{MeshPrimitive{}, 0})); - CORRADE_ASSERT(data[i].indexCount() == indexCount, - "MeshTools::combineIndexedAttributes(): data" << i << "has" << data[i].indexCount() << "indices but expected" << indexCount, (Trade::MeshData{MeshPrimitive{}, 0})); + CORRADE_ASSERT(meshes[i].primitive() == primitive, + "MeshTools::combineIndexedAttributes(): data" << i << "is" << meshes[i].primitive() << "but expected" << primitive, (Trade::MeshData{MeshPrimitive{}, 0})); + CORRADE_ASSERT(meshes[i].indexCount() == indexCount, + "MeshTools::combineIndexedAttributes(): data" << i << "has" << meshes[i].indexCount() << "indices but expected" << indexCount, (Trade::MeshData{MeshPrimitive{}, 0})); } indexStride += meshIndexTypeSize(indexType); } @@ -149,7 +149,7 @@ Trade::MeshData combineIndexedAttributes(const Containers::Iterable combinedIndices{NoInit, indexCount*indexStride}; { std::size_t indexOffset = 0; - for(const Trade::MeshData& mesh: data) { + for(const Trade::MeshData& mesh: meshes) { const UnsignedInt indexSize = meshIndexTypeSize(mesh.indexType()); Containers::StridedArrayView2D dst{combinedIndices, combinedIndices.data() + indexOffset, @@ -167,7 +167,7 @@ Trade::MeshData combineIndexedAttributes(const Containers::Iterable), alternatively you can turn a non-indexed attribute to an indexed one first @@ -95,7 +95,7 @@ implementation-specific format. @see @ref isMeshIndexTypeImplementationSpecific(), @ref isVertexFormatImplementationSpecific() */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData combineIndexedAttributes(const Containers::Iterable& data); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData combineIndexedAttributes(const Containers::Iterable& meshes); /** @brief Combine per-face attributes into an existing mesh diff --git a/src/Magnum/MeshTools/Compile.cpp b/src/Magnum/MeshTools/Compile.cpp index 79ebc4e05..01c7165de 100644 --- a/src/Magnum/MeshTools/Compile.cpp +++ b/src/Magnum/MeshTools/Compile.cpp @@ -252,61 +252,61 @@ GL::Mesh compileInternal(const Trade::MeshData& meshData, const CompileFlags fla } -GL::Mesh compile(const Trade::MeshData& meshData, GL::Buffer&& indices, GL::Buffer&& vertices) { - return compileInternal(meshData, std::move(indices), std::move(vertices), {}); +GL::Mesh compile(const Trade::MeshData& mesh, GL::Buffer&& indices, GL::Buffer&& vertices) { + return compileInternal(mesh, std::move(indices), std::move(vertices), {}); } -GL::Mesh compile(const Trade::MeshData& meshData, GL::Buffer& indices, GL::Buffer& vertices) { - return compileInternal(meshData, GL::Buffer::wrap(indices.id(), GL::Buffer::TargetHint::ElementArray), GL::Buffer::wrap(vertices.id(), GL::Buffer::TargetHint::Array), CompileFlag::NoWarnOnCustomAttributes); +GL::Mesh compile(const Trade::MeshData& mesh, GL::Buffer& indices, GL::Buffer& vertices) { + return compileInternal(mesh, GL::Buffer::wrap(indices.id(), GL::Buffer::TargetHint::ElementArray), GL::Buffer::wrap(vertices.id(), GL::Buffer::TargetHint::Array), CompileFlag::NoWarnOnCustomAttributes); } -GL::Mesh compile(const Trade::MeshData& meshData, GL::Buffer& indices, GL::Buffer&& vertices) { - return compileInternal(meshData, GL::Buffer::wrap(indices.id(), GL::Buffer::TargetHint::ElementArray), std::move(vertices), CompileFlag::NoWarnOnCustomAttributes); +GL::Mesh compile(const Trade::MeshData& mesh, GL::Buffer& indices, GL::Buffer&& vertices) { + return compileInternal(mesh, GL::Buffer::wrap(indices.id(), GL::Buffer::TargetHint::ElementArray), std::move(vertices), CompileFlag::NoWarnOnCustomAttributes); } -GL::Mesh compile(const Trade::MeshData& meshData, GL::Buffer&& indices, GL::Buffer& vertices) { - return compileInternal(meshData, std::move(indices), GL::Buffer::wrap(vertices.id(), GL::Buffer::TargetHint::Array), CompileFlag::NoWarnOnCustomAttributes); +GL::Mesh compile(const Trade::MeshData& mesh, GL::Buffer&& indices, GL::Buffer& vertices) { + return compileInternal(mesh, std::move(indices), GL::Buffer::wrap(vertices.id(), GL::Buffer::TargetHint::Array), CompileFlag::NoWarnOnCustomAttributes); } -GL::Mesh compile(const Trade::MeshData& meshData) { - return compileInternal(meshData, {}); +GL::Mesh compile(const Trade::MeshData& mesh) { + return compileInternal(mesh, {}); } -GL::Mesh compile(const Trade::MeshData& meshData, CompileFlags flags) { +GL::Mesh compile(const Trade::MeshData& mesh, CompileFlags flags) { /* If we want to generate normals, prepare a new mesh data and recurse, with the flags unset */ - if(meshData.primitive() == MeshPrimitive::Triangles && (flags & (CompileFlag::GenerateFlatNormals|CompileFlag::GenerateSmoothNormals))) { - CORRADE_ASSERT(meshData.attributeCount(Trade::MeshAttribute::Position), + if(mesh.primitive() == MeshPrimitive::Triangles && (flags & (CompileFlag::GenerateFlatNormals|CompileFlag::GenerateSmoothNormals))) { + CORRADE_ASSERT(mesh.attributeCount(Trade::MeshAttribute::Position), "MeshTools::compile(): the mesh has no positions, can't generate normals", GL::Mesh{}); /* This could fire if we have 2D positions or for packed formats */ - CORRADE_ASSERT(meshData.attributeFormat(Trade::MeshAttribute::Position) == VertexFormat::Vector3, - "MeshTools::compile(): can't generate normals for" << meshData.attributeFormat(Trade::MeshAttribute::Position) << "positions", GL::Mesh{}); + CORRADE_ASSERT(mesh.attributeFormat(Trade::MeshAttribute::Position) == VertexFormat::Vector3, + "MeshTools::compile(): can't generate normals for" << mesh.attributeFormat(Trade::MeshAttribute::Position) << "positions", GL::Mesh{}); /* If the data already have a normal array, reuse its location, otherwise mix in an extra one */ Trade::MeshAttributeData normalAttribute; Containers::ArrayView extra; - if(!meshData.hasAttribute(Trade::MeshAttribute::Normal)) { + if(!mesh.hasAttribute(Trade::MeshAttribute::Normal)) { normalAttribute = Trade::MeshAttributeData{ Trade::MeshAttribute::Normal, VertexFormat::Vector3, nullptr}; extra = {&normalAttribute, 1}; /* If we reuse a normal location, expect correct type */ - } else CORRADE_ASSERT(meshData.attributeFormat(Trade::MeshAttribute::Normal) == VertexFormat::Vector3, - "MeshTools::compile(): can't generate normals into" << meshData.attributeFormat(Trade::MeshAttribute::Normal), GL::Mesh{}); + } else CORRADE_ASSERT(mesh.attributeFormat(Trade::MeshAttribute::Normal) == VertexFormat::Vector3, + "MeshTools::compile(): can't generate normals into" << mesh.attributeFormat(Trade::MeshAttribute::Normal), GL::Mesh{}); /* If we want flat normals, we need to first duplicate everything using the index buffer. Otherwise just interleave the potential extra normal attribute in. */ Trade::MeshData generated{MeshPrimitive::Points, 0}; - if(flags & CompileFlag::GenerateFlatNormals && meshData.isIndexed()) - generated = duplicate(meshData, extra); + if(flags & CompileFlag::GenerateFlatNormals && mesh.isIndexed()) + generated = duplicate(mesh, extra); else - generated = interleave(meshData, extra); + generated = interleave(mesh, extra); /* Generate the normals. If we don't have the index buffer, we can only generate flat ones. */ - if(flags & CompileFlag::GenerateFlatNormals || !meshData.isIndexed()) + if(flags & CompileFlag::GenerateFlatNormals || !mesh.isIndexed()) generateFlatNormalsInto( generated.attribute(Trade::MeshAttribute::Position), generated.mutableAttribute(Trade::MeshAttribute::Normal)); @@ -320,7 +320,7 @@ GL::Mesh compile(const Trade::MeshData& meshData, CompileFlags flags) { flags &= ~(CompileFlag::GenerateFlatNormals|CompileFlag::GenerateSmoothNormals); CORRADE_INTERNAL_ASSERT(!(flags & ~CompileFlag::NoWarnOnCustomAttributes)); - return compileInternal(meshData, flags); + return compileInternal(mesh, flags); } #ifdef MAGNUM_BUILD_DEPRECATED @@ -555,16 +555,16 @@ CORRADE_IGNORE_DEPRECATED_POP #endif #ifndef MAGNUM_TARGET_GLES2 -Containers::Pair compiledPerVertexJointCount(const Trade::MeshData& meshData) { +Containers::Pair compiledPerVertexJointCount(const Trade::MeshData& mesh) { UnsignedInt primaryCount = 0, secondaryCount = 0; - for(UnsignedInt i = 0; i != meshData.attributeCount(); ++i) { + for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) { /* The mesh is expected to have the same count and array size of JointIds and Weights, so it's enough to do it just for one of them */ - if(meshData.attributeName(i) != Trade::MeshAttribute::JointIds) + if(mesh.attributeName(i) != Trade::MeshAttribute::JointIds) continue; - const UnsignedInt componentCount = meshData.attributeArraySize(i); + const UnsignedInt componentCount = mesh.attributeArraySize(i); for(UnsignedInt j = 0; j < componentCount; j += 4) { if(!primaryCount) primaryCount = Math::min(componentCount - j, 4u); diff --git a/src/Magnum/MeshTools/Compile.h b/src/Magnum/MeshTools/Compile.h index 299344541..cae676b39 100644 --- a/src/Magnum/MeshTools/Compile.h +++ b/src/Magnum/MeshTools/Compile.h @@ -167,7 +167,7 @@ to access them afterwards. For alternative solutions see the @see @ref shaders-generic */ -MAGNUM_MESHTOOLS_EXPORT GL::Mesh compile(const Trade::MeshData& meshData, CompileFlags flags); +MAGNUM_MESHTOOLS_EXPORT GL::Mesh compile(const Trade::MeshData& mesh, CompileFlags flags); /** * @overload @@ -176,7 +176,7 @@ MAGNUM_MESHTOOLS_EXPORT GL::Mesh compile(const Trade::MeshData& meshData, Compil /* Separately because this one doesn't rely on duplicate() / interleave() / generate*Normals() and thus the exe can be smaller when using this function directly */ -MAGNUM_MESHTOOLS_EXPORT GL::Mesh compile(const Trade::MeshData& meshData); +MAGNUM_MESHTOOLS_EXPORT GL::Mesh compile(const Trade::MeshData& mesh); /** @brief Compile mesh data using external buffers @@ -196,8 +196,8 @@ by the mesh or not: @snippet MagnumMeshTools-gl.cpp compile-external-attributes -If @p meshData is not indexed, the @p indices parameter is ignored --- in that -case you can pass a @ref NoCreate "NoCreate"-d instance to avoid allocating an +If @p mesh is not indexed, the @p indices parameter is ignored --- in that case +you can pass a @ref NoCreate "NoCreate"-d instance to avoid allocating an unnecessary OpenGL buffer object. Compared to @ref compile(const Trade::MeshData&, CompileFlags), this function @@ -205,25 +205,25 @@ implicitly enables the @ref CompileFlag::NoWarnOnCustomAttributes flag, assuming that custom attributes and attributes with implementation-specific formats are explicitly handled on the application side. */ -MAGNUM_MESHTOOLS_EXPORT GL::Mesh compile(const Trade::MeshData& meshData, GL::Buffer& indices, GL::Buffer& vertices); +MAGNUM_MESHTOOLS_EXPORT GL::Mesh compile(const Trade::MeshData& mesh, GL::Buffer& indices, GL::Buffer& vertices); /** * @overload * @m_since{2020,06} */ -MAGNUM_MESHTOOLS_EXPORT GL::Mesh compile(const Trade::MeshData& meshData, GL::Buffer& indices, GL::Buffer&& vertices); +MAGNUM_MESHTOOLS_EXPORT GL::Mesh compile(const Trade::MeshData& mesh, GL::Buffer& indices, GL::Buffer&& vertices); /** * @overload * @m_since{2020,06} */ -MAGNUM_MESHTOOLS_EXPORT GL::Mesh compile(const Trade::MeshData& meshData, GL::Buffer&& indices, GL::Buffer& vertices); +MAGNUM_MESHTOOLS_EXPORT GL::Mesh compile(const Trade::MeshData& mesh, GL::Buffer&& indices, GL::Buffer& vertices); /** * @overload * @m_since{2020,06} */ -MAGNUM_MESHTOOLS_EXPORT GL::Mesh compile(const Trade::MeshData& meshData, GL::Buffer&& indices, GL::Buffer&& vertices); +MAGNUM_MESHTOOLS_EXPORT GL::Mesh compile(const Trade::MeshData& mesh, GL::Buffer&& indices, GL::Buffer&& vertices); #ifdef MAGNUM_BUILD_DEPRECATED /** @@ -333,7 +333,7 @@ similarly with other builtin shaders. support which is not available in WebGL 1.0, thus neither this function is defined in WebGL 1.0 builds. */ -MAGNUM_MESHTOOLS_EXPORT Containers::Pair compiledPerVertexJointCount(const Trade::MeshData& meshData); +MAGNUM_MESHTOOLS_EXPORT Containers::Pair compiledPerVertexJointCount(const Trade::MeshData& mesh); #endif }} diff --git a/src/Magnum/MeshTools/CompressIndices.cpp b/src/Magnum/MeshTools/CompressIndices.cpp index 1e4a2c61c..b5d7c4d33 100644 --- a/src/Magnum/MeshTools/CompressIndices.cpp +++ b/src/Magnum/MeshTools/CompressIndices.cpp @@ -125,61 +125,61 @@ Containers::Pair, MeshIndexType> compressIndices(const C return compressIndices(indices, MeshIndexType::UnsignedShort, offset); } -Trade::MeshData compressIndices(Trade::MeshData&& data, MeshIndexType atLeast) { - CORRADE_ASSERT(data.isIndexed(), "MeshTools::compressIndices(): mesh data not indexed", (Trade::MeshData{MeshPrimitive::Triangles, 0})); +Trade::MeshData compressIndices(Trade::MeshData&& mesh, MeshIndexType atLeast) { + CORRADE_ASSERT(mesh.isIndexed(), "MeshTools::compressIndices(): mesh data not indexed", (Trade::MeshData{MeshPrimitive::Triangles, 0})); /* Transfer vertex data as-is, as those don't need any changes. Release if possible. */ Containers::Array vertexData; - const UnsignedInt vertexCount = data.vertexCount(); - if(data.vertexDataFlags() & Trade::DataFlag::Owned) - vertexData = data.releaseVertexData(); + const UnsignedInt vertexCount = mesh.vertexCount(); + if(mesh.vertexDataFlags() & Trade::DataFlag::Owned) + vertexData = mesh.releaseVertexData(); else { - vertexData = Containers::Array{NoInit, data.vertexData().size()}; - Utility::copy(data.vertexData(), vertexData); + vertexData = Containers::Array{NoInit, mesh.vertexData().size()}; + Utility::copy(mesh.vertexData(), vertexData); } /* Compress the indices */ UnsignedInt offset; Containers::Pair, MeshIndexType> result; - if(data.indexType() == MeshIndexType::UnsignedInt) { - auto indices = data.indices(); + if(mesh.indexType() == MeshIndexType::UnsignedInt) { + auto indices = mesh.indices(); offset = Math::min(indices); result = compressIndicesImplementation(indices, atLeast, offset); - } else if(data.indexType() == MeshIndexType::UnsignedShort) { - auto indices = data.indices(); + } else if(mesh.indexType() == MeshIndexType::UnsignedShort) { + auto indices = mesh.indices(); offset = Math::min(indices); result = compressIndicesImplementation(indices, atLeast, offset); } else { - CORRADE_ASSERT(!isMeshIndexTypeImplementationSpecific(data.indexType()), - "MeshTools::compressIndices(): mesh has an implementation-specific index type" << reinterpret_cast(meshIndexTypeUnwrap(data.indexType())), + CORRADE_ASSERT(!isMeshIndexTypeImplementationSpecific(mesh.indexType()), + "MeshTools::compressIndices(): mesh has an implementation-specific index type" << reinterpret_cast(meshIndexTypeUnwrap(mesh.indexType())), (Trade::MeshData{MeshPrimitive{}, 0})); - CORRADE_INTERNAL_ASSERT(data.indexType() == MeshIndexType::UnsignedByte); - auto indices = data.indices(); + CORRADE_INTERNAL_ASSERT(mesh.indexType() == MeshIndexType::UnsignedByte); + auto indices = mesh.indices(); offset = Math::min(indices); result = compressIndicesImplementation(indices, atLeast, offset); } /* Recreate the attribute array */ const UnsignedInt newVertexCount = vertexCount - offset; - Containers::Array attributeData{data.attributeCount()}; + Containers::Array attributeData{mesh.attributeCount()}; for(UnsignedInt i = 0, max = attributeData.size(); i != max; ++i) { - const UnsignedInt stride = data.attributeStride(i); - attributeData[i] = Trade::MeshAttributeData{data.attributeName(i), - data.attributeFormat(i), - Containers::StridedArrayView1D{vertexData, vertexData.data() + data.attributeOffset(i) + offset*stride, newVertexCount, stride}, - data.attributeArraySize(i)}; + const UnsignedInt stride = mesh.attributeStride(i); + attributeData[i] = Trade::MeshAttributeData{mesh.attributeName(i), + mesh.attributeFormat(i), + Containers::StridedArrayView1D{vertexData, vertexData.data() + mesh.attributeOffset(i) + offset*stride, newVertexCount, stride}, + mesh.attributeArraySize(i)}; } Trade::MeshIndexData indices{result.second(), result.first()}; - return Trade::MeshData{data.primitive(), std::move(result.first()), indices, + return Trade::MeshData{mesh.primitive(), std::move(result.first()), indices, std::move(vertexData), std::move(attributeData), newVertexCount}; } -Trade::MeshData compressIndices(const Trade::MeshData& data, MeshIndexType atLeast) { +Trade::MeshData compressIndices(const Trade::MeshData& mesh, MeshIndexType atLeast) { /* Pass through to the && overload, which then decides whether to reuse anything based on the DataFlags */ - return compressIndices(reference(data), atLeast); + return compressIndices(reference(mesh), atLeast); } #ifdef MAGNUM_BUILD_DEPRECATED diff --git a/src/Magnum/MeshTools/CompressIndices.h b/src/Magnum/MeshTools/CompressIndices.h index a367d7e5c..43616c27e 100644 --- a/src/Magnum/MeshTools/CompressIndices.h +++ b/src/Magnum/MeshTools/CompressIndices.h @@ -159,7 +159,7 @@ The mesh is expected to be indexed and the index type and the @p atLeast parameter is expected to not be implementation-specific type. @see @ref isMeshIndexTypeImplementationSpecific() */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData compressIndices(const Trade::MeshData& data, MeshIndexType atLeast = MeshIndexType::UnsignedShort); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData compressIndices(const Trade::MeshData& mesh, MeshIndexType atLeast = MeshIndexType::UnsignedShort); /** @brief Compress mesh data indices @@ -171,7 +171,7 @@ owned) to the returned instance instead of making a copy of it. Index and attribute data are copied always. @see @ref Trade::MeshData::vertexDataFlags() */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData compressIndices(Trade::MeshData&& data, MeshIndexType atLeast = MeshIndexType::UnsignedShort); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData compressIndices(Trade::MeshData&& mesh, MeshIndexType atLeast = MeshIndexType::UnsignedShort); #ifdef MAGNUM_BUILD_DEPRECATED /** diff --git a/src/Magnum/MeshTools/Duplicate.cpp b/src/Magnum/MeshTools/Duplicate.cpp index 1c4b76079..209019862 100644 --- a/src/Magnum/MeshTools/Duplicate.cpp +++ b/src/Magnum/MeshTools/Duplicate.cpp @@ -80,14 +80,14 @@ 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})); - CORRADE_ASSERT(!isMeshIndexTypeImplementationSpecific(data.indexType()), - "MeshTools::duplicate(): mesh has an implementation-specific index type" << reinterpret_cast(meshIndexTypeUnwrap(data.indexType())), +Trade::MeshData duplicate(const Trade::MeshData& mesh, const Containers::ArrayView extra) { + CORRADE_ASSERT(mesh.isIndexed(), "MeshTools::duplicate(): mesh data not indexed", (Trade::MeshData{MeshPrimitive::Triangles, 0})); + CORRADE_ASSERT(!isMeshIndexTypeImplementationSpecific(mesh.indexType()), + "MeshTools::duplicate(): mesh has an implementation-specific index type" << reinterpret_cast(meshIndexTypeUnwrap(mesh.indexType())), (Trade::MeshData{MeshPrimitive{}, 0})); #ifndef CORRADE_NO_ASSERT - for(std::size_t i = 0; i != data.attributeCount(); ++i) { - const VertexFormat format = data.attributeFormat(i); + for(std::size_t i = 0; i != mesh.attributeCount(); ++i) { + const VertexFormat format = mesh.attributeFormat(i); CORRADE_ASSERT(!isVertexFormatImplementationSpecific(format), "MeshTools::duplicate(): attribute" << i << "has an implementation-specific format" << reinterpret_cast(vertexFormatUnwrap(format)), (Trade::MeshData{MeshPrimitive::Points, 0})); @@ -101,14 +101,14 @@ Trade::MeshData duplicate(const Trade::MeshData& data, const Containers::ArrayVi #endif /* Calculate the layout */ - Trade::MeshData layout = interleavedLayout(data, data.indexCount(), extra); + Trade::MeshData layout = interleavedLayout(mesh, mesh.indexCount(), extra); /* Copy existing attributes to new locations */ - for(UnsignedInt i = 0; i != data.attributeCount(); ++i) - duplicateInto(data.indices(), data.attribute(i), layout.mutableAttribute(i)); + for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) + duplicateInto(mesh.indices(), mesh.attribute(i), layout.mutableAttribute(i)); /* Mix in the extra attributes */ - UnsignedInt attributeIndex = data.attributeCount(); + UnsignedInt attributeIndex = mesh.attributeCount(); for(UnsignedInt i = 0; i != extra.size(); ++i) { /* Padding, ignore */ if(extra[i].format() == VertexFormat{}) continue; @@ -122,13 +122,13 @@ Trade::MeshData duplicate(const Trade::MeshData& data, const Containers::ArrayVi /* Copy the attribute in, if it is non-empty, otherwise keep the memory uninitialized */ if(extra[i].data()) { - CORRADE_ASSERT(extra[i].data().size() == data.vertexCount(), - "MeshTools::duplicate(): extra attribute" << i << "expected to have" << data.vertexCount() << "items but got" << extra[i].data().size(), + CORRADE_ASSERT(extra[i].data().size() == mesh.vertexCount(), + "MeshTools::duplicate(): extra attribute" << i << "expected to have" << mesh.vertexCount() << "items but got" << extra[i].data().size(), (Trade::MeshData{MeshPrimitive::Triangles, 0})); const Containers::StridedArrayView2D attributeData = Containers::arrayCast<2, const char>(extra[i].data(), vertexFormatSize(extra[i].format())*Math::max(extra[i].arraySize(), UnsignedShort{1})); - duplicateInto(data.indices(), attributeData, layout.mutableAttribute(attributeIndex)); + duplicateInto(mesh.indices(), attributeData, layout.mutableAttribute(attributeIndex)); } ++attributeIndex; @@ -137,8 +137,8 @@ Trade::MeshData duplicate(const Trade::MeshData& data, const Containers::ArrayVi return layout; } -Trade::MeshData duplicate(const Trade::MeshData& data, std::initializer_list extra) { - return duplicate(data, Containers::arrayView(extra)); +Trade::MeshData duplicate(const Trade::MeshData& mesh, std::initializer_list extra) { + return duplicate(mesh, Containers::arrayView(extra)); } }} diff --git a/src/Magnum/MeshTools/Duplicate.h b/src/Magnum/MeshTools/Duplicate.h index f894d5110..1883dc679 100644 --- a/src/Magnum/MeshTools/Duplicate.h +++ b/src/Magnum/MeshTools/Duplicate.h @@ -135,8 +135,8 @@ MAGNUM_MESHTOOLS_EXPORT void duplicateInto(const Containers::StridedArrayView2D< @brief Duplicate indexed mesh data @m_since{2020,06} -Returns a copy of @p data that's not indexed and has all attributes interleaved -and duplicated according to @p data's index buffer. The @p extra attributes, if +Returns a copy of @p mesh that's not indexed and has all attributes interleaved +and duplicated according to @p mesh's index buffer. The @p extra attributes, if any, are duplicated and interleaved together with existing attributes (or, in case the attribute view is empty, only the corresponding space for given attribute type is reserved, with memory left uninitialized). The data layouting @@ -144,21 +144,21 @@ is done by @ref interleavedLayout(), see its documentation for detailed behavior description. Note that offset-only @ref Trade::MeshAttributeData instances are not supported in the @p extra array. -Expects that @p data is indexed with a non-implementation-specific index type +Expects that @p mesh is indexed with a non-implementation-specific index type and each attribute in @p extra has either the same amount of elements as -@p data vertex count (*not* index count) or has none. All attributes are +@p mesh vertex count (*not* index count) or has none. All attributes are expected to not have an implementation-specific format. @see @ref isMeshIndexTypeImplementationSpecific(), @ref isVertexFormatImplementationSpecific(), @ref Trade::MeshData::attributeData() */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData duplicate(const Trade::MeshData& data, Containers::ArrayView extra = {}); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData duplicate(const Trade::MeshData& mesh, Containers::ArrayView extra = {}); /** * @overload * @m_since{2020,06} */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData duplicate(const Trade::MeshData& data, std::initializer_list extra); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData duplicate(const Trade::MeshData& mesh, std::initializer_list extra); template inline void duplicateInto(const Containers::StridedArrayView1D& indices, const Containers::StridedArrayView1D& data, const Containers::StridedArrayView1D& out) { duplicateInto(indices, Containers::arrayCast<2, const char>(data), Containers::arrayCast<2, char>(out)); diff --git a/src/Magnum/MeshTools/FilterAttributes.cpp b/src/Magnum/MeshTools/FilterAttributes.cpp index 871dc1ae8..c803b9263 100644 --- a/src/Magnum/MeshTools/FilterAttributes.cpp +++ b/src/Magnum/MeshTools/FilterAttributes.cpp @@ -49,7 +49,7 @@ bool hasAttribute(const Containers::ArrayView attributes, con } -Trade::MeshData filterOnlyAttributes(const Trade::MeshData& data, const Containers::ArrayView attributes) { +Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, const Containers::ArrayView attributes) { /* Not asserting here for existence of attributes since that'd be another O(n^2) operation */ /** @todo but that's not consistent with the ID-based variant, or maybe do @@ -58,10 +58,10 @@ Trade::MeshData filterOnlyAttributes(const Trade::MeshData& data, const Containe /* Pick just attributes from the list */ Containers::Array filtered; - arrayReserve(filtered, data.attributeCount()); - for(UnsignedInt i = 0; i != data.attributeCount(); ++i) { - if(hasAttribute(attributes, data.attributeName(i))) - arrayAppend(filtered, data.attributeData(i)); + arrayReserve(filtered, mesh.attributeCount()); + for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) { + if(hasAttribute(attributes, mesh.attributeName(i))) + arrayAppend(filtered, mesh.attributeData(i)); } /* Convert back to a default deleter to make this usable in plugins */ @@ -72,37 +72,37 @@ Trade::MeshData filterOnlyAttributes(const Trade::MeshData& data, const Containe Trade::meshIndexData{data.indexType(), view} because asking for index type would assert on non-indexed meshes. */ Trade::MeshIndexData indices; - if(data.isIndexed()) indices = Trade::MeshIndexData{ - data.indexType(), + if(mesh.isIndexed()) indices = Trade::MeshIndexData{ + mesh.indexType(), Containers::StridedArrayView1D{ - data.indexData(), - data.indexData().data() + data.indexOffset(), - data.indexCount(), - data.indexStride()}}; - - return Trade::MeshData{data.primitive(), - {}, data.indexData(), indices, - {}, data.vertexData(), std::move(filtered), - data.vertexCount()}; + mesh.indexData(), + mesh.indexData().data() + mesh.indexOffset(), + mesh.indexCount(), + mesh.indexStride()}}; + + return Trade::MeshData{mesh.primitive(), + {}, mesh.indexData(), indices, + {}, mesh.vertexData(), std::move(filtered), + mesh.vertexCount()}; } -Trade::MeshData filterOnlyAttributes(const Trade::MeshData& data, std::initializer_list attributes) { - return filterOnlyAttributes(data, Containers::arrayView(attributes)); +Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, std::initializer_list attributes) { + return filterOnlyAttributes(mesh, Containers::arrayView(attributes)); } -Trade::MeshData filterOnlyAttributes(const Trade::MeshData& data, const Containers::ArrayView attributes) { +Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, const Containers::ArrayView attributes) { #ifndef CORRADE_NO_ASSERT - for(const UnsignedInt i: attributes) CORRADE_ASSERT(i < data.attributeCount(), - "MeshTools::filterOnlyAttributes(): index" << i << "out of range for" << data.attributeCount() << "attributes", + for(const UnsignedInt i: attributes) CORRADE_ASSERT(i < mesh.attributeCount(), + "MeshTools::filterOnlyAttributes(): index" << i << "out of range for" << mesh.attributeCount() << "attributes", (Trade::MeshData{MeshPrimitive{}, 0})); #endif /* Pick just attributes from the list */ Containers::Array filtered; - arrayReserve(filtered, data.attributeCount()); - for(UnsignedInt i = 0; i != data.attributeCount(); ++i) { + arrayReserve(filtered, mesh.attributeCount()); + for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) { if(hasAttribute(attributes, i)) - arrayAppend(filtered, data.attributeData(i)); + arrayAppend(filtered, mesh.attributeData(i)); } /* Convert back to a default deleter to make this usable in plugins */ @@ -113,25 +113,25 @@ Trade::MeshData filterOnlyAttributes(const Trade::MeshData& data, const Containe Trade::meshIndexData{data.indexType(), view} because asking for index type would assert on non-indexed meshes. */ Trade::MeshIndexData indices; - if(data.isIndexed()) indices = Trade::MeshIndexData{ - data.indexType(), + if(mesh.isIndexed()) indices = Trade::MeshIndexData{ + mesh.indexType(), Containers::StridedArrayView1D{ - data.indexData(), - data.indexData().data() + data.indexOffset(), - data.indexCount(), - data.indexStride()}}; - - return Trade::MeshData{data.primitive(), - {}, data.indexData(), indices, - {}, data.vertexData(), std::move(filtered), - data.vertexCount()}; + mesh.indexData(), + mesh.indexData().data() + mesh.indexOffset(), + mesh.indexCount(), + mesh.indexStride()}}; + + return Trade::MeshData{mesh.primitive(), + {}, mesh.indexData(), indices, + {}, mesh.vertexData(), std::move(filtered), + mesh.vertexCount()}; } -Trade::MeshData filterOnlyAttributes(const Trade::MeshData& data, std::initializer_list attributes) { - return filterOnlyAttributes(data, Containers::arrayView(attributes)); +Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, std::initializer_list attributes) { + return filterOnlyAttributes(mesh, Containers::arrayView(attributes)); } -Trade::MeshData filterExceptAttributes(const Trade::MeshData& data, const Containers::ArrayView attributes) { +Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, const Containers::ArrayView attributes) { /* Not asserting here for existence of attributes since that'd be another O(n^2) operation */ /** @todo but that's not consistent with the ID-based variant, or maybe do @@ -140,10 +140,10 @@ Trade::MeshData filterExceptAttributes(const Trade::MeshData& data, const Contai /* Pick just attributes from the list */ Containers::Array filtered; - arrayReserve(filtered, data.attributeCount()); - for(UnsignedInt i = 0; i != data.attributeCount(); ++i) { - if(!hasAttribute(attributes, data.attributeName(i))) - arrayAppend(filtered, data.attributeData(i)); + arrayReserve(filtered, mesh.attributeCount()); + for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) { + if(!hasAttribute(attributes, mesh.attributeName(i))) + arrayAppend(filtered, mesh.attributeData(i)); } /* Convert back to a default deleter to make this usable in plugins */ @@ -154,37 +154,37 @@ Trade::MeshData filterExceptAttributes(const Trade::MeshData& data, const Contai Trade::meshIndexData{data.indexType(), view} because asking for index type would assert on non-indexed meshes. */ Trade::MeshIndexData indices; - if(data.isIndexed()) indices = Trade::MeshIndexData{ - data.indexType(), + if(mesh.isIndexed()) indices = Trade::MeshIndexData{ + mesh.indexType(), Containers::StridedArrayView1D{ - data.indexData(), - data.indexData().data() + data.indexOffset(), - data.indexCount(), - data.indexStride()}}; - - return Trade::MeshData{data.primitive(), - {}, data.indexData(), indices, - {}, data.vertexData(), std::move(filtered), - data.vertexCount()}; + mesh.indexData(), + mesh.indexData().data() + mesh.indexOffset(), + mesh.indexCount(), + mesh.indexStride()}}; + + return Trade::MeshData{mesh.primitive(), + {}, mesh.indexData(), indices, + {}, mesh.vertexData(), std::move(filtered), + mesh.vertexCount()}; } -Trade::MeshData filterExceptAttributes(const Trade::MeshData& data, std::initializer_list attributes) { - return filterExceptAttributes(data, Containers::arrayView(attributes)); +Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, std::initializer_list attributes) { + return filterExceptAttributes(mesh, Containers::arrayView(attributes)); } -Trade::MeshData filterExceptAttributes(const Trade::MeshData& data, const Containers::ArrayView attributes) { +Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, const Containers::ArrayView attributes) { #ifndef CORRADE_NO_ASSERT - for(const UnsignedInt i: attributes) CORRADE_ASSERT(i < data.attributeCount(), - "MeshTools::filterExceptAttributes(): index" << i << "out of range for" << data.attributeCount() << "attributes", + for(const UnsignedInt i: attributes) CORRADE_ASSERT(i < mesh.attributeCount(), + "MeshTools::filterExceptAttributes(): index" << i << "out of range for" << mesh.attributeCount() << "attributes", (Trade::MeshData{MeshPrimitive{}, 0})); #endif /* Pick just attributes from the list */ Containers::Array filtered; - arrayReserve(filtered, data.attributeCount()); - for(UnsignedInt i = 0; i != data.attributeCount(); ++i) { + arrayReserve(filtered, mesh.attributeCount()); + for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) { if(!hasAttribute(attributes, i)) - arrayAppend(filtered, data.attributeData(i)); + arrayAppend(filtered, mesh.attributeData(i)); } /* Convert back to a default deleter to make this usable in plugins */ @@ -195,22 +195,22 @@ Trade::MeshData filterExceptAttributes(const Trade::MeshData& data, const Contai Trade::meshIndexData{data.indexType(), view} because asking for index type would assert on non-indexed meshes. */ Trade::MeshIndexData indices; - if(data.isIndexed()) indices = Trade::MeshIndexData{ - data.indexType(), + if(mesh.isIndexed()) indices = Trade::MeshIndexData{ + mesh.indexType(), Containers::StridedArrayView1D{ - data.indexData(), - data.indexData().data() + data.indexOffset(), - data.indexCount(), - data.indexStride()}}; - - return Trade::MeshData{data.primitive(), - {}, data.indexData(), indices, - {}, data.vertexData(), std::move(filtered), - data.vertexCount()}; + mesh.indexData(), + mesh.indexData().data() + mesh.indexOffset(), + mesh.indexCount(), + mesh.indexStride()}}; + + return Trade::MeshData{mesh.primitive(), + {}, mesh.indexData(), indices, + {}, mesh.vertexData(), std::move(filtered), + mesh.vertexCount()}; } -Trade::MeshData filterExceptAttributes(const Trade::MeshData& data, std::initializer_list attributes) { - return filterExceptAttributes(data, Containers::arrayView(attributes)); +Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, std::initializer_list attributes) { + return filterExceptAttributes(mesh, Containers::arrayView(attributes)); } }} diff --git a/src/Magnum/MeshTools/FilterAttributes.h b/src/Magnum/MeshTools/FilterAttributes.h index 8eedd0468..e43664254 100644 --- a/src/Magnum/MeshTools/FilterAttributes.h +++ b/src/Magnum/MeshTools/FilterAttributes.h @@ -41,10 +41,10 @@ namespace Magnum { namespace MeshTools { @brief Filter a mesh to contain only the selected subset of named attributes @m_since_latest -Returns a non-owning reference to the vertex and index buffer from @p data with +Returns a non-owning reference to the vertex and index buffer from @p mesh with only the attributes that are listed in @p attributes. The index buffer, if present, is left untouched. Attributes from the list that are not present in -@p data are skipped. All duplicates of a listed attribute are kept --- if you +@p mesh are skipped. All duplicates of a listed attribute are kept --- if you want a different behavior, use the @ref filterOnlyAttributes(const Trade::MeshData&, Containers::ArrayView) overload and pick attributes by their IDs instead. @@ -54,19 +54,19 @@ the output to @ref interleave(const Trade::MeshData&, Containers::ArrayView attributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, Containers::ArrayView attributes); /** * @overload * @m_since_latest */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterOnlyAttributes(const Trade::MeshData& data, std::initializer_list attributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, std::initializer_list attributes); /** @brief Filter a mesh to contain only the selected subset of attributes @m_since_latest -Returns a non-owning reference to the vertex and index buffer from @p data with +Returns a non-owning reference to the vertex and index buffer from @p mesh with only the attribute IDs listed in @p attributes. IDs specified more than once don't result in given attribute being added multiple times. The index buffer, if present, is left untouched. All attribute IDs are expected to be smaller @@ -78,44 +78,44 @@ the output to @ref interleave(const Trade::MeshData&, Containers::ArrayView attributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, Containers::ArrayView attributes); /** * @overload * @m_since_latest */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterOnlyAttributes(const Trade::MeshData& data, std::initializer_list attributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, std::initializer_list attributes); /** @brief Filter a mesh to contain everything except the selected subset of named attributes @m_since_latest -Returns a non-owning reference to the vertex and index buffer from @p data with +Returns a non-owning reference to the vertex and index buffer from @p mesh with only the attributes that are not listed in @p attributes. The index buffer, if present, is left untouched. Attributes from the list that are not present in -@p data are skipped. All duplicates of a listed attribute are removed --- if +@p mesh are skipped. All duplicates of a listed attribute are removed --- if you want a different behavior, use the @ref filterExceptAttributes(const Trade::MeshData&, Containers::ArrayView) overload and pick attributes by their IDs instead. If @p attributes is empty, the behavior is equivalent to @ref reference(). This function only operates on the attribute metadata --- if you'd like to have -the vertex data repacked to contain just the remaining attributes as well, pass +the vertex mesh repacked to contain just the remaining attributes as well, pass the output to @ref interleave(const Trade::MeshData&, Containers::ArrayView, InterleaveFlags) "interleave()" without @ref InterleaveFlag::PreserveInterleavedAttributes set. */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterExceptAttributes(const Trade::MeshData& data, Containers::ArrayView attributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, Containers::ArrayView attributes); /** * @overload * @m_since_latest */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterExceptAttributes(const Trade::MeshData& data, std::initializer_list attributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, std::initializer_list attributes); /** @brief Filter a mesh to contain everything except the selected subset of attributes @m_since_latest -Returns a non-owning reference to the vertex and index buffer from @p data with +Returns a non-owning reference to the vertex and index buffer from @p mesh with only the attribute IDs that are not listed in @p attributes. IDs specified multiple times behave like if specified just once. The index buffer, if present, is left untouched. All attribute IDs are expected to be smaller than @@ -127,13 +127,13 @@ the vertex data repacked to contain just the remaining attributes as well, pass the output to @ref interleave(const Trade::MeshData&, Containers::ArrayView, InterleaveFlags) "interleave()" without @ref InterleaveFlag::PreserveInterleavedAttributes set. */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterExceptAttributes(const Trade::MeshData& data, Containers::ArrayView attributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, Containers::ArrayView attributes); /** * @overload * @m_since_latest */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterExceptAttributes(const Trade::MeshData& data, std::initializer_list attributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, std::initializer_list attributes); }} diff --git a/src/Magnum/MeshTools/GenerateIndices.cpp b/src/Magnum/MeshTools/GenerateIndices.cpp index 5ab1371f8..2a4815638 100644 --- a/src/Magnum/MeshTools/GenerateIndices.cpp +++ b/src/Magnum/MeshTools/GenerateIndices.cpp @@ -576,77 +576,77 @@ void generateQuadIndicesInto(const Containers::StridedArrayView1D return generateQuadIndicesIntoImplementation(positions, quads, output); } -Trade::MeshData generateIndices(Trade::MeshData&& data) { - CORRADE_ASSERT(!data.isIndexed() || !isMeshIndexTypeImplementationSpecific(data.indexType()), - "MeshTools::generateIndices(): mesh has an implementation-specific index type" << reinterpret_cast(meshIndexTypeUnwrap(data.indexType())), +Trade::MeshData generateIndices(Trade::MeshData&& mesh) { + CORRADE_ASSERT(!mesh.isIndexed() || !isMeshIndexTypeImplementationSpecific(mesh.indexType()), + "MeshTools::generateIndices(): mesh has an implementation-specific index type" << reinterpret_cast(meshIndexTypeUnwrap(mesh.indexType())), (Trade::MeshData{MeshPrimitive{}, 0})); - const UnsignedInt vertexCount = data.vertexCount(); + const UnsignedInt vertexCount = mesh.vertexCount(); #ifndef CORRADE_NO_ASSERT UnsignedInt minVertexCount; - if(data.primitive() == MeshPrimitive::LineStrip || - data.primitive() == MeshPrimitive::LineLoop) { + if(mesh.primitive() == MeshPrimitive::LineStrip || + mesh.primitive() == MeshPrimitive::LineLoop) { minVertexCount = 2; - } else if(data.primitive() == MeshPrimitive::TriangleStrip || - data.primitive() == MeshPrimitive::TriangleFan) { + } else if(mesh.primitive() == MeshPrimitive::TriangleStrip || + mesh.primitive() == MeshPrimitive::TriangleFan) { minVertexCount = 3; - } else CORRADE_ASSERT_UNREACHABLE("MeshTools::generateIndices(): invalid primitive" << data.primitive(), + } else CORRADE_ASSERT_UNREACHABLE("MeshTools::generateIndices(): invalid primitive" << mesh.primitive(), (Trade::MeshData{MeshPrimitive::Triangles, 0})); CORRADE_ASSERT(vertexCount == 0 || vertexCount >= minVertexCount, - "MeshTools::generateIndices(): expected either zero or at least" << minVertexCount << "vertices for" << data.primitive() << Debug::nospace << ", got" << vertexCount, + "MeshTools::generateIndices(): expected either zero or at least" << minVertexCount << "vertices for" << mesh.primitive() << Debug::nospace << ", got" << vertexCount, (Trade::MeshData{MeshPrimitive::Triangles, 0})); #endif /* Transfer vertex / attribute data as-is, as those don't need any changes. Release if possible. */ Containers::Array vertexData; - if(data.vertexDataFlags() & Trade::DataFlag::Owned) - vertexData = data.releaseVertexData(); + if(mesh.vertexDataFlags() & Trade::DataFlag::Owned) + vertexData = mesh.releaseVertexData(); else { - vertexData = Containers::Array{NoInit, data.vertexData().size()}; - Utility::copy(data.vertexData(), vertexData); + vertexData = Containers::Array{NoInit, mesh.vertexData().size()}; + Utility::copy(mesh.vertexData(), vertexData); } /* Recreate the attribute array with views on the new vertexData */ /** @todo if the vertex data were moved and this array is owned, it wouldn't need to be recreated, but the logic is a bit complex */ - Containers::Array attributeData{data.attributeCount()}; + Containers::Array attributeData{mesh.attributeCount()}; for(UnsignedInt i = 0, max = attributeData.size(); i != max; ++i) { - attributeData[i] = Trade::MeshAttributeData{data.attributeName(i), - data.attributeFormat(i), - Containers::StridedArrayView1D{vertexData, vertexData.data() + data.attributeOffset(i), vertexCount, data.attributeStride(i)}, - data.attributeArraySize(i)}; + attributeData[i] = Trade::MeshAttributeData{mesh.attributeName(i), + mesh.attributeFormat(i), + Containers::StridedArrayView1D{vertexData, vertexData.data() + mesh.attributeOffset(i), vertexCount, mesh.attributeStride(i)}, + mesh.attributeArraySize(i)}; } /* Generate the index array */ MeshPrimitive primitive; Containers::Array indexData; - if(data.primitive() == MeshPrimitive::LineStrip) { + if(mesh.primitive() == MeshPrimitive::LineStrip) { primitive = MeshPrimitive::Lines; indexData = Containers::Array{NoInit, 2*(Math::max(vertexCount, 1u) - 1)*sizeof(UnsignedInt)}; - if(data.isIndexed()) - generateLineStripIndicesInto(data.indices(), Containers::arrayCast(indexData)); + if(mesh.isIndexed()) + generateLineStripIndicesInto(mesh.indices(), Containers::arrayCast(indexData)); else generateLineStripIndicesInto(vertexCount, Containers::arrayCast(indexData)); - } else if(data.primitive() == MeshPrimitive::LineLoop) { + } else if(mesh.primitive() == MeshPrimitive::LineLoop) { primitive = MeshPrimitive::Lines; indexData = Containers::Array{NoInit, 2*vertexCount*sizeof(UnsignedInt)}; - if(data.isIndexed()) - generateLineLoopIndicesInto(data.indices(), Containers::arrayCast(indexData)); + if(mesh.isIndexed()) + generateLineLoopIndicesInto(mesh.indices(), Containers::arrayCast(indexData)); else generateLineLoopIndicesInto(vertexCount, Containers::arrayCast(indexData)); - } else if(data.primitive() == MeshPrimitive::TriangleStrip) { + } else if(mesh.primitive() == MeshPrimitive::TriangleStrip) { primitive = MeshPrimitive::Triangles; indexData = Containers::Array{NoInit, 3*(Math::max(vertexCount, 2u) - 2)*sizeof(UnsignedInt)}; - if(data.isIndexed()) - generateTriangleStripIndicesInto(data.indices(), Containers::arrayCast(indexData)); + if(mesh.isIndexed()) + generateTriangleStripIndicesInto(mesh.indices(), Containers::arrayCast(indexData)); else generateTriangleStripIndicesInto(vertexCount, Containers::arrayCast(indexData)); - } else if(data.primitive() == MeshPrimitive::TriangleFan) { + } else if(mesh.primitive() == MeshPrimitive::TriangleFan) { primitive = MeshPrimitive::Triangles; indexData = Containers::Array{NoInit, 3*(Math::max(vertexCount, 2u) - 2)*sizeof(UnsignedInt)}; - if(data.isIndexed()) - generateTriangleFanIndicesInto(data.indices(), Containers::arrayCast(indexData)); + if(mesh.isIndexed()) + generateTriangleFanIndicesInto(mesh.indices(), Containers::arrayCast(indexData)); else generateTriangleFanIndicesInto(vertexCount, Containers::arrayCast(indexData)); } else CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ @@ -656,10 +656,10 @@ Trade::MeshData generateIndices(Trade::MeshData&& data) { std::move(vertexData), std::move(attributeData), vertexCount}; } -Trade::MeshData generateIndices(const Trade::MeshData& data) { +Trade::MeshData generateIndices(const Trade::MeshData& mesh) { /* Pass through to the && overload, which then decides whether to reuse anything based on the DataFlags */ - return generateIndices(reference(data)); + return generateIndices(reference(mesh)); } }} diff --git a/src/Magnum/MeshTools/GenerateIndices.h b/src/Magnum/MeshTools/GenerateIndices.h index 059bbcb4a..16e9fb42a 100644 --- a/src/Magnum/MeshTools/GenerateIndices.h +++ b/src/Magnum/MeshTools/GenerateIndices.h @@ -508,12 +508,12 @@ MAGNUM_MESHTOOLS_EXPORT Trade::MeshData generateIndices(const Trade::MeshData& m @m_since{2020,06} Compared to @ref generateIndices(const Trade::MeshData&) this function can -transfer ownership of @p data vertex buffer (in case it is owned) to the +transfer ownership of @p mesh vertex buffer (in case it is owned) to the returned instance instead of making a copy of it. Attribute data is copied always. @see @ref Trade::MeshData::vertexDataFlags() */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData generateIndices(Trade::MeshData&& data); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData generateIndices(Trade::MeshData&& mesh); }} diff --git a/src/Magnum/MeshTools/Interleave.cpp b/src/Magnum/MeshTools/Interleave.cpp index 5cf734497..173c5ccc1 100644 --- a/src/Magnum/MeshTools/Interleave.cpp +++ b/src/Magnum/MeshTools/Interleave.cpp @@ -36,41 +36,41 @@ namespace Magnum { namespace MeshTools { namespace { -inline std::size_t attributeSize(const Trade::MeshData& data, UnsignedInt i) { - return vertexFormatSize(data.attributeFormat(i))*Math::max(data.attributeArraySize(i), UnsignedShort{1}); +inline std::size_t attributeSize(const Trade::MeshData& mesh, UnsignedInt i) { + return vertexFormatSize(mesh.attributeFormat(i))*Math::max(mesh.attributeArraySize(i), UnsignedShort{1}); } -inline std::size_t attributeSize(const Trade::MeshAttributeData& data) { - return vertexFormatSize(data.format())*Math::max(data.arraySize(), UnsignedShort{1}); +inline std::size_t attributeSize(const Trade::MeshAttributeData& mesh) { + return vertexFormatSize(mesh.format())*Math::max(mesh.arraySize(), UnsignedShort{1}); } -Containers::Optional> interleavedDataInternal(const Trade::MeshData& data) { +Containers::Optional> interleavedDataInternal(const Trade::MeshData& mesh) { /* There is no attributes, return a zero-sized view to indicate a success */ - if(!data.attributeCount()) - return Containers::StridedArrayView2D{data.vertexData(), {data.vertexCount(), 0}}; + if(!mesh.attributeCount()) + return Containers::StridedArrayView2D{mesh.vertexData(), {mesh.vertexCount(), 0}}; /* Technically zero and negative strides *may* also be categorized as interleaved if they are all the same, but it causes way too many problems especially when used within interleavedLayout() etc. May tackle properly later. */ - const Int stride = data.attributeStride(0); + const Int stride = mesh.attributeStride(0); if(stride <= 0) return Containers::NullOpt; std::size_t minOffset = ~std::size_t{}; std::size_t maxOffset = 0; bool hasImplementationSpecificVertexFormat = false; - for(UnsignedInt i = 0; i != data.attributeCount(); ++i) { - if(data.attributeStride(i) != stride) return Containers::NullOpt; + for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) { + if(mesh.attributeStride(i) != stride) return Containers::NullOpt; - const std::size_t offset = data.attributeOffset(i); + const std::size_t offset = mesh.attributeOffset(i); minOffset = Math::min(minOffset, offset); /* If the attribute has implementation-specific format, remember that for later and optimistically use size of 1 byte for calculations */ std::size_t size; - if(isVertexFormatImplementationSpecific(data.attributeFormat(i))) { + if(isVertexFormatImplementationSpecific(mesh.attributeFormat(i))) { hasImplementationSpecificVertexFormat = true; size = 1; - } else size = attributeSize(data, i); + } else size = attributeSize(mesh, i); maxOffset = Math::max(maxOffset, offset + size); } @@ -87,26 +87,26 @@ Containers::Optional> interleavedData if(maxOffset - minOffset > UnsignedInt(stride)) return Containers::NullOpt; return Containers::StridedArrayView2D{ - data.vertexData(), data.vertexData().data() + minOffset, - {data.vertexCount(), maxOffset - minOffset}, + mesh.vertexData(), mesh.vertexData().data() + minOffset, + {mesh.vertexCount(), maxOffset - minOffset}, {std::ptrdiff_t(stride), 1}}; } } -bool isInterleaved(const Trade::MeshData& data) { - return !!interleavedDataInternal(data); +bool isInterleaved(const Trade::MeshData& mesh) { + return !!interleavedDataInternal(mesh); } -Containers::StridedArrayView2D interleavedData(const Trade::MeshData& data) { - auto out = interleavedDataInternal(data); +Containers::StridedArrayView2D interleavedData(const Trade::MeshData& mesh) { + auto out = interleavedDataInternal(mesh); CORRADE_ASSERT(out, "MeshTools::interleavedData(): the mesh is not interleaved", {}); return *out; } -Containers::StridedArrayView2D interleavedMutableData(Trade::MeshData& data) { - Containers::StridedArrayView2D out = interleavedData(data); - CORRADE_ASSERT(data.vertexDataFlags() & Trade::DataFlag::Mutable, +Containers::StridedArrayView2D interleavedMutableData(Trade::MeshData& mesh) { + Containers::StridedArrayView2D out = interleavedData(mesh); + CORRADE_ASSERT(mesh.vertexDataFlags() & Trade::DataFlag::Mutable, "MeshTools::interleavedMutableData(): vertex data is not mutable", {}); return Containers::StridedArrayView2D{ {nullptr, ~std::size_t{}}, /* to sidestep the range assertions */ @@ -116,32 +116,32 @@ Containers::StridedArrayView2D interleavedMutableData(Trade::MeshData& dat namespace Implementation { -Containers::Array interleavedLayout(Trade::MeshData&& data, const Containers::ArrayView extra, const InterleaveFlags flags) { +Containers::Array interleavedLayout(Trade::MeshData&& mesh, const Containers::ArrayView extra, const InterleaveFlags flags) { /* Nothing to do here, bye! */ - if(!data.attributeCount() && extra.isEmpty()) return {}; + if(!mesh.attributeCount() && extra.isEmpty()) return {}; /* If we're not told to preserve the layout, treat the mesh as noninterleaved always, forcing a repack. Otherwise check if it's already interleaved. */ - const bool interleaved = flags >= InterleaveFlag::PreserveInterleavedAttributes && isInterleaved(data); + const bool interleaved = flags >= InterleaveFlag::PreserveInterleavedAttributes && isInterleaved(mesh); /* If the mesh is already interleaved, use the original stride to preserve all padding, but remove the initial offset. Otherwise calculate a tightly-packed stride. */ std::size_t stride; std::size_t minOffset; - if(interleaved && data.attributeCount()) { - stride = data.attributeStride(0); + if(interleaved && mesh.attributeCount()) { + stride = mesh.attributeStride(0); minOffset = ~std::size_t{}; - for(UnsignedInt i = 0, max = data.attributeCount(); i != max; ++i) - minOffset = Math::min(minOffset, data.attributeOffset(i)); + for(UnsignedInt i = 0, max = mesh.attributeCount(); i != max; ++i) + minOffset = Math::min(minOffset, mesh.attributeOffset(i)); } else { stride = 0; minOffset = 0; - for(UnsignedInt i = 0, max = data.attributeCount(); i != max; ++i) { - CORRADE_ASSERT(!isVertexFormatImplementationSpecific(data.attributeFormat(i)), - "MeshTools::interleavedLayout(): attribute" << i << "has an implementation-specific format" << reinterpret_cast(vertexFormatUnwrap(data.attributeFormat(i))), {}); - stride += attributeSize(data, i); + for(UnsignedInt i = 0, max = mesh.attributeCount(); i != max; ++i) { + CORRADE_ASSERT(!isVertexFormatImplementationSpecific(mesh.attributeFormat(i)), + "MeshTools::interleavedLayout(): attribute" << i << "has an implementation-specific format" << reinterpret_cast(vertexFormatUnwrap(mesh.attributeFormat(i))), {}); + stride += attributeSize(mesh, i); } } @@ -166,11 +166,11 @@ Containers::Array interleavedLayout(Trade::MeshData&& can take over the ownership and avoid an allocation. Otherwise we allocate a new array and copy the prefix over so we can just patch the data array later. */ - const UnsignedInt originalAttributeCount = data.attributeCount(); + const UnsignedInt originalAttributeCount = mesh.attributeCount(); const UnsignedInt originalAttributeStride = originalAttributeCount ? - data.attributeStride(0) : 0; + mesh.attributeStride(0) : 0; Containers::Array originalAttributeData = - data.releaseAttributeData(); + mesh.releaseAttributeData(); Containers::Array attributeData; if(!extraAttributeCount && !originalAttributeData.deleter()) attributeData = std::move(originalAttributeData); @@ -183,7 +183,7 @@ Containers::Array interleavedLayout(Trade::MeshData&& preserve relative attribute offsets, otherwise pack tightly. */ std::size_t offset = 0; for(UnsignedInt i = 0; i != originalAttributeCount; ++i) { - if(interleaved) offset = attributeData[i].offset(data.vertexData()) - minOffset; + if(interleaved) offset = attributeData[i].offset(mesh.vertexData()) - minOffset; attributeData[i] = Trade::MeshAttributeData{ attributeData[i].name(), attributeData[i].format(), @@ -219,13 +219,13 @@ Containers::Array interleavedLayout(Trade::MeshData&& } -Trade::MeshData interleavedLayout(Trade::MeshData&& data, const UnsignedInt vertexCount, const Containers::ArrayView extra, const InterleaveFlags flags) { - Containers::Array attributeData = Implementation::interleavedLayout(std::move(data), extra, flags); +Trade::MeshData interleavedLayout(Trade::MeshData&& mesh, const UnsignedInt vertexCount, const Containers::ArrayView extra, const InterleaveFlags flags) { + Containers::Array attributeData = Implementation::interleavedLayout(std::move(mesh), extra, flags); /* If there are no attributes, bail -- return an empty mesh with desired vertex count but nothing else */ if(!attributeData) - return Trade::MeshData{data.primitive(), vertexCount}; + return Trade::MeshData{mesh.primitive(), vertexCount}; /* Allocate new data array */ Containers::Array vertexData{NoInit, attributeData[0].stride()*vertexCount}; @@ -241,53 +241,53 @@ Trade::MeshData interleavedLayout(Trade::MeshData&& data, const UnsignedInt vert attribute.arraySize()}; } - return Trade::MeshData{data.primitive(), std::move(vertexData), std::move(attributeData)}; + return Trade::MeshData{mesh.primitive(), std::move(vertexData), std::move(attributeData)}; } -Trade::MeshData interleavedLayout(Trade::MeshData&& data, const UnsignedInt vertexCount, const std::initializer_list extra, const InterleaveFlags flags) { - return interleavedLayout(std::move(data), vertexCount, Containers::arrayView(extra), flags); +Trade::MeshData interleavedLayout(Trade::MeshData&& mesh, const UnsignedInt vertexCount, const std::initializer_list extra, const InterleaveFlags flags) { + return interleavedLayout(std::move(mesh), vertexCount, Containers::arrayView(extra), flags); } -Trade::MeshData interleavedLayout(const Trade::MeshData& data, const UnsignedInt vertexCount, const Containers::ArrayView extra, const InterleaveFlags flags) { +Trade::MeshData interleavedLayout(const Trade::MeshData& mesh, const UnsignedInt vertexCount, const Containers::ArrayView extra, const InterleaveFlags flags) { /* Pass through to the && overload, which then decides whether to reuse anything based on the DataFlags */ - return interleavedLayout(reference(data), vertexCount, extra, flags); + return interleavedLayout(reference(mesh), vertexCount, extra, flags); } -Trade::MeshData interleavedLayout(const Trade::MeshData& data, const UnsignedInt vertexCount, const std::initializer_list extra, const InterleaveFlags flags) { - return interleavedLayout(data, vertexCount, Containers::arrayView(extra), flags); +Trade::MeshData interleavedLayout(const Trade::MeshData& mesh, const UnsignedInt vertexCount, const std::initializer_list extra, const InterleaveFlags flags) { + return interleavedLayout(mesh, vertexCount, Containers::arrayView(extra), flags); } -Trade::MeshData interleave(Trade::MeshData&& data, const Containers::ArrayView extra, const InterleaveFlags flags) { +Trade::MeshData interleave(Trade::MeshData&& mesh, const Containers::ArrayView extra, const InterleaveFlags flags) { /* Transfer the indices unchanged, in case the mesh is indexed */ Containers::Array indexData; Trade::MeshIndexData indices; - if(data.isIndexed()) { - const MeshIndexType indexType = data.indexType(); + if(mesh.isIndexed()) { + const MeshIndexType indexType = mesh.indexType(); /* If we can steal the data and we're allowed to preserve a strided layout or it's tightly packed, do the steal */ - if((data.indexDataFlags() & Trade::DataFlag::Owned) && ((flags & InterleaveFlag::PreserveStridedIndices) || (!isMeshIndexTypeImplementationSpecific(indexType) && data.indexStride() == Int(meshIndexTypeSize(indexType))))) { + if((mesh.indexDataFlags() & Trade::DataFlag::Owned) && ((flags & InterleaveFlag::PreserveStridedIndices) || (!isMeshIndexTypeImplementationSpecific(indexType) && mesh.indexStride() == Int(meshIndexTypeSize(indexType))))) { indices = Trade::MeshIndexData{indexType, Containers::StridedArrayView1D{ - data.indexData(), - data.indexData().data() + data.indexOffset(), - data.indexCount(), - data.indexStride()}}; - indexData = data.releaseIndexData(); + mesh.indexData(), + mesh.indexData().data() + mesh.indexOffset(), + mesh.indexCount(), + mesh.indexStride()}}; + indexData = mesh.releaseIndexData(); /* Otherwise, if we can't steal the data but we're told to preserve strided indices, make a full copy including any extra offsets and paddings */ } else if(flags & InterleaveFlag::PreserveStridedIndices) { - indexData = Containers::Array{NoInit, data.indexData().size()}; + indexData = Containers::Array{NoInit, mesh.indexData().size()}; indices = Trade::MeshIndexData{indexType, Containers::StridedArrayView1D{ indexData, - indexData.data() + data.indexOffset(), - data.indexCount(), - data.indexStride()}}; - Utility::copy(data.indexData(), indexData); + indexData.data() + mesh.indexOffset(), + mesh.indexCount(), + mesh.indexStride()}}; + Utility::copy(mesh.indexData(), indexData); /* Otherwise, make a tightly packed copy, in which case we can't have an implementation-specific index type */ @@ -297,48 +297,48 @@ Trade::MeshData interleave(Trade::MeshData&& data, const Containers::ArrayView{NoInit, data.indexCount()*indexTypeSize}; + indexData = Containers::Array{NoInit, mesh.indexCount()*indexTypeSize}; Containers::StridedArrayView2D out{indexData, - {data.indexCount(), indexTypeSize}, + {mesh.indexCount(), indexTypeSize}, {std::ptrdiff_t(indexTypeSize), 1}}; indices = Trade::MeshIndexData{out}; - Utility::copy(data.indices(), out); + Utility::copy(mesh.indices(), out); } } /* If we're not told to preserve the layout, treat the mesh as noninterleaved always, forcing a repack. Otherwise check if it's already interleaved. */ - const bool interleaved = flags >= InterleaveFlag::PreserveInterleavedAttributes && isInterleaved(data); - const UnsignedInt vertexCount = data.vertexCount(); + const bool interleaved = flags >= InterleaveFlag::PreserveInterleavedAttributes && isInterleaved(mesh); + const UnsignedInt vertexCount = mesh.vertexCount(); /* If the mesh is already interleaved and we don't have anything extra, steal that data as well */ Containers::Array vertexData; Containers::Array attributeData; - if(interleaved && extra.isEmpty() && (data.vertexDataFlags() & Trade::DataFlag::Owned)) { - attributeData = data.releaseAttributeData(); - vertexData = data.releaseVertexData(); + if(interleaved && extra.isEmpty() && (mesh.vertexDataFlags() & Trade::DataFlag::Owned)) { + attributeData = mesh.releaseAttributeData(); + vertexData = mesh.releaseVertexData(); /* Otherwise do it the hard way */ } else { /* Calculate the layout. Can't std::move() the data in to avoid copying the attribute array as we need the original attributes below. */ - Trade::MeshData layout = interleavedLayout(data, vertexCount, extra, flags); + Trade::MeshData layout = interleavedLayout(mesh, vertexCount, extra, flags); #ifdef CORRADE_GRACEFUL_ASSERT /* If interleavedLayout() gracefully asserted and returned no attributes (but the original had some), exit right away to not blow up on something else later. Sorry, yes, this is shitty. */ - if(!layout.attributeCount() && (data.attributeCount() || extra.size())) + if(!layout.attributeCount() && (mesh.attributeCount() || extra.size())) return Trade::MeshData{MeshPrimitive::Points, 0}; #endif /* Copy existing attributes to new locations */ - for(UnsignedInt i = 0; i != data.attributeCount(); ++i) - Utility::copy(data.attribute(i), layout.mutableAttribute(i)); + for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) + Utility::copy(mesh.attribute(i), layout.mutableAttribute(i)); /* Mix in the extra attributes */ - UnsignedInt attributeIndex = data.attributeCount(); + UnsignedInt attributeIndex = mesh.attributeCount(); for(UnsignedInt i = 0; i != extra.size(); ++i) { /* Padding, ignore */ if(extra[i].format() == VertexFormat{}) continue; @@ -368,22 +368,22 @@ Trade::MeshData interleave(Trade::MeshData&& data, const Containers::ArrayView extra, const InterleaveFlags flags) { - return interleave(std::move(data), Containers::arrayView(extra), flags); +Trade::MeshData interleave(Trade::MeshData&& mesh, const std::initializer_list extra, const InterleaveFlags flags) { + return interleave(std::move(mesh), Containers::arrayView(extra), flags); } -Trade::MeshData interleave(const Trade::MeshData& data, const Containers::ArrayView extra, const InterleaveFlags flags) { +Trade::MeshData interleave(const Trade::MeshData& mesh, const Containers::ArrayView extra, const InterleaveFlags flags) { /* Pass through to the && overload, which then decides whether to reuse anything based on the DataFlags */ - return interleave(reference(data), extra, flags); + return interleave(reference(mesh), extra, flags); } -Trade::MeshData interleave(const Trade::MeshData& data, const std::initializer_list extra, const InterleaveFlags flags) { - return interleave(std::move(data), Containers::arrayView(extra), flags); +Trade::MeshData interleave(const Trade::MeshData& mesh, const std::initializer_list extra, const InterleaveFlags flags) { + return interleave(std::move(mesh), Containers::arrayView(extra), flags); } }} diff --git a/src/Magnum/MeshTools/Interleave.h b/src/Magnum/MeshTools/Interleave.h index 299435d79..889bb70f6 100644 --- a/src/Magnum/MeshTools/Interleave.h +++ b/src/Magnum/MeshTools/Interleave.h @@ -204,7 +204,7 @@ non-interleaved. @see @ref Trade::MeshData::attributeStride(), @ref Trade::MeshData::attributeOffset(), @ref interleavedData() */ -MAGNUM_MESHTOOLS_EXPORT bool isInterleaved(const Trade::MeshData& data); +MAGNUM_MESHTOOLS_EXPORT bool isInterleaved(const Trade::MeshData& mesh); /** @brief Type-erased view on interleaved mesh data @@ -219,7 +219,7 @@ count to cover all interleaved attributes, including any padding between them but not before or after. @see @ref isInterleaved() */ -MAGNUM_MESHTOOLS_EXPORT Containers::StridedArrayView2D interleavedData(const Trade::MeshData& data); +MAGNUM_MESHTOOLS_EXPORT Containers::StridedArrayView2D interleavedData(const Trade::MeshData& mesh); /** @brief Mutable type-erased view on interleaved mesh data @@ -229,16 +229,16 @@ 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); +MAGNUM_MESHTOOLS_EXPORT Containers::StridedArrayView2D interleavedMutableData(Trade::MeshData& mesh); /** @brief Create an interleaved mesh layout @m_since{2020,06} Returns a @ref Trade::MeshData instance with its vertex data allocated for -@p vertexCount vertices containing attributes from both @p data and @p extra +@p vertexCount vertices containing attributes from both @p mesh and @p extra interleaved together. No data is actually copied, only an interleaved layout is -created. If @p data is already interleaved according to @ref isInterleaved() +created. If @p mesh is already interleaved according to @ref isInterleaved() and @ref InterleaveFlag::PreserveInterleavedAttributes is set in @p flags, keeps the attributes in the same layout, potentially extending them with @p extra. The @p extra attributes, if any, are interleaved together with @@ -265,42 +265,42 @@ This function will unconditionally allocate a new array to store all @ref Trade::MeshAttributeData, use @ref interleavedLayout(Trade::MeshData&&, UnsignedInt, Containers::ArrayView, InterleaveFlags) to avoid that allocation. -All attributes in both @p data and @p extra are expected to not have an -implementation-specific format, except for @p data attributes in case @p data +All attributes in both @p mesh and @p extra are expected to not have an +implementation-specific format, except for @p mesh attributes in case @p mesh is already interleaved, then the layout is untouched. @see @ref isVertexFormatImplementationSpecific() */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData interleavedLayout(const Trade::MeshData& data, UnsignedInt vertexCount, Containers::ArrayView extra = {}, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData interleavedLayout(const Trade::MeshData& mesh, UnsignedInt vertexCount, Containers::ArrayView extra = {}, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); /** * @overload * @m_since{2020,06} */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData interleavedLayout(const Trade::MeshData& data, UnsignedInt vertexCount, std::initializer_list extra, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData interleavedLayout(const Trade::MeshData& mesh, UnsignedInt vertexCount, std::initializer_list extra, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); /** @brief Create an interleaved mesh layout @m_since{2020,06} Compared to @ref interleavedLayout(const Trade::MeshData&, UnsignedInt, Containers::ArrayView, InterleaveFlags) -this function can reuse the @ref Trade::MeshAttributeData array from @p data +this function can reuse the @ref Trade::MeshAttributeData array from @p mesh instead of allocating a new one if there are no attributes passed in @p extra, the attribute array is owned by the mesh and @ref InterleaveFlag::PreserveInterleavedAttributes is set in @p flags. */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData interleavedLayout(Trade::MeshData&& data, UnsignedInt vertexCount, Containers::ArrayView extra = {}, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData interleavedLayout(Trade::MeshData&& mesh, UnsignedInt vertexCount, Containers::ArrayView extra = {}, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); /** * @overload * @m_since{2020,06} */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData interleavedLayout(Trade::MeshData&& data, UnsignedInt vertexCount, std::initializer_list extra, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData interleavedLayout(Trade::MeshData&& mesh, UnsignedInt vertexCount, std::initializer_list extra, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); /** @brief Interleave mesh data @m_since{2020,06} -Returns a copy of @p data with all attributes interleaved. The @p extra +Returns a copy of @p mesh with all attributes interleaved. The @p extra attributes, if any, are interleaved together with existing attributes (or, in case the attribute view is empty, only the corresponding space for given attribute type is reserved, with memory left uninitialized). The data layouting @@ -314,32 +314,32 @@ implementation-specific type. Otherwise the behavior depends on presence of @ref InterleaveFlag::PreserveStridedIndices. Expects that each attribute in @p extra has either the same amount of elements -as @p data vertex count or has none. This function will unconditionally make a -copy of all data even if @p data is already interleaved and needs no change, +as @p mesh vertex count or has none. This function will unconditionally make a +copy of all data even if @p mesh is already interleaved and needs no change, use @ref interleave(Trade::MeshData&&, Containers::ArrayView, InterleaveFlags) to avoid that copy. -All attributes in both @p data and @p extra are expected to not have an -implementation-specific format, except for @p data attributes in case @p data +All attributes in both @p mesh and @p extra are expected to not have an +implementation-specific format, except for @p mesh attributes in case @p data is already interleaved, then the layout is untouched. @see @ref isInterleaved(), @ref isMeshIndexTypeImplementationSpecific(), @ref isVertexFormatImplementationSpecific(), @ref Trade::MeshData::attributeData() */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData interleave(const Trade::MeshData& data, Containers::ArrayView extra = {}, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData interleave(const Trade::MeshData& mesh, Containers::ArrayView extra = {}, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); /** * @overload * @m_since{2020,06} */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData interleave(const Trade::MeshData& data, std::initializer_list extra, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData interleave(const Trade::MeshData& mesh, std::initializer_list extra, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); /** @brief Interleave mesh data @m_since{2020,06} Compared to @ref interleave(const Trade::MeshData&, Containers::ArrayView, InterleaveFlags) -this function can transfer ownership of @p data index buffer (in case it is +this function can transfer ownership of @p mesh index buffer (in case it is owned) and vertex buffer (in case it is owned, already interleaved, there's no @p extra attributes and @ref InterleaveFlag::PreserveInterleavedAttributes is set in @p flags) to the returned instance instead of making copies of them. @@ -347,18 +347,18 @@ set in @p flags) to the returned instance instead of making copies of them. @ref Trade::MeshData::vertexDataFlags(), @ref Trade::MeshData::attributeData() */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData interleave(Trade::MeshData&& data, Containers::ArrayView extra = {}, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData interleave(Trade::MeshData&& mesh, Containers::ArrayView extra = {}, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); /** * @overload * @m_since{2020,06} */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData interleave(Trade::MeshData&& data, std::initializer_list extra, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData interleave(Trade::MeshData&& mesh, std::initializer_list extra, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); namespace Implementation { /* Used internally by interleavedLayout() and concatenate() */ -MAGNUM_MESHTOOLS_EXPORT Containers::Array interleavedLayout(Trade::MeshData&& data, Containers::ArrayView extra, InterleaveFlags flags); +MAGNUM_MESHTOOLS_EXPORT Containers::Array interleavedLayout(Trade::MeshData&& mesh, Containers::ArrayView extra, InterleaveFlags flags); } diff --git a/src/Magnum/MeshTools/Reference.cpp b/src/Magnum/MeshTools/Reference.cpp index 31563da5e..a3cd80b0b 100644 --- a/src/Magnum/MeshTools/Reference.cpp +++ b/src/Magnum/MeshTools/Reference.cpp @@ -31,28 +31,28 @@ namespace Magnum { namespace MeshTools { -Trade::MeshData reference(const Trade::MeshData& data) { +Trade::MeshData reference(const Trade::MeshData& mesh) { /* Can't do just Trade::MeshIndexData{data.indices()} as that would discard implementation-specific types. And can't do Trade::meshIndexData{data.indexType(), view} because asking for index type would assert on non-indexed meshes. */ Trade::MeshIndexData indices; - if(data.isIndexed()) indices = Trade::MeshIndexData{ - data.indexType(), + if(mesh.isIndexed()) indices = Trade::MeshIndexData{ + mesh.indexType(), Containers::StridedArrayView1D{ - data.indexData(), - data.indexData().data() + data.indexOffset(), - data.indexCount(), - data.indexStride()}}; - - return Trade::MeshData{data.primitive(), - {}, data.indexData(), indices, - {}, data.vertexData(), Trade::meshAttributeDataNonOwningArray(data.attributeData()), - data.vertexCount()}; + mesh.indexData(), + mesh.indexData().data() + mesh.indexOffset(), + mesh.indexCount(), + mesh.indexStride()}}; + + return Trade::MeshData{mesh.primitive(), + {}, mesh.indexData(), indices, + {}, mesh.vertexData(), Trade::meshAttributeDataNonOwningArray(mesh.attributeData()), + mesh.vertexCount()}; } -Trade::MeshData mutableReference(Trade::MeshData& data) { - CORRADE_ASSERT((data.indexDataFlags() & Trade::DataFlag::Mutable) && (data.vertexDataFlags() & Trade::DataFlag::Mutable), +Trade::MeshData mutableReference(Trade::MeshData& mesh) { + CORRADE_ASSERT((mesh.indexDataFlags() & Trade::DataFlag::Mutable) && (mesh.vertexDataFlags() & Trade::DataFlag::Mutable), "MeshTools::mutableReference(): data not mutable", (Trade::MeshData{MeshPrimitive::Points, 0})); @@ -61,57 +61,57 @@ Trade::MeshData mutableReference(Trade::MeshData& data) { Trade::meshIndexData{data.indexType(), view} because asking for index type would assert on non-indexed meshes. */ Trade::MeshIndexData indices; - if(data.isIndexed()) indices = Trade::MeshIndexData{ - data.indexType(), + if(mesh.isIndexed()) indices = Trade::MeshIndexData{ + mesh.indexType(), Containers::StridedArrayView1D{ - data.indexData(), - data.indexData().data() + data.indexOffset(), - data.indexCount(), - data.indexStride()}}; - - return Trade::MeshData{data.primitive(), - Trade::DataFlag::Mutable, data.mutableIndexData(), indices, - Trade::DataFlag::Mutable, data.mutableVertexData(), Trade::meshAttributeDataNonOwningArray(data.attributeData()), - data.vertexCount()}; + mesh.indexData(), + mesh.indexData().data() + mesh.indexOffset(), + mesh.indexCount(), + mesh.indexStride()}}; + + return Trade::MeshData{mesh.primitive(), + Trade::DataFlag::Mutable, mesh.mutableIndexData(), indices, + Trade::DataFlag::Mutable, mesh.mutableVertexData(), Trade::meshAttributeDataNonOwningArray(mesh.attributeData()), + mesh.vertexCount()}; } -Trade::MeshData owned(const Trade::MeshData& data) { - return owned(reference(data)); +Trade::MeshData owned(const Trade::MeshData& mesh) { + return owned(reference(mesh)); } -Trade::MeshData owned(Trade::MeshData&& data) { +Trade::MeshData owned(Trade::MeshData&& mesh) { /** @todo copy only the actually used range instead of the whole thing? */ /* If index data are already owned, move them to the output. This works without any extra effort also for non-indexed meshes. */ Containers::Array indexData; Trade::MeshIndexData indices; - if(data.indexDataFlags() & Trade::DataFlag::Owned) { - indices = Trade::MeshIndexData{data.indices()}; - indexData = data.releaseIndexData(); + if(mesh.indexDataFlags() & Trade::DataFlag::Owned) { + indices = Trade::MeshIndexData{mesh.indices()}; + indexData = mesh.releaseIndexData(); /* Otherwise copy them, if the mesh is indexed. If not, the default-constructed instances are fine. */ - } else if(data.isIndexed()) { - indexData = Containers::Array{NoInit, data.indexData().size()}; + } else if(mesh.isIndexed()) { + indexData = Containers::Array{NoInit, mesh.indexData().size()}; indices = Trade::MeshIndexData{ - data.indexType(), + mesh.indexType(), Containers::StridedArrayView1D{ indexData, - indexData.data() + data.indexOffset(), - data.indexCount(), - data.indexStride()}}; - Utility::copy(data.indexData(), indexData); + indexData.data() + mesh.indexOffset(), + mesh.indexCount(), + mesh.indexStride()}}; + Utility::copy(mesh.indexData(), indexData); } /* If vertex data are already owned, move them to the output. Because releasing them will clear vertex count, save that in advance, save also original vertex data view for attribute offset calculation */ - const UnsignedInt vertexCount = data.vertexCount(); - const Containers::ArrayView originalVertexData = data.vertexData(); + const UnsignedInt vertexCount = mesh.vertexCount(); + const Containers::ArrayView originalVertexData = mesh.vertexData(); Containers::Array vertexData; - if(data.vertexDataFlags() & Trade::DataFlag::Owned) { - vertexData = data.releaseVertexData(); + if(mesh.vertexDataFlags() & Trade::DataFlag::Owned) { + vertexData = mesh.releaseVertexData(); /* Otherwise copy them */ } else { @@ -122,12 +122,12 @@ Trade::MeshData owned(Trade::MeshData&& data) { /* There's no way to know if attribute data are owned until we release them and check the deleter, but releasing them makes it impossible to use the convenience MeshData APIs, so we have to do the hard way. */ - Containers::Array originalAttributeData = data.releaseAttributeData(); + Containers::Array originalAttributeData = mesh.releaseAttributeData(); /* If the attribute data are owned *and* the vertex data weren't copied, we can reuse the original array in its entirety */ Containers::Array attributeData; - if(!originalAttributeData.deleter() && (data.vertexDataFlags() & Trade::DataFlag::Owned)) { + if(!originalAttributeData.deleter() && (mesh.vertexDataFlags() & Trade::DataFlag::Owned)) { attributeData = std::move(originalAttributeData); /* Otherwise we have to allocate a new one and re-route the attributes to @@ -147,7 +147,7 @@ Trade::MeshData owned(Trade::MeshData&& data) { } } - return Trade::MeshData{data.primitive(), + return Trade::MeshData{mesh.primitive(), std::move(indexData), indices, std::move(vertexData), std::move(attributeData), vertexCount}; diff --git a/src/Magnum/MeshTools/Reference.h b/src/Magnum/MeshTools/Reference.h index d99d38cfd..69056dccd 100644 --- a/src/Magnum/MeshTools/Reference.h +++ b/src/Magnum/MeshTools/Reference.h @@ -41,11 +41,11 @@ namespace Magnum { namespace MeshTools { The returned instance has empty @ref Trade::MeshData::indexDataFlags() and @ref Trade::MeshData::vertexDataFlags() and references attribute data from the -@p data as well. The function performs no allocation or data copy. Use +@p mesh as well. The function performs no allocation or data copy. Use @ref owned() for an inverse operation. @see @ref mutableReference() */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData reference(const Trade::MeshData& data); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData reference(const Trade::MeshData& mesh); /** @brief Create a mutable reference on a @ref Trade::MeshData @@ -54,10 +54,10 @@ MAGNUM_MESHTOOLS_EXPORT Trade::MeshData reference(const Trade::MeshData& data); The returned instance has @ref Trade::MeshData::indexDataFlags() and @ref Trade::MeshData::vertexDataFlags() set to @ref Trade::DataFlag::Mutable. The function performs no allocation or data copy. Use @ref owned() for an -inverse operation. Expects that @p data is mutable. +inverse operation. Expects that @p mesh is mutable. @see @ref reference() */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData mutableReference(Trade::MeshData& data); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData mutableReference(Trade::MeshData& mesh); /** @brief Create an owned @ref Trade::MeshData @@ -67,12 +67,12 @@ The returned instance owns its index, vertex and attribute data --- both @ref Trade::MeshData::indexDataFlags() and @ref Trade::MeshData::vertexDataFlags() have @ref Trade::DataFlag::Mutable and @ref Trade::DataFlag::Owned set. This function unconditionally does an -allocation and a copy even if the @p data is already owned, use +allocation and a copy even if the @p mesh is already owned, use @ref owned(Trade::MeshData&&) to make an owned copy only if the instance isn't already owned. @see @ref reference(), @ref mutableReference() */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData owned(const Trade::MeshData& data); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData owned(const Trade::MeshData& mesh); /** @brief Create an owned @ref Trade::MeshData, if not already @@ -86,7 +86,7 @@ already owned are simply moved to the output, otherwise the data get copied into newly allocated arrays. @see @ref reference(), @ref mutableReference() */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData owned(Trade::MeshData&& data); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData owned(Trade::MeshData&& mesh); }} diff --git a/src/Magnum/MeshTools/RemoveDuplicates.cpp b/src/Magnum/MeshTools/RemoveDuplicates.cpp index 2d334b37d..7d6ad30d6 100644 --- a/src/Magnum/MeshTools/RemoveDuplicates.cpp +++ b/src/Magnum/MeshTools/RemoveDuplicates.cpp @@ -397,13 +397,13 @@ std::size_t removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayVi return removeDuplicatesFuzzyIndexedInPlaceImplementation(indices, data, epsilon); } -Trade::MeshData removeDuplicates(const Trade::MeshData& data) { - CORRADE_ASSERT(data.attributeCount(), +Trade::MeshData removeDuplicates(const Trade::MeshData& mesh) { + CORRADE_ASSERT(mesh.attributeCount(), "MeshTools::removeDuplicates(): can't remove duplicates in an attributeless mesh", (Trade::MeshData{MeshPrimitive::Points, 0})); #ifndef CORRADE_NO_ASSERT - for(std::size_t i = 0; i != data.attributeCount(); ++i) { - const VertexFormat format = data.attributeFormat(i); + for(std::size_t i = 0; i != mesh.attributeCount(); ++i) { + const VertexFormat format = mesh.attributeFormat(i); CORRADE_ASSERT(!isVertexFormatImplementationSpecific(format), "MeshTools::removeDuplicates(): attribute" << i << "has an implementation-specific format" << reinterpret_cast(vertexFormatUnwrap(format)), (Trade::MeshData{MeshPrimitive::Points, 0})); @@ -412,8 +412,8 @@ Trade::MeshData removeDuplicates(const Trade::MeshData& data) { /* This has to be checked before passing the data to interleave() as there it would die also, but with a confusing function name in the message */ - CORRADE_ASSERT(!data.isIndexed() || !isMeshIndexTypeImplementationSpecific(data.indexType()), - "MeshTools::removeDuplicates(): mesh has an implementation-specific index type" << reinterpret_cast(meshIndexTypeUnwrap(data.indexType())), + CORRADE_ASSERT(!mesh.isIndexed() || !isMeshIndexTypeImplementationSpecific(mesh.indexType()), + "MeshTools::removeDuplicates(): mesh has an implementation-specific index type" << reinterpret_cast(meshIndexTypeUnwrap(mesh.indexType())), (Trade::MeshData{MeshPrimitive{}, 0})); /* Turn the passed data into an interleaved owned mutable instance we can @@ -424,7 +424,7 @@ Trade::MeshData removeDuplicates(const Trade::MeshData& data) { which is set by default, otherwise random padding bytes or filtered-out attributes may contribute to the non-uniqueness of particular elements. */ - Trade::MeshData ownedInterleaved = owned(interleave(data, {}, InterleaveFlags{})); + Trade::MeshData ownedInterleaved = owned(interleave(mesh, {}, InterleaveFlags{})); /* Because the interleaved mesh was forced to be repacked, the vertex data should span the whole stride -- this is relied on in the attribute @@ -472,15 +472,15 @@ Trade::MeshData removeDuplicates(const Trade::MeshData& data) { uniqueVertexCount}; } -Trade::MeshData removeDuplicatesFuzzy(const Trade::MeshData& data, const Float floatEpsilon, const Double doubleEpsilon) { - CORRADE_ASSERT(data.attributeCount(), +Trade::MeshData removeDuplicatesFuzzy(const Trade::MeshData& mesh, const Float floatEpsilon, const Double doubleEpsilon) { + CORRADE_ASSERT(mesh.attributeCount(), "MeshTools::removeDuplicatesFuzzy(): can't remove duplicates in an attributeless mesh", (Trade::MeshData{MeshPrimitive::Points, 0})); /* Turn the passed data into an owned mutable instance we can operate on. There's a chance the original data are already like this, in which case this will be just a passthrough. */ - Trade::MeshData owned = MeshTools::owned(std::move(data)); + Trade::MeshData owned = MeshTools::owned(std::move(mesh)); /* Allocate an interleaved index array for all vertices times all attributes */ diff --git a/src/Magnum/MeshTools/RemoveDuplicates.h b/src/Magnum/MeshTools/RemoveDuplicates.h index 8766dc8ce..bce932252 100644 --- a/src/Magnum/MeshTools/RemoveDuplicates.h +++ b/src/Magnum/MeshTools/RemoveDuplicates.h @@ -310,7 +310,7 @@ copies and interleaves the input vertex and index data. @see @ref isMeshIndexTypeImplementationSpecific(), @ref isVertexFormatImplementationSpecific() */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData removeDuplicates(const Trade::MeshData& data); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData removeDuplicates(const Trade::MeshData& mesh); /** @brief Remove mesh data duplicates with fuzzy comparison for floating-point attributes @@ -323,7 +323,7 @@ on floating-point attributes. For attributes with a known range (such as direction) the @p floatEpsilon / @p doubleEpsilon is scaled appropriately, otherwise it's scaled to calculated value range. */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData removeDuplicatesFuzzy(const Trade::MeshData& data, Float floatEpsilon = Math::TypeTraits::epsilon(), Double doubleEpsilon = Math::TypeTraits::epsilon()); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData removeDuplicatesFuzzy(const Trade::MeshData& mesh, Float floatEpsilon = Math::TypeTraits::epsilon(), Double doubleEpsilon = Math::TypeTraits::epsilon()); #ifdef MAGNUM_BUILD_DEPRECATED template std::vector removeDuplicates(std::vector& data, typename Vector::Type epsilon) { diff --git a/src/Magnum/MeshTools/Transform.cpp b/src/Magnum/MeshTools/Transform.cpp index 6f5b8a6c3..1e674d997 100644 --- a/src/Magnum/MeshTools/Transform.cpp +++ b/src/Magnum/MeshTools/Transform.cpp @@ -33,12 +33,12 @@ namespace Magnum { namespace MeshTools { -Trade::MeshData transform2D(const Trade::MeshData& data, const Matrix3& transformation, const UnsignedInt id, const InterleaveFlags flags) { - const Containers::Optional positionAttributeId = data.findAttributeId(Trade::MeshAttribute::Position, id); +Trade::MeshData transform2D(const Trade::MeshData& mesh, const Matrix3& transformation, const UnsignedInt id, const InterleaveFlags flags) { + const Containers::Optional positionAttributeId = mesh.findAttributeId(Trade::MeshAttribute::Position, id); CORRADE_ASSERT(positionAttributeId, "MeshTools::transform2D(): the mesh has no positions with index" << id, (Trade::MeshData{MeshPrimitive::Triangles, 0})); - const VertexFormat positionAttributeFormat = data.attributeFormat(*positionAttributeId); + const VertexFormat positionAttributeFormat = mesh.attributeFormat(*positionAttributeId); CORRADE_ASSERT(!isVertexFormatImplementationSpecific(positionAttributeFormat), "MeshTools::transform2D(): positions have an implementation-specific format" << reinterpret_cast(vertexFormatUnwrap(positionAttributeFormat)), (Trade::MeshData{MeshPrimitive::Points, 0})); @@ -50,9 +50,9 @@ Trade::MeshData transform2D(const Trade::MeshData& data, const Matrix3& transfor position attribute format, if needed. Not using Utility::copy() here as the view returned by attributeData() might have offset-only attributes which interleave() doesn't want. */ - Containers::Array attributes{data.attributeCount()}; - for(UnsignedInt i = 0; i != data.attributeCount(); ++i) - attributes[i] = data.attributeData(i); + Containers::Array attributes{mesh.attributeCount()}; + for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) + attributes[i] = mesh.attributeData(i); /* If the position attribute isn't in a desired format, replace it with an empty placeholder that we'll unpack the data into */ @@ -61,73 +61,73 @@ Trade::MeshData transform2D(const Trade::MeshData& data, const Matrix3& transfor /* Create the output mesh, making more room for the full formats if necessary */ - Trade::MeshData out = interleave(filterOnlyAttributes(data, Containers::ArrayView{}), attributes, flags); + Trade::MeshData out = interleave(filterOnlyAttributes(mesh, Containers::ArrayView{}), attributes, flags); /* If the position attribute wasn't in a desired format, unpack it */ if(positionAttributeFormat != VertexFormat::Vector2) - data.positions2DInto(out.mutableAttribute(*positionAttributeId), id); + mesh.positions2DInto(out.mutableAttribute(*positionAttributeId), id); /* Delegate to the in-place implementation and return */ transform2DInPlace(out, transformation, id); return out; } -Trade::MeshData transform2D(Trade::MeshData&& data, const Matrix3& transformation, const UnsignedInt id, const InterleaveFlags flags) { +Trade::MeshData transform2D(Trade::MeshData&& mesh, const Matrix3& transformation, const UnsignedInt id, const InterleaveFlags flags) { /* Perform the operation in-place, if we can transfer the ownership and have positions in the right format already. Explicitly checking for presence of the position attribute so we don't need to duplicate the assert here again. */ - if((data.indexDataFlags() & Trade::DataFlag::Owned) && - (data.vertexDataFlags() & Trade::DataFlag::Owned) && - data.attributeCount(Trade::MeshAttribute::Position) > id && - data.attributeFormat(Trade::MeshAttribute::Position, id) == VertexFormat::Vector2) + if((mesh.indexDataFlags() & Trade::DataFlag::Owned) && + (mesh.vertexDataFlags() & Trade::DataFlag::Owned) && + mesh.attributeCount(Trade::MeshAttribute::Position) > id && + mesh.attributeFormat(Trade::MeshAttribute::Position, id) == VertexFormat::Vector2) { - transform2DInPlace(data, transformation, id); - return std::move(data); + transform2DInPlace(mesh, transformation, id); + return std::move(mesh); } /* Otherwise delegate to the function that does all the copying and format expansion */ - return transform2D(data, transformation, id, flags); + return transform2D(mesh, transformation, id, flags); } -void transform2DInPlace(Trade::MeshData& data, const Matrix3& transformation, const UnsignedInt id) { - CORRADE_ASSERT(data.vertexDataFlags() & Trade::DataFlag::Mutable, +void transform2DInPlace(Trade::MeshData& mesh, const Matrix3& transformation, const UnsignedInt id) { + CORRADE_ASSERT(mesh.vertexDataFlags() & Trade::DataFlag::Mutable, "MeshTools::transform2DInPlace(): vertex data not mutable", ); - const Containers::Optional positionAttributeId = data.findAttributeId(Trade::MeshAttribute::Position, id); + const Containers::Optional positionAttributeId = mesh.findAttributeId(Trade::MeshAttribute::Position, id); CORRADE_ASSERT(positionAttributeId, "MeshTools::transform2DInPlace(): the mesh has no positions with index" << id, ); - CORRADE_ASSERT(data.attributeFormat(*positionAttributeId) == VertexFormat::Vector2, - "MeshTools::transform2DInPlace(): expected" << VertexFormat::Vector2 << "positions but got" << data.attributeFormat(*positionAttributeId), ); + CORRADE_ASSERT(mesh.attributeFormat(*positionAttributeId) == VertexFormat::Vector2, + "MeshTools::transform2DInPlace(): expected" << VertexFormat::Vector2 << "positions but got" << mesh.attributeFormat(*positionAttributeId), ); /** @todo this needs a proper batch implementation */ - for(Vector2& position: data.mutableAttribute(*positionAttributeId)) + for(Vector2& position: mesh.mutableAttribute(*positionAttributeId)) position = transformation.transformPoint(position); } -Trade::MeshData transform3D(const Trade::MeshData& data, const Matrix4& transformation, const UnsignedInt id, const InterleaveFlags flags) { - const Containers::Optional positionAttributeId = data.findAttributeId(Trade::MeshAttribute::Position, id); +Trade::MeshData transform3D(const Trade::MeshData& mesh, const Matrix4& transformation, const UnsignedInt id, const InterleaveFlags flags) { + const Containers::Optional positionAttributeId = mesh.findAttributeId(Trade::MeshAttribute::Position, id); CORRADE_ASSERT(positionAttributeId, "MeshTools::transform3D(): the mesh has no positions with index" << id, (Trade::MeshData{MeshPrimitive::Triangles, 0})); - const VertexFormat positionAttributeFormat = data.attributeFormat(*positionAttributeId); + const VertexFormat positionAttributeFormat = mesh.attributeFormat(*positionAttributeId); CORRADE_ASSERT(!isVertexFormatImplementationSpecific(positionAttributeFormat), "MeshTools::transform3D(): positions have an implementation-specific format" << reinterpret_cast(vertexFormatUnwrap(positionAttributeFormat)), (Trade::MeshData{MeshPrimitive::Points, 0})); CORRADE_ASSERT(vertexFormatComponentCount(positionAttributeFormat) == 3, "MeshTools::transform3D(): expected 3D positions but got" << positionAttributeFormat, (Trade::MeshData{MeshPrimitive::Triangles, 0})); - const Containers::Optional tangentAttributeId = data.findAttributeId(Trade::MeshAttribute::Tangent, id); - const Containers::Optional bitangentAttributeId = data.findAttributeId(Trade::MeshAttribute::Bitangent, id); - const Containers::Optional normalAttributeId = data.findAttributeId(Trade::MeshAttribute::Normal, id); + const Containers::Optional tangentAttributeId = mesh.findAttributeId(Trade::MeshAttribute::Tangent, id); + const Containers::Optional bitangentAttributeId = mesh.findAttributeId(Trade::MeshAttribute::Bitangent, id); + const Containers::Optional normalAttributeId = mesh.findAttributeId(Trade::MeshAttribute::Normal, id); /* Copy original attributes to a mutable array so we can update the position attribute format, if needed. Not using Utility::copy() here as the view returned by attributeData() might have offset-only attributes which interleave() doesn't want. */ - Containers::Array attributes{data.attributeCount()}; - for(UnsignedInt i = 0; i != data.attributeCount(); ++i) - attributes[i] = data.attributeData(i); + Containers::Array attributes{mesh.attributeCount()}; + for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) + attributes[i] = mesh.attributeData(i); /* If the position/TBN attributes aren't in a desired format, replace them with an empty placeholder that we'll unpack the data into */ @@ -136,18 +136,18 @@ Trade::MeshData transform3D(const Trade::MeshData& data, const Matrix4& transfor VertexFormat tangentAttributeFormat{}; VertexFormat desiredTangentVertexFormat{}; if(tangentAttributeId) { - tangentAttributeFormat = data.attributeFormat(*tangentAttributeId); + tangentAttributeFormat = mesh.attributeFormat(*tangentAttributeId); CORRADE_ASSERT(!isVertexFormatImplementationSpecific(tangentAttributeFormat), "MeshTools::transform3D(): tangents have an implementation-specific format" << reinterpret_cast(vertexFormatUnwrap(tangentAttributeFormat)), (Trade::MeshData{MeshPrimitive::Points, 0})); - desiredTangentVertexFormat = vertexFormatComponentCount(data.attributeFormat(*tangentAttributeId)) == 4 ? + desiredTangentVertexFormat = vertexFormatComponentCount(mesh.attributeFormat(*tangentAttributeId)) == 4 ? VertexFormat::Vector4 : VertexFormat::Vector3; if(tangentAttributeFormat != desiredTangentVertexFormat) attributes[*tangentAttributeId] = Trade::MeshAttributeData{Trade::MeshAttribute::Tangent, desiredTangentVertexFormat, nullptr}; } VertexFormat bitangentAttributeFormat{}; if(bitangentAttributeId) { - bitangentAttributeFormat = data.attributeFormat(*bitangentAttributeId); + bitangentAttributeFormat = mesh.attributeFormat(*bitangentAttributeId); CORRADE_ASSERT(!isVertexFormatImplementationSpecific(bitangentAttributeFormat), "MeshTools::transform3D(): bitangents have an implementation-specific format" << reinterpret_cast(vertexFormatUnwrap(bitangentAttributeFormat)), (Trade::MeshData{MeshPrimitive::Points, 0})); @@ -156,7 +156,7 @@ Trade::MeshData transform3D(const Trade::MeshData& data, const Matrix4& transfor } VertexFormat normalAttributeFormat{}; if(normalAttributeId) { - normalAttributeFormat = data.attributeFormat(*normalAttributeId); + normalAttributeFormat = mesh.attributeFormat(*normalAttributeId); CORRADE_ASSERT(!isVertexFormatImplementationSpecific(normalAttributeFormat), "MeshTools::transform3D(): normals have an implementation-specific format" << reinterpret_cast(vertexFormatUnwrap(normalAttributeFormat)), (Trade::MeshData{MeshPrimitive::Points, 0})); @@ -166,76 +166,76 @@ Trade::MeshData transform3D(const Trade::MeshData& data, const Matrix4& transfor /* Create the output mesh, making more room for the full formats if necessary */ - Trade::MeshData out = interleave(filterOnlyAttributes(data, Containers::ArrayView{}), attributes, flags); + Trade::MeshData out = interleave(filterOnlyAttributes(mesh, Containers::ArrayView{}), attributes, flags); /* If the position/TBN attributes weren't in a desired format, unpack them */ if(positionAttributeFormat != VertexFormat::Vector3) - data.positions3DInto(out.mutableAttribute(*positionAttributeId), id); + mesh.positions3DInto(out.mutableAttribute(*positionAttributeId), id); if(tangentAttributeId && tangentAttributeFormat != desiredTangentVertexFormat) { if(desiredTangentVertexFormat == VertexFormat::Vector4) { - data.tangentsInto(out.mutableAttribute(*tangentAttributeId).slice(&Vector4::xyz), id); - data.bitangentSignsInto(out.mutableAttribute(*tangentAttributeId).slice(&Vector4::w), id); + mesh.tangentsInto(out.mutableAttribute(*tangentAttributeId).slice(&Vector4::xyz), id); + mesh.bitangentSignsInto(out.mutableAttribute(*tangentAttributeId).slice(&Vector4::w), id); } else { - data.tangentsInto(out.mutableAttribute(*tangentAttributeId), id); + mesh.tangentsInto(out.mutableAttribute(*tangentAttributeId), id); } } if(bitangentAttributeId && bitangentAttributeFormat != VertexFormat::Vector3) - data.bitangentsInto(out.mutableAttribute(*bitangentAttributeId), id); + mesh.bitangentsInto(out.mutableAttribute(*bitangentAttributeId), id); if(normalAttributeId && normalAttributeFormat != VertexFormat::Vector3) - data.normalsInto(out.mutableAttribute(*normalAttributeId), id); + mesh.normalsInto(out.mutableAttribute(*normalAttributeId), id); /* Delegate to the in-place implementation and return */ transform3DInPlace(out, transformation, id); return out; } -Trade::MeshData transform3D(Trade::MeshData&& data, const Matrix4& transformation, const UnsignedInt id, const InterleaveFlags flags) { +Trade::MeshData transform3D(Trade::MeshData&& mesh, const Matrix4& transformation, const UnsignedInt id, const InterleaveFlags flags) { /* Perform the operation in-place, if we can transfer the ownership and have positions in the right format already. Explicitly checking for presence of the position attribute so we don't need to duplicate the assert here again. */ - const Containers::Optional positionAttributeId = data.findAttributeId(Trade::MeshAttribute::Position, id); - const Containers::Optional tangentAttributeId = data.findAttributeId(Trade::MeshAttribute::Tangent, id); - const Containers::Optional bitangentAttributeId = data.findAttributeId(Trade::MeshAttribute::Bitangent, id); - const Containers::Optional normalAttributeId = data.findAttributeId(Trade::MeshAttribute::Normal, id); - if((data.indexDataFlags() & Trade::DataFlag::Owned) && - (data.vertexDataFlags() & Trade::DataFlag::Owned) && + const Containers::Optional positionAttributeId = mesh.findAttributeId(Trade::MeshAttribute::Position, id); + const Containers::Optional tangentAttributeId = mesh.findAttributeId(Trade::MeshAttribute::Tangent, id); + const Containers::Optional bitangentAttributeId = mesh.findAttributeId(Trade::MeshAttribute::Bitangent, id); + const Containers::Optional normalAttributeId = mesh.findAttributeId(Trade::MeshAttribute::Normal, id); + if((mesh.indexDataFlags() & Trade::DataFlag::Owned) && + (mesh.vertexDataFlags() & Trade::DataFlag::Owned) && positionAttributeId && - data.attributeFormat(*positionAttributeId) == VertexFormat::Vector3 && - (!tangentAttributeId || data.attributeFormat(*tangentAttributeId) == VertexFormat::Vector3 || data.attributeFormat(*tangentAttributeId) == VertexFormat::Vector4) && - (!bitangentAttributeId || data.attributeFormat(*bitangentAttributeId) == VertexFormat::Vector3) && - (!normalAttributeId || data.attributeFormat(*normalAttributeId) == VertexFormat::Vector3)) + mesh.attributeFormat(*positionAttributeId) == VertexFormat::Vector3 && + (!tangentAttributeId || mesh.attributeFormat(*tangentAttributeId) == VertexFormat::Vector3 || mesh.attributeFormat(*tangentAttributeId) == VertexFormat::Vector4) && + (!bitangentAttributeId || mesh.attributeFormat(*bitangentAttributeId) == VertexFormat::Vector3) && + (!normalAttributeId || mesh.attributeFormat(*normalAttributeId) == VertexFormat::Vector3)) { - transform3DInPlace(data, transformation, id); - return std::move(data); + transform3DInPlace(mesh, transformation, id); + return std::move(mesh); } /* Otherwise delegate to the function that does all the copying and format expansion */ - return transform3D(data, transformation, id, flags); + return transform3D(mesh, transformation, id, flags); } -void transform3DInPlace(Trade::MeshData& data, const Matrix4& transformation, const UnsignedInt id) { - CORRADE_ASSERT(data.vertexDataFlags() & Trade::DataFlag::Mutable, +void transform3DInPlace(Trade::MeshData& mesh, const Matrix4& transformation, const UnsignedInt id) { + CORRADE_ASSERT(mesh.vertexDataFlags() & Trade::DataFlag::Mutable, "MeshTools::transform3DInPlace(): vertex data not mutable", ); - const Containers::Optional positionAttributeId = data.findAttributeId(Trade::MeshAttribute::Position, id); + const Containers::Optional positionAttributeId = mesh.findAttributeId(Trade::MeshAttribute::Position, id); CORRADE_ASSERT(positionAttributeId, "MeshTools::transform3DInPlace(): the mesh has no positions with index" << id, ); - CORRADE_ASSERT(data.attributeFormat(*positionAttributeId) == VertexFormat::Vector3, - "MeshTools::transform3DInPlace(): expected" << VertexFormat::Vector3 << "positions but got" << data.attributeFormat(*positionAttributeId), ); - const Containers::Optional tangentAttributeId = data.findAttributeId(Trade::MeshAttribute::Tangent, id); - const VertexFormat tangentAttributeFormat = tangentAttributeId ? data.attributeFormat(*tangentAttributeId) : VertexFormat{}; + CORRADE_ASSERT(mesh.attributeFormat(*positionAttributeId) == VertexFormat::Vector3, + "MeshTools::transform3DInPlace(): expected" << VertexFormat::Vector3 << "positions but got" << mesh.attributeFormat(*positionAttributeId), ); + const Containers::Optional tangentAttributeId = mesh.findAttributeId(Trade::MeshAttribute::Tangent, id); + const VertexFormat tangentAttributeFormat = tangentAttributeId ? mesh.attributeFormat(*tangentAttributeId) : VertexFormat{}; CORRADE_ASSERT(!tangentAttributeId || tangentAttributeFormat == VertexFormat::Vector3 || tangentAttributeFormat == VertexFormat::Vector4, - "MeshTools::transform3DInPlace(): expected" << VertexFormat::Vector3 << "or" << VertexFormat::Vector4 << "tangents but got" << data.attributeFormat(*tangentAttributeId), ); - const Containers::Optional bitangentAttributeId = data.findAttributeId(Trade::MeshAttribute::Bitangent, id); - CORRADE_ASSERT(!bitangentAttributeId || data.attributeFormat(*bitangentAttributeId) == VertexFormat::Vector3, - "MeshTools::transform3DInPlace(): expected" << VertexFormat::Vector3 << "bitangents but got" << data.attributeFormat(*bitangentAttributeId), ); - const Containers::Optional normalAttributeId = data.findAttributeId(Trade::MeshAttribute::Normal, id); - CORRADE_ASSERT(!normalAttributeId || data.attributeFormat(*normalAttributeId) == VertexFormat::Vector3, - "MeshTools::transform3DInPlace(): expected" << VertexFormat::Vector3 << "normals but got" << data.attributeFormat(*normalAttributeId), ); + "MeshTools::transform3DInPlace(): expected" << VertexFormat::Vector3 << "or" << VertexFormat::Vector4 << "tangents but got" << mesh.attributeFormat(*tangentAttributeId), ); + const Containers::Optional bitangentAttributeId = mesh.findAttributeId(Trade::MeshAttribute::Bitangent, id); + CORRADE_ASSERT(!bitangentAttributeId || mesh.attributeFormat(*bitangentAttributeId) == VertexFormat::Vector3, + "MeshTools::transform3DInPlace(): expected" << VertexFormat::Vector3 << "bitangents but got" << mesh.attributeFormat(*bitangentAttributeId), ); + const Containers::Optional normalAttributeId = mesh.findAttributeId(Trade::MeshAttribute::Normal, id); + CORRADE_ASSERT(!normalAttributeId || mesh.attributeFormat(*normalAttributeId) == VertexFormat::Vector3, + "MeshTools::transform3DInPlace(): expected" << VertexFormat::Vector3 << "normals but got" << mesh.attributeFormat(*normalAttributeId), ); /** @todo this needs a proper batch implementation */ - for(Vector3& position: data.mutableAttribute(*positionAttributeId)) + for(Vector3& position: mesh.mutableAttribute(*positionAttributeId)) position = transformation.transformPoint(position); /* If no other attributes are present, nothing to do */ @@ -246,28 +246,28 @@ void transform3DInPlace(Trade::MeshData& data, const Matrix4& transformation, co if(tangentAttributeId) { /** @todo this needs a proper batch implementation */ if(tangentAttributeFormat == VertexFormat::Vector3) - for(Vector3& tangent: data.mutableAttribute(*tangentAttributeId)) + for(Vector3& tangent: mesh.mutableAttribute(*tangentAttributeId)) tangent = normalMatrix*tangent; - else for(Vector4& tangent: data.mutableAttribute(*tangentAttributeId)) { + else for(Vector4& tangent: mesh.mutableAttribute(*tangentAttributeId)) { tangent.xyz() = normalMatrix*tangent.xyz(); /** @todo figure out the fourth component, probably has to get flipped when the scale changes handedness? */ } } /** @todo this needs a proper batch implementation */ - if(bitangentAttributeId) for(Vector3& bitangent: data.mutableAttribute(*bitangentAttributeId)) + if(bitangentAttributeId) for(Vector3& bitangent: mesh.mutableAttribute(*bitangentAttributeId)) bitangent = normalMatrix*bitangent; /** @todo this needs a proper batch implementation */ - if(normalAttributeId) for(Vector3& normal: data.mutableAttribute(*normalAttributeId)) + if(normalAttributeId) for(Vector3& normal: mesh.mutableAttribute(*normalAttributeId)) normal = normalMatrix*normal; } -Trade::MeshData transformTextureCoordinates2D(const Trade::MeshData& data, const Matrix3& transformation, const UnsignedInt id, const InterleaveFlags flags) { - const Containers::Optional textureCoordinateAttributeId = data.findAttributeId(Trade::MeshAttribute::TextureCoordinates, id); +Trade::MeshData transformTextureCoordinates2D(const Trade::MeshData& mesh, const Matrix3& transformation, const UnsignedInt id, const InterleaveFlags flags) { + const Containers::Optional textureCoordinateAttributeId = mesh.findAttributeId(Trade::MeshAttribute::TextureCoordinates, id); CORRADE_ASSERT(textureCoordinateAttributeId, "MeshTools::transformTextureCoordinates2D(): the mesh has no texture coordinates with index" << id, (Trade::MeshData{MeshPrimitive::Triangles, 0})); - const VertexFormat textureCoordinateAttributeFormat = data.attributeFormat(*textureCoordinateAttributeId); + const VertexFormat textureCoordinateAttributeFormat = mesh.attributeFormat(*textureCoordinateAttributeId); CORRADE_ASSERT(!isVertexFormatImplementationSpecific(textureCoordinateAttributeFormat), "MeshTools::transformTextureCoordinates2D(): texture coordinates have an implementation-specific format" << reinterpret_cast(vertexFormatUnwrap(textureCoordinateAttributeFormat)), (Trade::MeshData{MeshPrimitive::Points, 0})); @@ -276,9 +276,9 @@ Trade::MeshData transformTextureCoordinates2D(const Trade::MeshData& data, const position attribute format, if needed. Not using Utility::copy() here as the view returned by attributeData() might have offset-only attributes which interleave() doesn't want. */ - Containers::Array attributes{data.attributeCount()}; - for(UnsignedInt i = 0; i != data.attributeCount(); ++i) - attributes[i] = data.attributeData(i); + Containers::Array attributes{mesh.attributeCount()}; + for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) + attributes[i] = mesh.attributeData(i); /* If the position attribute isn't in a desired format, replace it with an empty placeholder that we'll unpack the data into */ @@ -287,47 +287,47 @@ Trade::MeshData transformTextureCoordinates2D(const Trade::MeshData& data, const /* Create the output mesh, making more room for the full formats if necessary */ - Trade::MeshData out = interleave(filterOnlyAttributes(data, Containers::ArrayView{}), attributes, flags); + Trade::MeshData out = interleave(filterOnlyAttributes(mesh, Containers::ArrayView{}), attributes, flags); /* If the position attribute wasn't in a desired format, unpack it */ - if(data.attributeFormat(*textureCoordinateAttributeId) != VertexFormat::Vector2) - data.textureCoordinates2DInto(out.mutableAttribute(*textureCoordinateAttributeId), id); + if(mesh.attributeFormat(*textureCoordinateAttributeId) != VertexFormat::Vector2) + mesh.textureCoordinates2DInto(out.mutableAttribute(*textureCoordinateAttributeId), id); /* Delegate to the in-place implementation and return */ transformTextureCoordinates2DInPlace(out, transformation, id); return out; } -Trade::MeshData transformTextureCoordinates2D(Trade::MeshData&& data, const Matrix3& transformation, const UnsignedInt id, const InterleaveFlags flags) { +Trade::MeshData transformTextureCoordinates2D(Trade::MeshData&& mesh, const Matrix3& transformation, const UnsignedInt id, const InterleaveFlags flags) { /* Perform the operation in-place, if we can transfer the ownership and have positions in the right format already. Explicitly checking for presence of the position attribute so we don't need to duplicate the assert here again. */ - if((data.indexDataFlags() & Trade::DataFlag::Owned) && - (data.vertexDataFlags() & Trade::DataFlag::Owned) && - data.attributeCount(Trade::MeshAttribute::TextureCoordinates) > id && - data.attributeFormat(Trade::MeshAttribute::TextureCoordinates, id) == VertexFormat::Vector2) + if((mesh.indexDataFlags() & Trade::DataFlag::Owned) && + (mesh.vertexDataFlags() & Trade::DataFlag::Owned) && + mesh.attributeCount(Trade::MeshAttribute::TextureCoordinates) > id && + mesh.attributeFormat(Trade::MeshAttribute::TextureCoordinates, id) == VertexFormat::Vector2) { - transformTextureCoordinates2DInPlace(data, transformation, id); - return std::move(data); + transformTextureCoordinates2DInPlace(mesh, transformation, id); + return std::move(mesh); } /* Otherwise delegate to the function that does all the copying and format expansion */ - return transformTextureCoordinates2D(data, transformation, id, flags); + return transformTextureCoordinates2D(mesh, transformation, id, flags); } -void transformTextureCoordinates2DInPlace(Trade::MeshData& data, const Matrix3& transformation, const UnsignedInt id) { - CORRADE_ASSERT(data.vertexDataFlags() & Trade::DataFlag::Mutable, +void transformTextureCoordinates2DInPlace(Trade::MeshData& mesh, const Matrix3& transformation, const UnsignedInt id) { + CORRADE_ASSERT(mesh.vertexDataFlags() & Trade::DataFlag::Mutable, "MeshTools::transformTextureCoordinates2DInPlace(): vertex data not mutable", ); - const Containers::Optional textureCoordinateAttributeId = data.findAttributeId(Trade::MeshAttribute::TextureCoordinates, id); + const Containers::Optional textureCoordinateAttributeId = mesh.findAttributeId(Trade::MeshAttribute::TextureCoordinates, id); CORRADE_ASSERT(textureCoordinateAttributeId, "MeshTools::transformTextureCoordinates2DInPlace(): the mesh has no texture coordinates with index" << id, ); - CORRADE_ASSERT(data.attributeFormat(*textureCoordinateAttributeId) == VertexFormat::Vector2, - "MeshTools::transformTextureCoordinates2DInPlace(): expected" << VertexFormat::Vector2 << "texture coordinates but got" << data.attributeFormat(*textureCoordinateAttributeId), ); + CORRADE_ASSERT(mesh.attributeFormat(*textureCoordinateAttributeId) == VertexFormat::Vector2, + "MeshTools::transformTextureCoordinates2DInPlace(): expected" << VertexFormat::Vector2 << "texture coordinates but got" << mesh.attributeFormat(*textureCoordinateAttributeId), ); /** @todo this needs a proper batch implementation */ - for(Vector2& position: data.mutableAttribute(*textureCoordinateAttributeId)) + for(Vector2& position: mesh.mutableAttribute(*textureCoordinateAttributeId)) position = transformation.transformPoint(position); } diff --git a/src/Magnum/MeshTools/Transform.h b/src/Magnum/MeshTools/Transform.h index 9d8bb63b0..288918c43 100644 --- a/src/Magnum/MeshTools/Transform.h +++ b/src/Magnum/MeshTools/Transform.h @@ -165,7 +165,7 @@ copy, you can also do an in-place transformation using @ref transform2DInPlace() @ref Trade::MeshData::attributeFormat(MeshAttribute, UnsignedInt) const, @ref isVertexFormatImplementationSpecific() */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData transform2D(const Trade::MeshData& data, const Matrix3& transformation, UnsignedInt id = 0, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData transform2D(const Trade::MeshData& mesh, const Matrix3& transformation, UnsignedInt id = 0, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); /** @brief Transform 2D positions in a mesh data @@ -177,7 +177,7 @@ data ownership to the returned instance, if both vertex and index data is owned, vertex data is mutable and the positions with index @p id are @ref VertexFormat::Vector2. */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData transform2D(Trade::MeshData&& data, const Matrix3& transformation, UnsignedInt id = 0, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData transform2D(Trade::MeshData&& mesh, const Matrix3& transformation, UnsignedInt id = 0, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); /** @brief Transform 2D positions in a mesh data in-place @@ -194,7 +194,7 @@ packed types, the in-place operation requires the position type to be @ref Trade::MeshData::attributeCount(MeshAttribute) const, @ref Trade::MeshData::attributeFormat(MeshAttribute, UnsignedInt) const */ -MAGNUM_MESHTOOLS_EXPORT void transform2DInPlace(Trade::MeshData& data, const Matrix3& transformation, UnsignedInt id = 0); +MAGNUM_MESHTOOLS_EXPORT void transform2DInPlace(Trade::MeshData& mesh, const Matrix3& transformation, UnsignedInt id = 0); /** @brief Transform 3D positions, normals, tangents and bitangents in a mesh data @@ -223,7 +223,7 @@ copy, you can also do an in-place transformation using @ref transform3DInPlace() @ref Trade::MeshData::attributeFormat(MeshAttribute, UnsignedInt) const, @ref isVertexFormatImplementationSpecific() */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData transform3D(const Trade::MeshData& data, const Matrix4& transformation, UnsignedInt id = 0, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData transform3D(const Trade::MeshData& mesh, const Matrix4& transformation, UnsignedInt id = 0, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); /** @brief Transform 3D positions, normals, tangenta and bitangents in a mesh data @@ -236,7 +236,7 @@ owned, vertex data is mutable, positions, normals and bitangents (if present) are @ref VertexFormat::Vector3 and tangents (if present) either @ref VertexFormat::Vector3 or @ref VertexFormat::Vector4. */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData transform3D(Trade::MeshData&& data, const Matrix4& transformation, UnsignedInt id = 0, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData transform3D(Trade::MeshData&& mesh, const Matrix4& transformation, UnsignedInt id = 0, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); /** @brief Transform 3D positions, normals, tangents and bitangents in a mesh data in-place @@ -258,7 +258,7 @@ than @p id, and indices (if any) are left untouched. @ref Trade::MeshData::attributeCount(MeshAttribute) const, @ref Trade::MeshData::attributeFormat(MeshAttribute, UnsignedInt) const */ -MAGNUM_MESHTOOLS_EXPORT void transform3DInPlace(Trade::MeshData& data, const Matrix4& transformation, UnsignedInt id = 0); +MAGNUM_MESHTOOLS_EXPORT void transform3DInPlace(Trade::MeshData& mesh, const Matrix4& transformation, UnsignedInt id = 0); /** @brief Transform 2D texture coordinates in a mesh data @@ -280,7 +280,7 @@ copy, you can also do an in-place transformation using @ref Trade::MeshData::attributeCount(MeshAttribute) const, @ref isVertexFormatImplementationSpecific() */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData transformTextureCoordinates2D(const Trade::MeshData& data, const Matrix3& transformation, UnsignedInt id = 0, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData transformTextureCoordinates2D(const Trade::MeshData& mesh, const Matrix3& transformation, UnsignedInt id = 0, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); /** @brief Transform 2D texture coordinates in a mesh data @@ -292,7 +292,7 @@ data ownership to the returned instance, if both vertex and index data is owned, vertex data is mutable and the coordinates with index @p id are @ref VertexFormat::Vector2. */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData transformTextureCoordinates2D(Trade::MeshData&& data, const Matrix3& transformation, UnsignedInt id = 0, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData transformTextureCoordinates2D(Trade::MeshData&& mesh, const Matrix3& transformation, UnsignedInt id = 0, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes); /** @brief Transform 2D texture coordinates in a mesh data in-place @@ -311,7 +311,7 @@ untouched. @ref Trade::MeshData::attributeCount(MeshAttribute) const, @ref Trade::MeshData::attributeFormat(MeshAttribute, UnsignedInt) const */ -MAGNUM_MESHTOOLS_EXPORT void transformTextureCoordinates2DInPlace(Trade::MeshData& data, const Matrix3& transformation, UnsignedInt id = 0); +MAGNUM_MESHTOOLS_EXPORT void transformTextureCoordinates2DInPlace(Trade::MeshData& mesh, const Matrix3& transformation, UnsignedInt id = 0); }}