Browse Source

MeshTools: unconditionally repack the input in removeDuplicates().

Since the main speed advantage of the function is that it hashes a
*whole* vertex together instead of going through the attribute arrays
one by one, it can't really operate on whatever funny interleaved layout
it was given as there may be padding bytes with random content, breaking
the deduplication.

Since checking that a layout is really padding-less is rather complex,
the repacking is now performed always. This also means the && overload
makes no sense anymore and thus it was dropped.

This makes the test added in the previous commit not assert anymore, and
behave the same as the padding-less case.
pull/547/head
Vladimír Vondruš 4 years ago
parent
commit
e496241290
  1. 11
      doc/changelog.dox
  2. 24
      src/Magnum/MeshTools/RemoveDuplicates.cpp
  3. 17
      src/Magnum/MeshTools/RemoveDuplicates.h

11
doc/changelog.dox

@ -527,6 +527,17 @@ See also:
for most shader-related limits for most shader-related limits
- Fixed assertions related to OpenGL driver workarounds when the proprietary - Fixed assertions related to OpenGL driver workarounds when the proprietary
AMDGPU PRO drivers are used on Linux AMDGPU PRO drivers are used on Linux
- Fixed an assertion when using @ref MeshTools::removeDuplicates() on an
interleaved @ref Trade::MeshData that included padding at the beginning or
end of each vertex
- Fixed @ref MeshTools::removeDuplicates() to not take into account random
padding bytes and filtered-out attributes in interleaved source
@ref Trade::MeshData. This was a particularly glaring issue when using
@ref magnum-sceneconverter "magnum-sceneconverter" with both
`--only-attributes` and `--remove-duplicates` specified together, where it
usually just didn't remove any duplicate whatsoever while
`--remove-duplicates-fuzzy` did, no matter how ridiculously low epsilon
was used.
- @ref Platform::EmscriptenApplication randomly created antialiased contexts - @ref Platform::EmscriptenApplication randomly created antialiased contexts
due to an uninitialized variable in its due to an uninitialized variable in its
@ref Platform::EmscriptenApplication::GLConfiguration "GLConfiguration" @ref Platform::EmscriptenApplication::GLConfiguration "GLConfiguration"

24
src/Magnum/MeshTools/RemoveDuplicates.cpp

@ -397,13 +397,6 @@ std::size_t removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayVi
} }
Trade::MeshData removeDuplicates(const Trade::MeshData& data) { Trade::MeshData removeDuplicates(const Trade::MeshData& data) {
return removeDuplicates(Trade::MeshData{data.primitive(),
{}, data.indexData(), Trade::MeshIndexData{data.indices()},
{}, data.vertexData(), Trade::meshAttributeDataNonOwningArray(data.attributeData()),
data.vertexCount()});
}
Trade::MeshData removeDuplicates(Trade::MeshData&& data) {
CORRADE_ASSERT(data.attributeCount(), CORRADE_ASSERT(data.attributeCount(),
"MeshTools::removeDuplicates(): can't remove duplicates in an attributeless mesh", "MeshTools::removeDuplicates(): can't remove duplicates in an attributeless mesh",
(Trade::MeshData{MeshPrimitive::Points, 0})); (Trade::MeshData{MeshPrimitive::Points, 0}));
@ -418,12 +411,19 @@ Trade::MeshData removeDuplicates(Trade::MeshData&& data) {
/* Turn the passed data into an interleaved owned mutable instance we can /* Turn the passed data into an interleaved owned mutable instance we can
operate on -- owned() alone only makes the data owned, interleave() operate on -- owned() alone only makes the data owned, interleave()
alone only makes the data interleaved (but those can stay non-owned). alone only makes the data interleaved (but the index data can stay
There's a chance the original data are already like this, in which case non-owned). Additionally we need to ensure the interleaved data are
this will be just a passthrough. */ tightly packed by removing InterleaveFlag::PreserveInterleavedAttributes
Trade::MeshData ownedInterleaved = owned(interleave(std::move(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{}));
/* Because the interleaved mesh was forced to be repacked, the vertex data
should span the whole stride -- this is relied on in the attribute
rerouting loop below */
const Containers::StridedArrayView2D<char> vertexData = MeshTools::interleavedMutableData(ownedInterleaved); const Containers::StridedArrayView2D<char> vertexData = MeshTools::interleavedMutableData(ownedInterleaved);
CORRADE_INTERNAL_ASSERT(vertexData.size()[1] == ownedInterleaved.attributeStride(0));
UnsignedInt uniqueVertexCount; UnsignedInt uniqueVertexCount;
Containers::Array<char> indexData; Containers::Array<char> indexData;

17
src/Magnum/MeshTools/RemoveDuplicates.h

@ -302,24 +302,13 @@ interleaved and owned, if the input is already interleaved attribute offsets
and paddings are preserved. All attributes are expected to not have an and paddings are preserved. All attributes are expected to not have an
implementation-specific format. implementation-specific format.
This function unconditionally copies and interleaves passed vertex and index In order to remove random padding values from the input and make the vertices
data in order to operate on them in-place. If your data is interleaved and suitable for fast in-place duplicate removal, this function unconditionally
owned by the instance and you don't need the original data after the process, copies and interleaves the input vertex and index data.
call @ref removeDuplicates(Trade::MeshData&&) instead to avoid the extra copy.
@see @ref isVertexFormatImplementationSpecific() @see @ref isVertexFormatImplementationSpecific()
*/ */
MAGNUM_MESHTOOLS_EXPORT Trade::MeshData removeDuplicates(const Trade::MeshData& data); MAGNUM_MESHTOOLS_EXPORT Trade::MeshData removeDuplicates(const Trade::MeshData& data);
/**
@brief Remove mesh data duplicates
@m_since{2020,06}
Same as @ref removeDuplicates(const Trade::MeshData&), except that it operates
in-place on the passed instance, avoiding an extra copy of vertex and index
data.
*/
MAGNUM_MESHTOOLS_EXPORT Trade::MeshData removeDuplicates(Trade::MeshData&& data);
/** /**
@brief Remove mesh data duplicates with fuzzy comparison for floating-point attributes @brief Remove mesh data duplicates with fuzzy comparison for floating-point attributes
@m_since{2020,06} @m_since{2020,06}

Loading…
Cancel
Save