Browse Source

MeshTools: don't create tons of strided views from scratch in combine*().

Instead create it once and then slice it up. Significantly less error
prone and faster as well as the assertions don't need to check that
much.
pull/623/head
Vladimír Vondruš 3 years ago
parent
commit
b1d1d65e5a
  1. 39
      src/Magnum/MeshTools/Combine.cpp

39
src/Magnum/MeshTools/Combine.cpp

@ -43,7 +43,7 @@ Trade::MeshData combineIndexedImplementation(
#if !defined(CORRADE_NO_ASSERT) && !defined(CORRADE_STANDARD_ASSERT) #if !defined(CORRADE_NO_ASSERT) && !defined(CORRADE_STANDARD_ASSERT)
const char* assertPrefix, const char* assertPrefix,
#endif #endif
const MeshPrimitive primitive, Containers::ArrayView<char> combinedIndices, const UnsignedInt indexCount, const UnsignedInt indexStride, const Containers::Iterable<const Trade::MeshData>& meshes) const MeshPrimitive primitive, const Containers::StridedArrayView2D<char>& combinedIndices, const Containers::Iterable<const Trade::MeshData>& meshes)
{ {
/* Calculate attribute count and vertex stride */ /* Calculate attribute count and vertex stride */
UnsignedInt attributeCount = 0; UnsignedInt attributeCount = 0;
@ -61,10 +61,10 @@ Trade::MeshData combineIndexedImplementation(
} }
/* Make the combined index array unique */ /* Make the combined index array unique */
Containers::Array<char> indexData{indexCount*sizeof(UnsignedInt)}; Containers::Array<char> indexData{combinedIndices.size()[0]*sizeof(UnsignedInt)};
const auto indexDataI = Containers::arrayCast<UnsignedInt>(indexData); const auto indexDataI = Containers::arrayCast<UnsignedInt>(indexData);
const UnsignedInt vertexCount = removeDuplicatesInPlaceInto( const UnsignedInt vertexCount = removeDuplicatesInPlaceInto(
Containers::StridedArrayView2D<char>{combinedIndices, {indexCount, indexStride}}, combinedIndices,
indexDataI); indexDataI);
/* Allocate resulting attribute and vertex data and duplicate the /* Allocate resulting attribute and vertex data and duplicate the
@ -78,10 +78,9 @@ Trade::MeshData combineIndexedImplementation(
for(const Trade::MeshData& mesh: meshes) { for(const Trade::MeshData& mesh: meshes) {
const UnsignedInt indexSize = mesh.isIndexed() ? const UnsignedInt indexSize = mesh.isIndexed() ?
meshIndexTypeSize(mesh.indexType()) : 4; meshIndexTypeSize(mesh.indexType()) : 4;
Containers::StridedArrayView2D<const char> indices{combinedIndices, Containers::StridedArrayView2D<const char> indices = combinedIndices.sliceSize(
combinedIndices.data() + indexOffset, {0, indexOffset},
{vertexCount, indexSize}, {vertexCount, indexSize});
{std::ptrdiff_t(indexStride), 1}};
for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) { for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) {
Containers::StridedArrayView2D<const char> src = mesh.attribute(i); Containers::StridedArrayView2D<const char> src = mesh.attribute(i);
@ -146,15 +145,14 @@ Trade::MeshData combineIndexedAttributes(const Containers::Iterable<const Trade:
reading 32-bit values from odd addresses on some platforms) */ reading 32-bit values from odd addresses on some platforms) */
/* Create a combined index array */ /* Create a combined index array */
Containers::Array<char> combinedIndices{NoInit, indexCount*indexStride}; Containers::Array<char> combinedIndicesStorage{NoInit, indexCount*indexStride};
const Containers::StridedArrayView2D<char> combinedIndices{combinedIndicesStorage, {indexCount, indexStride}};
{ {
std::size_t indexOffset = 0; std::size_t indexOffset = 0;
for(const Trade::MeshData& mesh: meshes) { for(const Trade::MeshData& mesh: meshes) {
const UnsignedInt indexSize = meshIndexTypeSize(mesh.indexType()); const UnsignedInt indexSize = meshIndexTypeSize(mesh.indexType());
Containers::StridedArrayView2D<char> dst{combinedIndices, Containers::StridedArrayView2D<char> dst = combinedIndices
combinedIndices.data() + indexOffset, .sliceSize({0, indexOffset}, {indexCount, indexSize});
{indexCount, indexSize},
{std::ptrdiff_t(indexStride), 1}};
Utility::copy(mesh.indices(), dst); Utility::copy(mesh.indices(), dst);
indexOffset += indexSize; indexOffset += indexSize;
} }
@ -167,7 +165,7 @@ Trade::MeshData combineIndexedAttributes(const Containers::Iterable<const Trade:
#if !defined(CORRADE_NO_ASSERT) && !defined(CORRADE_STANDARD_ASSERT) #if !defined(CORRADE_NO_ASSERT) && !defined(CORRADE_STANDARD_ASSERT)
"MeshTools::combineIndexedAttributes():", "MeshTools::combineIndexedAttributes():",
#endif #endif
primitive, combinedIndices, indexCount, indexStride, meshes); primitive, combinedIndices, meshes);
} }
Trade::MeshData combineFaceAttributes(const Trade::MeshData& mesh, const Trade::MeshData& faceAttributes) { Trade::MeshData combineFaceAttributes(const Trade::MeshData& mesh, const Trade::MeshData& faceAttributes) {
@ -198,17 +196,18 @@ Trade::MeshData combineFaceAttributes(const Trade::MeshData& mesh, const Trade::
faceIndexSize = meshIndexTypeSize(faceAttributes.indexType()); faceIndexSize = meshIndexTypeSize(faceAttributes.indexType());
} else faceIndexSize = 4; } else faceIndexSize = 4;
const UnsignedInt indexStride = meshIndexSize + faceIndexSize; const UnsignedInt indexStride = meshIndexSize + faceIndexSize;
Containers::Array<char> combinedIndices{NoInit, meshIndexCount*indexStride}; Containers::Array<char> combinedIndicesStorage{NoInit, meshIndexCount*indexStride};
const Containers::StridedArrayView2D<char> combinedIndices{combinedIndicesStorage, {meshIndexCount, indexStride}};
Utility::copy(mesh.indices(), Utility::copy(mesh.indices(),
Containers::StridedArrayView2D<char>{combinedIndices, {meshIndexCount, meshIndexSize}, {std::ptrdiff_t(indexStride), 1}}); combinedIndices.prefix({meshIndexCount, meshIndexSize}));
/* Then, if the face attributes are not indexed, remove duplicates and put /* Then, if the face attributes are not indexed, remove duplicates and put
the resulting indices into the combined array above. For simplicity the resulting indices into the combined array above. For simplicity
assume face data are interleaved. */ assume face data are interleaved. */
Containers::StridedArrayView3D<char> combinedFaceIndices{combinedIndices, Containers::StridedArrayView3D<char> combinedFaceIndices = combinedIndices
combinedIndices.data() + meshIndexSize, .sliceSize({0, meshIndexSize}, {meshIndexCount, faceIndexSize})
{3, faceIndexCount, faceIndexSize}, .expanded<0>(Containers::Size2D{faceIndexCount, 3})
{std::ptrdiff_t(indexStride), 3*std::ptrdiff_t(indexStride), 1}}; .transposed<0, 1>();
if(!faceAttributes.isIndexed()) { if(!faceAttributes.isIndexed()) {
/** @todo this could go into a dedicated removeDuplicates(MeshData) /** @todo this could go into a dedicated removeDuplicates(MeshData)
feature at some point, which would handle everything including feature at some point, which would handle everything including
@ -230,7 +229,7 @@ Trade::MeshData combineFaceAttributes(const Trade::MeshData& mesh, const Trade::
#if !defined(CORRADE_NO_ASSERT) && !defined(CORRADE_STANDARD_ASSERT) #if !defined(CORRADE_NO_ASSERT) && !defined(CORRADE_STANDARD_ASSERT)
"MeshTools::combineFaceAttributes():", "MeshTools::combineFaceAttributes():",
#endif #endif
mesh.primitive(), combinedIndices, meshIndexCount, indexStride, { mesh.primitive(), combinedIndices, {
mesh, faceAttributes mesh, faceAttributes
}); });
} }

Loading…
Cancel
Save