Browse Source

MeshTools: preserve offset-only attributes in copy().

pull/620/head
Vladimír Vondruš 3 years ago
parent
commit
3bcc847596
  1. 19
      src/Magnum/MeshTools/Copy.cpp
  2. 8
      src/Magnum/MeshTools/Copy.h
  3. 26
      src/Magnum/MeshTools/Test/CopyTest.cpp

19
src/Magnum/MeshTools/Copy.cpp

@ -142,15 +142,22 @@ Trade::MeshData copy(Trade::MeshData&& mesh) {
problematic to use in plugins */
attributeData = Containers::Array<Trade::MeshAttributeData>{DefaultInit, originalAttributeData.size()};
for(std::size_t i = 0; i != originalAttributeData.size(); ++i) {
attributeData[i] = Trade::MeshAttributeData{
originalAttributeData[i].name(),
originalAttributeData[i].format(),
const Trade::MeshAttributeData& originalAttribute = originalAttributeData[i];
/* If the attribute is offset-only, copy it directly, yay! */
if(originalAttribute.isOffsetOnly())
attributeData[i] = originalAttribute;
/* Otherwise it's kinda verbose */
else attributeData[i] = Trade::MeshAttributeData{
originalAttribute.name(),
originalAttribute.format(),
Containers::StridedArrayView1D<const void>{
vertexData,
vertexData.data() + originalAttributeData[i].offset(originalVertexData),
vertexData.data() + originalAttribute.offset(originalVertexData),
vertexCount,
originalAttributeData[i].stride()},
originalAttributeData[i].arraySize()};
originalAttribute.stride()},
originalAttribute.arraySize()};
}
}

8
src/Magnum/MeshTools/Copy.h

@ -46,7 +46,9 @@ All other properties such as the primitive or importer state are passed through
unchanged, the data layout isn't changed in any way. The resulting
@ref Trade::MeshData::indexDataFlags() and
@relativeref{Trade::MeshData,vertexDataFlags()} are always
@ref Trade::DataFlag::Owned and @ref Trade::DataFlag::Mutable.
@ref Trade::DataFlag::Owned and @ref Trade::DataFlag::Mutable. Attributes that
were offset-only before are kept offset-only, others have offsets recalculated
against the newly-allocated vertex data.
@see @ref copy(Trade::MeshData&&), @ref reference(), @ref mutableReference()
*/
MAGNUM_MESHTOOLS_EXPORT Trade::MeshData copy(const Trade::MeshData& mesh);
@ -63,7 +65,9 @@ data don't have the default deleter, allocates a copy of
@relativeref{Trade::MeshData,vertexData()} or
@relativeref{Trade::MeshData,attributeData()}, otherwise transfers their
ownership. The resulting data are always owned and mutable, the data layout
isn't changed in any way.
isn't changed in any way. Attributes that were offset-only before are kept
offset-only, others have offsets recalculated against the
potentially-newly-allocated vertex data.
@see @ref reference(), @ref mutableReference()
*/
MAGNUM_MESHTOOLS_EXPORT Trade::MeshData copy(Trade::MeshData&& mesh);

26
src/Magnum/MeshTools/Test/CopyTest.cpp

@ -42,6 +42,7 @@ struct CopyTest: TestSuite::Tester {
explicit CopyTest();
void copy();
void copyOffsetOnlyAttributes();
void copyNoIndexData();
void copyNoAttributeVertexData();
void copyStridedIndices();
@ -72,6 +73,7 @@ struct {
CopyTest::CopyTest() {
addTests({&CopyTest::copy,
&CopyTest::copyOffsetOnlyAttributes,
&CopyTest::copyNoIndexData,
&CopyTest::copyNoAttributeVertexData});
@ -134,6 +136,30 @@ void CopyTest::copy() {
CORRADE_VERIFY(!attributeData.deleter());
}
void CopyTest::copyOffsetOnlyAttributes() {
Trade::MeshData circle = Primitives::circle2DSolid(5);
Trade::MeshData copy = MeshTools::copy(circle);
CORRADE_COMPARE(copy.primitive(), circle.primitive());
CORRADE_COMPARE(copy.vertexCount(), circle.vertexCount());
CORRADE_COMPARE(copy.attributeCount(), circle.attributeCount());
for(std::size_t i = 0; i != circle.attributeCount(); ++i) {
CORRADE_ITERATION(i);
CORRADE_COMPARE(copy.attributeName(i), circle.attributeName(i));
CORRADE_COMPARE(copy.attributeFormat(i), circle.attributeFormat(i));
CORRADE_COMPARE(copy.attributeOffset(i), circle.attributeOffset(i));
CORRADE_COMPARE(copy.attributeStride(i), circle.attributeStride(i));
CORRADE_COMPARE(copy.attributeArraySize(i), circle.attributeArraySize(i));
/* The circle has offset-only attributes, that should be preserved
after the copy as well */
CORRADE_VERIFY(copy.attributeData()[i].isOffsetOnly());
}
CORRADE_COMPARE_AS(copy.vertexData(), circle.vertexData(), TestSuite::Compare::Container);
}
void CopyTest::copyNoIndexData() {
Trade::MeshData cube = Primitives::cubeSolidStrip();
CORRADE_VERIFY(!cube.isIndexed());

Loading…
Cancel
Save