Browse Source

MeshTools: common helper for remapping MeshAttributeData to new arrays.

So all the locations don't need to be explicitly tested when anything
happens with this -- already way too complex -- MeshAttributeData
constructor.
pull/623/head
Vladimír Vondruš 3 years ago
parent
commit
ec3241f425
  1. 1
      src/Magnum/MeshTools/CMakeLists.txt
  2. 11
      src/Magnum/MeshTools/CompressIndices.cpp
  3. 12
      src/Magnum/MeshTools/Concatenate.cpp
  4. 13
      src/Magnum/MeshTools/Copy.cpp
  5. 10
      src/Magnum/MeshTools/GenerateIndices.cpp
  6. 53
      src/Magnum/MeshTools/Implementation/remapAttributeData.h
  7. 13
      src/Magnum/MeshTools/Interleave.cpp
  8. 9
      src/Magnum/MeshTools/RemoveDuplicates.cpp

1
src/Magnum/MeshTools/CMakeLists.txt

@ -70,6 +70,7 @@ set(MagnumMeshTools_HEADERS
visibility.h)
set(MagnumMeshTools_INTERNAL_HEADERS
Implementation/remapAttributeData.h
Implementation/Tipsify.h)
if(MAGNUM_BUILD_DEPRECATED)

11
src/Magnum/MeshTools/CompressIndices.cpp

@ -31,6 +31,7 @@
#include "Magnum/Math/FunctionsBatch.h"
#include "Magnum/MeshTools/Copy.h"
#include "Magnum/MeshTools/Implementation/remapAttributeData.h"
#include "Magnum/Trade/MeshData.h"
#ifdef MAGNUM_BUILD_DEPRECATED
@ -130,6 +131,7 @@ Trade::MeshData compressIndices(Trade::MeshData&& mesh, MeshIndexType atLeast) {
/* Transfer vertex data as-is, as those don't need any changes. Release if
possible. */
const Containers::ArrayView<const char> originalVertexData = mesh.vertexData();
Containers::Array<char> vertexData;
const UnsignedInt vertexCount = mesh.vertexCount();
if(mesh.vertexDataFlags() & Trade::DataFlag::Owned)
@ -160,15 +162,12 @@ Trade::MeshData compressIndices(Trade::MeshData&& mesh, MeshIndexType atLeast) {
result = compressIndicesImplementation<UnsignedByte>(indices, atLeast, offset);
}
/* Recreate the attribute array */
/* Recreate the attribute array with each attribute being shifted by the
offset calculated above */
const UnsignedInt newVertexCount = vertexCount - offset;
Containers::Array<Trade::MeshAttributeData> attributeData{mesh.attributeCount()};
for(UnsignedInt i = 0, max = attributeData.size(); i != max; ++i) {
const UnsignedInt stride = mesh.attributeStride(i);
attributeData[i] = Trade::MeshAttributeData{mesh.attributeName(i),
mesh.attributeFormat(i),
Containers::StridedArrayView1D<const void>{vertexData, vertexData.data() + mesh.attributeOffset(i) + offset*stride, newVertexCount, stride},
mesh.attributeArraySize(i)};
attributeData[i] = Implementation::remapAttributeData(mesh.attributeData(i), newVertexCount, originalVertexData, vertexData.exceptPrefix(offset*mesh.attributeStride(i)));
}
Trade::MeshIndexData indices{result.second(), result.first()};

12
src/Magnum/MeshTools/Concatenate.cpp

@ -29,6 +29,8 @@
#include <unordered_map>
#include <Corrade/Utility/Algorithms.h>
#include "Magnum/MeshTools/Implementation/remapAttributeData.h"
namespace Magnum { namespace MeshTools {
namespace Implementation {
@ -69,14 +71,8 @@ Trade::MeshData concatenate(Containers::Array<char>&& indexData, const UnsignedI
/* Convert the attributes from offset-only and zero vertex count to
absolute, referencing the vertex data array */
for(Trade::MeshAttributeData& attribute: attributeData) {
attribute = Trade::MeshAttributeData{
attribute.name(), attribute.format(),
Containers::StridedArrayView1D<void>{vertexData,
vertexData + attribute.offset(vertexData),
vertexCount, attribute.stride()},
attribute.arraySize()};
}
for(Trade::MeshAttributeData& attribute: attributeData)
attribute = Implementation::remapAttributeData(attribute, vertexCount, vertexData, vertexData);
/* Only list primitives are supported currently */
/** @todo delegate to `indexTriangleStrip()` (`duplicate*()`?) etc when

13
src/Magnum/MeshTools/Copy.cpp

@ -28,6 +28,7 @@
#include <Corrade/Utility/Algorithms.h>
#include "Magnum/Trade/MeshData.h"
#include "Magnum/MeshTools/Implementation/remapAttributeData.h"
#ifdef MAGNUM_BUILD_DEPRECATED
#define _MAGNUM_NO_DEPRECATED_MESHTOOLS_REFERENCE
@ -149,16 +150,8 @@ Trade::MeshData copy(Trade::MeshData&& mesh) {
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() + originalAttribute.offset(originalVertexData),
vertexCount,
originalAttribute.stride()},
originalAttribute.arraySize()};
/* Otherwise remap it to the new vertex data */
else attributeData[i] = Implementation::remapAttributeData(originalAttribute, vertexCount, originalVertexData, vertexData);
}
}

10
src/Magnum/MeshTools/GenerateIndices.cpp

@ -31,6 +31,7 @@
#include "Magnum/Math/Vector3.h"
#include "Magnum/MeshTools/Copy.h"
#include "Magnum/MeshTools/Implementation/remapAttributeData.h"
#include "Magnum/Trade/MeshData.h"
namespace Magnum { namespace MeshTools {
@ -599,6 +600,7 @@ Trade::MeshData generateIndices(Trade::MeshData&& mesh) {
/* Transfer vertex / attribute data as-is, as those don't need any changes.
Release if possible. */
const Containers::ArrayView<const char> originalVertexData = mesh.vertexData();
Containers::Array<char> vertexData;
if(mesh.vertexDataFlags() & Trade::DataFlag::Owned)
vertexData = mesh.releaseVertexData();
@ -611,12 +613,8 @@ Trade::MeshData generateIndices(Trade::MeshData&& mesh) {
/** @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<Trade::MeshAttributeData> attributeData{mesh.attributeCount()};
for(UnsignedInt i = 0, max = attributeData.size(); i != max; ++i) {
attributeData[i] = Trade::MeshAttributeData{mesh.attributeName(i),
mesh.attributeFormat(i),
Containers::StridedArrayView1D<const void>{vertexData, vertexData.data() + mesh.attributeOffset(i), vertexCount, mesh.attributeStride(i)},
mesh.attributeArraySize(i)};
}
for(UnsignedInt i = 0, max = attributeData.size(); i != max; ++i)
attributeData[i] = Implementation::remapAttributeData(mesh.attributeData(i), vertexCount, originalVertexData, vertexData);
/* Generate the index array */
MeshPrimitive primitive;

53
src/Magnum/MeshTools/Implementation/remapAttributeData.h

@ -0,0 +1,53 @@
#ifndef Magnum_MeshTools_Implementation_remapAttributeData_h
#define Magnum_MeshTools_Implementation_remapAttributeData_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "Magnum/Trade/MeshData.h"
namespace Magnum { namespace MeshTools { namespace Implementation {
/* Common helper used by various MeshTools algorithms.
Remaps MeshAttributeData to be relative to the passed vertexData array,
which is assumed to be exactly the same as the original except in different
memory location. All properties including array size are kept but
offset-only attributes are changed to absolute and attributes with
(placeholder) zero vertex count are changed to actual vertex count. */
inline Trade::MeshAttributeData remapAttributeData(const Trade::MeshAttributeData& attribute, const UnsignedInt vertexCount, const Containers::ArrayView<const char> originalVertexData, Containers::ArrayView<const char> vertexData) {
return Trade::MeshAttributeData{
attribute.name(),
attribute.format(),
Containers::StridedArrayView1D<const void>{
vertexData,
vertexData.data() + attribute.offset(originalVertexData),
vertexCount,
attribute.stride()},
attribute.arraySize()};
}
}}}
#endif

13
src/Magnum/MeshTools/Interleave.cpp

@ -30,6 +30,7 @@
#include "Magnum/Math/Functions.h"
#include "Magnum/MeshTools/Copy.h"
#include "Magnum/MeshTools/Implementation/remapAttributeData.h"
#include "Magnum/Trade/MeshData.h"
namespace Magnum { namespace MeshTools {
@ -230,15 +231,11 @@ Trade::MeshData interleavedLayout(Trade::MeshData&& mesh, const UnsignedInt vert
/* Allocate new data array */
Containers::Array<char> vertexData{NoInit, attributeData[0].stride()*vertexCount};
/* Convert the attributes from offset-only and zero vertex count to
absolute, referencing the above-allocated data array */
/* Convert the attributes from all being offset-only and zero vertex count
to absolute, referencing the above-allocated data array */
for(Trade::MeshAttributeData& attribute: attributeData) {
attribute = Trade::MeshAttributeData{
attribute.name(), attribute.format(),
Containers::StridedArrayView1D<void>{vertexData,
vertexData + attribute.offset(vertexData),
vertexCount, attribute.stride()},
attribute.arraySize()};
CORRADE_INTERNAL_ASSERT(attribute.isOffsetOnly());
attribute = Implementation::remapAttributeData(attribute, vertexCount, vertexData, vertexData);
}
return Trade::MeshData{mesh.primitive(), std::move(vertexData), std::move(attributeData)};

9
src/Magnum/MeshTools/RemoveDuplicates.cpp

@ -40,6 +40,7 @@
#include "Magnum/MeshTools/Copy.h"
#include "Magnum/MeshTools/Duplicate.h"
#include "Magnum/MeshTools/Interleave.h"
#include "Magnum/MeshTools/Implementation/remapAttributeData.h"
#include "Magnum/Trade/MeshData.h"
namespace Magnum { namespace MeshTools {
@ -456,13 +457,7 @@ Trade::MeshData removeDuplicates(const Trade::MeshData& mesh) {
/* Route all attributes to the new vertex data */
Containers::Array<Trade::MeshAttributeData> attributeData{ownedInterleaved.attributeCount()};
for(UnsignedInt i = 0; i != ownedInterleaved.attributeCount(); ++i)
attributeData[i] = Trade::MeshAttributeData{ownedInterleaved.attributeName(i),
ownedInterleaved.attributeFormat(i),
Containers::StridedArrayView1D<void>{uniqueVertexData,
uniqueVertexData.data() + ownedInterleaved.attributeOffset(i),
uniqueVertexCount,
ownedInterleaved.attributeStride(i)},
ownedInterleaved.attributeArraySize(i)};
attributeData[i] = Implementation::remapAttributeData(ownedInterleaved.attributeData(i), uniqueVertexCount, ownedInterleaved.vertexData(), uniqueVertexData);
Trade::MeshIndexData indices{indexType, indexData};
return Trade::MeshData{ownedInterleaved.primitive(),

Loading…
Cancel
Save