Browse Source

MeshTools: disallow impl-spec index types in concatenate().

pull/547/head
Vladimír Vondruš 4 years ago
parent
commit
d44798c5df
  1. 4
      src/Magnum/MeshTools/Concatenate.cpp
  2. 10
      src/Magnum/MeshTools/Concatenate.h
  3. 38
      src/Magnum/MeshTools/Test/ConcatenateTest.cpp

4
src/Magnum/MeshTools/Concatenate.cpp

@ -120,6 +120,10 @@ Trade::MeshData concatenate(Containers::Array<char>&& indexData, const UnsignedI
/* If the mesh is indexed, copy the indices over, expanded to 32bit */ /* If the mesh is indexed, copy the indices over, expanded to 32bit */
if(mesh.isIndexed()) { if(mesh.isIndexed()) {
CORRADE_ASSERT(!isMeshIndexTypeImplementationSpecific(mesh.indexType()),
assertPrefix << "mesh" << i << "has an implementation-specific index type" << reinterpret_cast<void*>(meshIndexTypeUnwrap(mesh.indexType())),
(Trade::MeshData{MeshPrimitive{}, 0}));
Containers::ArrayView<UnsignedInt> dst = indices.slice(indexOffset, indexOffset + mesh.indexCount()); Containers::ArrayView<UnsignedInt> dst = indices.slice(indexOffset, indexOffset + mesh.indexCount());
mesh.indicesInto(dst); mesh.indicesInto(dst);
indexOffset += mesh.indexCount(); indexOffset += mesh.indexCount();

10
src/Magnum/MeshTools/Concatenate.h

@ -50,9 +50,10 @@ namespace Implementation {
@m_since{2020,06} @m_since{2020,06}
The returned mesh contains vertices from all meshes concatenated together. If The returned mesh contains vertices from all meshes concatenated together. If
any mesh is indexed, the resulting mesh is indexed as well, with indices any mesh is indexed (expected to not have an implementation-specific index
adjusted for vertex offsets of particular meshes. The behavior is undefined if type), the resulting mesh is indexed as well, with indices adjusted for vertex
any mesh has indices out of bounds for its particular vertex count. Meshes with offsets of particular meshes. The behavior is undefined if any mesh has indices
out of bounds for its particular vertex count. Meshes with
@ref MeshPrimitive::LineStrip, @ref MeshPrimitive::LineLoop, @ref MeshPrimitive::LineStrip, @ref MeshPrimitive::LineLoop,
@ref MeshPrimitive::TriangleStrip and @ref MeshPrimitive::TriangleFan can't be @ref MeshPrimitive::TriangleStrip and @ref MeshPrimitive::TriangleFan can't be
concatenated --- use @ref generateIndices() to turn them into concatenated --- use @ref generateIndices() to turn them into
@ -76,7 +77,8 @@ description.
If an index buffer is needed, @ref MeshIndexType::UnsignedInt is always used. If an index buffer is needed, @ref MeshIndexType::UnsignedInt is always used.
Call @ref compressIndices(const Trade::MeshData&, MeshIndexType) on the result Call @ref compressIndices(const Trade::MeshData&, MeshIndexType) on the result
to compress it to a smaller type, if desired. to compress it to a smaller type, if desired.
@see @ref concatenateInto(), @ref isVertexFormatImplementationSpecific(), @see @ref concatenateInto(), @ref isMeshIndexTypeImplementationSpecific(),
@ref isVertexFormatImplementationSpecific(),
@ref SceneTools::flattenMeshHierarchy2D(), @ref SceneTools::flattenMeshHierarchy2D(),
@ref SceneTools::flattenMeshHierarchy3D() @ref SceneTools::flattenMeshHierarchy3D()
*/ */

38
src/Magnum/MeshTools/Test/ConcatenateTest.cpp

@ -51,6 +51,7 @@ struct ConcatenateTest: TestSuite::Tester {
void concatenateInconsistentPrimitive(); void concatenateInconsistentPrimitive();
void concatenateInconsistentAttributeFormat(); void concatenateInconsistentAttributeFormat();
void concatenateInconsistentAttributeArraySize(); void concatenateInconsistentAttributeArraySize();
void concatenateImplementationSpecificIndexType();
void concatenateImplementationSpecificVertexFormat(); void concatenateImplementationSpecificVertexFormat();
void concatenateIntoNoMeshes(); void concatenateIntoNoMeshes();
}; };
@ -81,6 +82,7 @@ ConcatenateTest::ConcatenateTest() {
&ConcatenateTest::concatenateInconsistentPrimitive, &ConcatenateTest::concatenateInconsistentPrimitive,
&ConcatenateTest::concatenateInconsistentAttributeFormat, &ConcatenateTest::concatenateInconsistentAttributeFormat,
&ConcatenateTest::concatenateInconsistentAttributeArraySize, &ConcatenateTest::concatenateInconsistentAttributeArraySize,
&ConcatenateTest::concatenateImplementationSpecificIndexType,
&ConcatenateTest::concatenateImplementationSpecificVertexFormat, &ConcatenateTest::concatenateImplementationSpecificVertexFormat,
&ConcatenateTest::concatenateIntoNoMeshes}); &ConcatenateTest::concatenateIntoNoMeshes});
} }
@ -668,6 +670,42 @@ void ConcatenateTest::concatenateInconsistentAttributeArraySize() {
"MeshTools::concatenateInto(): expected array size 5 for attribute 2 (Trade::MeshAttribute::Custom(42)) but got 4 in mesh 3 attribute 1\n"); "MeshTools::concatenateInto(): expected array size 5 for attribute 2 (Trade::MeshAttribute::Custom(42)) but got 4 in mesh 3 attribute 1\n");
} }
void ConcatenateTest::concatenateImplementationSpecificIndexType() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
/* Things are a bit duplicated to test correct numbering */
Trade::MeshData a{MeshPrimitive::Lines, nullptr, {
Trade::MeshAttributeData{Trade::MeshAttribute::Position,
VertexFormat::Vector3, nullptr},
}};
const Trade::MeshData b{MeshPrimitive::Lines,
nullptr, Trade::MeshIndexData{meshIndexTypeWrap(0xcaca), Containers::StridedArrayView1D<const void>{}},
nullptr, {
Trade::MeshAttributeData{Trade::MeshAttribute::Position,
VertexFormat::Vector3, nullptr},
}};
Trade::MeshData bDestination{MeshPrimitive::Lines,
nullptr, Trade::MeshIndexData{meshIndexTypeWrap(0xcaca), Containers::StridedArrayView1D<const void>{}},
nullptr, {
Trade::MeshAttributeData{Trade::MeshAttribute::Position,
VertexFormat::Vector3, nullptr},
}};
/* This is fine, as the mesh index buffer is cleared and replaced with
a tightly-packed 32bit buffer */
MeshTools::concatenateInto(bDestination, {a});
std::ostringstream out;
Error redirectError{&out};
MeshTools::concatenate({a, b});
MeshTools::concatenateInto(a, {b});
CORRADE_COMPARE(out.str(),
"MeshTools::concatenate(): mesh 1 has an implementation-specific index type 0xcaca\n"
"MeshTools::concatenateInto(): mesh 0 has an implementation-specific index type 0xcaca\n");
}
void ConcatenateTest::concatenateImplementationSpecificVertexFormat() { void ConcatenateTest::concatenateImplementationSpecificVertexFormat() {
#ifdef CORRADE_NO_ASSERT #ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");

Loading…
Cancel
Save