Browse Source

MeshTools: allow empty input in generate*Indices().

The restriction didn't make sense. Disallowing 1 input vertex for lines
or 1/2 input vertices for triangles sure, but 0 vertices should work as
the expected behavior is obvious.
pull/601/head
Vladimír Vondruš 3 years ago
parent
commit
5b22b0dbb9
  1. 7
      doc/changelog.dox
  2. 64
      src/Magnum/MeshTools/GenerateIndices.cpp
  3. 46
      src/Magnum/MeshTools/GenerateIndices.h
  4. 86
      src/Magnum/MeshTools/Test/GenerateIndicesTest.cpp

7
doc/changelog.dox

@ -544,6 +544,13 @@ See also:
@ref Trade::MeshAttribute::Weights in @ref MeshTools::compile() as well as
a new @ref MeshTools::compiledPerVertexJointCount() helper utility (see
also [mosra/magnum#444](https://github.com/mosra/magnum/pull/444))
- @ref MeshTools::generateLineStripIndices(),
@relativeref{MeshTools,generateLineLoopIndices()},
@relativeref{MeshTools,generateTriangleStripIndices()},
@relativeref{MeshTools,generateTriangleFanIndices()} and
@relativeref{MeshTools,generateIndices()} now allow empty input, producing
an empty index buffer as a result. Disallowing empty input was an
unnecessary restriction that was inconsistent with other APIs.
@subsubsection changelog-latest-changes-platform Platform libraries

64
src/Magnum/MeshTools/GenerateIndices.cpp

@ -58,10 +58,12 @@ UnsignedInt primitiveCount(const MeshPrimitive primitive, const UnsignedInt elem
}
void generateLineStripIndicesInto(const UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& indices) {
CORRADE_ASSERT(vertexCount >= 2,
"MeshTools::generateLineStripIndicesInto(): expected at least two vertices, got" << vertexCount, );
CORRADE_ASSERT(indices.size() == 2*(vertexCount - 1),
"MeshTools::generateLineStripIndicesInto(): bad output size, expected" << 2*(vertexCount - 1) << "but got" << indices.size(), );
CORRADE_ASSERT(vertexCount == 0 || vertexCount >= 2,
"MeshTools::generateLineStripIndicesInto(): expected either zero or at least two vertices, got" << vertexCount, );
const UnsignedInt iMax = Math::max(vertexCount, 1u) - 1;
CORRADE_ASSERT(indices.size() == 2*iMax,
"MeshTools::generateLineStripIndicesInto(): bad output size, expected" << 2*iMax << "but got" << indices.size(), );
/*
1 --- 2 1 2 --- 3 4
@ -70,21 +72,21 @@ void generateLineStripIndicesInto(const UnsignedInt vertexCount, const Container
/ \ / \
0 3 0 5
*/
for(std::size_t i = 0; i != vertexCount - 1; ++i) {
for(std::size_t i = 0; i != iMax; ++i) {
indices[i*2 + 0] = i;
indices[i*2 + 1] = i + 1;
}
}
Containers::Array<UnsignedInt> generateLineStripIndices(const UnsignedInt vertexCount) {
Containers::Array<UnsignedInt> indices{NoInit, 2*(vertexCount - 1)};
Containers::Array<UnsignedInt> indices{NoInit, 2*(Math::max(vertexCount, 1u) - 1)};
generateLineStripIndicesInto(vertexCount, indices);
return indices;
}
void generateLineLoopIndicesInto(const UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& indices) {
CORRADE_ASSERT(vertexCount >= 2,
"MeshTools::generateLineLoopIndicesInto(): expected at least two vertices, got" << vertexCount, );
CORRADE_ASSERT(vertexCount == 0 || vertexCount >= 2,
"MeshTools::generateLineLoopIndicesInto(): expected either zero or at least two vertices, got" << vertexCount, );
CORRADE_ASSERT(indices.size() == 2*vertexCount,
"MeshTools::generateLineLoopIndicesInto(): bad output size, expected" << 2*vertexCount << "but got" << indices.size(), );
@ -97,12 +99,14 @@ void generateLineLoopIndicesInto(const UnsignedInt vertexCount, const Containers
/ \ / \
0 ----------- 3 0 7 ----------- 6 5
*/
for(std::size_t i = 0; i != vertexCount - 1; ++i) {
for(std::size_t i = 0, iMax = Math::max(vertexCount, 1u) - 1; i != iMax; ++i) {
indices[i*2 + 0] = i;
indices[i*2 + 1] = i + 1;
}
indices[2*vertexCount - 2] = vertexCount - 1;
indices[2*vertexCount - 1] = 0;
if(vertexCount >= 2) {
indices[2*vertexCount - 2] = vertexCount - 1;
indices[2*vertexCount - 1] = 0;
}
}
Containers::Array<UnsignedInt> generateLineLoopIndices(const UnsignedInt vertexCount) {
@ -112,10 +116,12 @@ Containers::Array<UnsignedInt> generateLineLoopIndices(const UnsignedInt vertexC
}
void generateTriangleStripIndicesInto(const UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& indices) {
CORRADE_ASSERT(vertexCount >= 3,
"MeshTools::generateTriangleStripIndicesInto(): expected at least three vertices, got" << vertexCount, );
CORRADE_ASSERT(indices.size() == 3*(vertexCount - 2),
"MeshTools::generateTriangleStripIndicesInto(): bad output size, expected" << 3*(vertexCount - 2) << "but got" << indices.size(), );
CORRADE_ASSERT(vertexCount == 0 || vertexCount >= 3,
"MeshTools::generateTriangleStripIndicesInto(): expected either zero or at least three vertices, got" << vertexCount, );
const UnsignedInt iMax = Math::max(vertexCount, 2u) - 2;
CORRADE_ASSERT(indices.size() == 3*iMax,
"MeshTools::generateTriangleStripIndicesInto(): bad output size, expected" << 3*iMax << "but got" << indices.size(), );
/*
Triangles starting with odd vertices (marked with !) have the first two
@ -127,7 +133,7 @@ void generateTriangleStripIndicesInto(const UnsignedInt vertexCount, const Conta
\ / \ / \ \ / / ! \ \ / / ! \
1 ----- 3 ----- 5 1 4 ----- 5 7 10 ---- 11
*/
for(std::size_t i = 0; i != vertexCount - 2; ++i) {
for(std::size_t i = 0; i != iMax; ++i) {
indices[i*3 + 0] = i % 2 ? i + 1 : i;
indices[i*3 + 1] = i % 2 ? i : i + 1;
indices[i*3 + 2] = i + 2;
@ -135,16 +141,18 @@ void generateTriangleStripIndicesInto(const UnsignedInt vertexCount, const Conta
}
Containers::Array<UnsignedInt> generateTriangleStripIndices(const UnsignedInt vertexCount) {
Containers::Array<UnsignedInt> indices{NoInit, 3*(vertexCount - 2)};
Containers::Array<UnsignedInt> indices{NoInit, 3*(Math::max(vertexCount, 2u) - 2u)};
generateTriangleStripIndicesInto(vertexCount, indices);
return indices;
}
void generateTriangleFanIndicesInto(const UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& indices) {
CORRADE_ASSERT(vertexCount >= 3,
"MeshTools::generateTriangleFanIndicesInto(): expected at least three vertices, got" << vertexCount, );
CORRADE_ASSERT(indices.size() == 3*(vertexCount - 2),
"MeshTools::generateTriangleFanIndicesInto(): bad output size, expected" << 3*(vertexCount - 2) << "but got" << indices.size(), );
CORRADE_ASSERT(vertexCount == 0 || vertexCount >= 3,
"MeshTools::generateTriangleFanIndicesInto(): expected either zero or at least three vertices, got" << vertexCount, );
const UnsignedInt iMax = Math::max(vertexCount, 2u) - 2;
CORRADE_ASSERT(indices.size() == 3*iMax,
"MeshTools::generateTriangleFanIndicesInto(): bad output size, expected" << 3*iMax << "but got" << indices.size(), );
/* 10 8 ----- 7 5
4 ----- 3 / \ \ / / \
@ -157,7 +165,7 @@ void generateTriangleFanIndicesInto(const UnsignedInt vertexCount, const Contain
\ / \ /
1 1
*/
for(std::size_t i = 0; i != vertexCount - 2; ++i) {
for(std::size_t i = 0; i != iMax; ++i) {
indices[i*3 + 0] = 0;
indices[i*3 + 1] = i + 1;
indices[i*3 + 2] = i + 2;
@ -165,7 +173,7 @@ void generateTriangleFanIndicesInto(const UnsignedInt vertexCount, const Contain
}
Containers::Array<UnsignedInt> generateTriangleFanIndices(const UnsignedInt vertexCount) {
Containers::Array<UnsignedInt> indices{NoInit, 3*(vertexCount - 2)};
Containers::Array<UnsignedInt> indices{NoInit, 3*(Math::max(vertexCount, 2u) - 2)};
generateTriangleFanIndicesInto(vertexCount, indices);
return indices;
}
@ -286,8 +294,8 @@ Trade::MeshData generateIndices(Trade::MeshData&& data) {
minVertexCount = 3;
} else CORRADE_ASSERT_UNREACHABLE("MeshTools::generateIndices(): invalid primitive" << data.primitive(),
(Trade::MeshData{MeshPrimitive::Triangles, 0}));
CORRADE_ASSERT(vertexCount >= minVertexCount,
"MeshTools::generateIndices(): expected at least" << minVertexCount << "vertices for" << data.primitive() << Debug::nospace << ", got" << vertexCount,
CORRADE_ASSERT(vertexCount == 0 || vertexCount >= minVertexCount,
"MeshTools::generateIndices(): expected either zero or at least" << minVertexCount << "vertices for" << data.primitive() << Debug::nospace << ", got" << vertexCount,
(Trade::MeshData{MeshPrimitive::Triangles, 0}));
#endif
@ -317,7 +325,7 @@ Trade::MeshData generateIndices(Trade::MeshData&& data) {
Containers::Array<char> indexData;
if(data.primitive() == MeshPrimitive::LineStrip) {
primitive = MeshPrimitive::Lines;
indexData = Containers::Array<char>{NoInit, 2*(vertexCount - 1)*sizeof(UnsignedInt)};
indexData = Containers::Array<char>{NoInit, 2*(Math::max(vertexCount, 1u) - 1)*sizeof(UnsignedInt)};
generateLineStripIndicesInto(vertexCount, Containers::arrayCast<UnsignedInt>(indexData));
} else if(data.primitive() == MeshPrimitive::LineLoop) {
primitive = MeshPrimitive::Lines;
@ -325,11 +333,11 @@ Trade::MeshData generateIndices(Trade::MeshData&& data) {
generateLineLoopIndicesInto(vertexCount, Containers::arrayCast<UnsignedInt>(indexData));
} else if(data.primitive() == MeshPrimitive::TriangleStrip) {
primitive = MeshPrimitive::Triangles;
indexData = Containers::Array<char>{NoInit, 3*(vertexCount - 2)*sizeof(UnsignedInt)};
indexData = Containers::Array<char>{NoInit, 3*(Math::max(vertexCount, 2u) - 2)*sizeof(UnsignedInt)};
generateTriangleStripIndicesInto(vertexCount, Containers::arrayCast<UnsignedInt>(indexData));
} else if(data.primitive() == MeshPrimitive::TriangleFan) {
primitive = MeshPrimitive::Triangles;
indexData = Containers::Array<char>{NoInit, 3*(vertexCount - 2)*sizeof(UnsignedInt)};
indexData = Containers::Array<char>{NoInit, 3*(Math::max(vertexCount, 2u) - 2)*sizeof(UnsignedInt)};
generateTriangleFanIndicesInto(vertexCount, Containers::arrayCast<UnsignedInt>(indexData));
} else CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */

46
src/Magnum/MeshTools/GenerateIndices.h

@ -53,8 +53,8 @@ MAGNUM_MESHTOOLS_EXPORT UnsignedInt primitiveCount(MeshPrimitive primitive, Unsi
@m_since{2020,06}
Can be used to convert a @ref MeshPrimitive::LineStrip mesh to
@ref MeshPrimitive::Lines. The @p vertexCount is expected to be at least
@cpp 2 @ce. Primitive restart is not supported.
@ref MeshPrimitive::Lines. The @p vertexCount is expected to be either
@cpp 0 @ce or at least @cpp 2 @ce. Primitive restart is not supported.
@see @ref generateLineStripIndicesInto(), @ref generateLineLoopIndices(),
@ref generateTriangleStripIndices(), @ref generateTriangleFanIndices(),
@ref generateIndices()
@ -66,9 +66,9 @@ MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineStripIndices(
@m_since{2020,06}
A variant of @ref generateLineStripIndicesInto() that fills existing memory
instead of allocating a new array. The @p vertexCount is expected to be at
least @cpp 2 @ce, the @p indices array is expected to have a size of
@cpp 2*(vertexCount - 1) @ce. Primitive restart is not supported.
instead of allocating a new array. The @p vertexCount is expected to be either
@cpp 0 @ce or at least @cpp 2 @ce, the @p indices array is expected to have a
size of @cpp 2*(vertexCount - 1) @ce. Primitive restart is not supported.
*/
MAGNUM_MESHTOOLS_EXPORT void generateLineStripIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& indices);
@ -77,8 +77,8 @@ MAGNUM_MESHTOOLS_EXPORT void generateLineStripIndicesInto(UnsignedInt vertexCoun
@m_since{2020,06}
Can be used to convert a @ref MeshPrimitive::LineLoop mesh to
@ref MeshPrimitive::Lines. The @p vertexCount is expected to be at least
@cpp 2 @ce. Primitive restart is not supported.
@ref MeshPrimitive::Lines. The @p vertexCount is expected to be either
@cpp 0 @ce or at least @cpp 2 @ce. Primitive restart is not supported.
@see @ref generateLineLoopIndicesInto(), @ref generateLineStripIndices(),
@ref generateTriangleStripIndices(), @ref generateTriangleFanIndices(),
@ref generateIndices()
@ -90,9 +90,9 @@ MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineLoopIndices(U
@m_since{2020,06}
A variant of @ref generateLineLoopIndicesInto() that fills existing memory
instead of allocating a new array. The @p vertexCount is expected to be at
least @cpp 2 @ce, the @p indices array is expected to have a size of
@cpp 2*vertexCount @ce. Primitive restart is not supported.
instead of allocating a new array. The @p vertexCount is expected to be either
@cpp 0 @ce or at least @cpp 2 @ce, the @p indices array is expected to have a
size of @cpp 2*vertexCount @ce. Primitive restart is not supported.
*/
MAGNUM_MESHTOOLS_EXPORT void generateLineLoopIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& into);
@ -101,8 +101,8 @@ MAGNUM_MESHTOOLS_EXPORT void generateLineLoopIndicesInto(UnsignedInt vertexCount
@m_since{2020,06}
Can be used to convert a @ref MeshPrimitive::TriangleStrip mesh to
@ref MeshPrimitive::Triangles. The @p vertexCount is expected to be at least
@cpp 3 @ce. Primitive restart is not supported.
@ref MeshPrimitive::Triangles. The @p vertexCount is expected to be either
@cpp 0 @ce or at least @cpp 3 @ce. Primitive restart is not supported.
@see @ref generateTriangleStripIndicesInto(), @ref generateLineStripIndices(),
@ref generateLineLoopIndices(), @ref generateTriangleFanIndices(),
@ref generateIndices()
@ -114,9 +114,9 @@ MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleStripIndi
@m_since{2020,06}
A variant of @ref generateTriangleStripIndicesInto() that fills existing memory
instead of allocating a new array. The @p vertexCount is expected to be at
least @cpp 3 @ce, the @p indices array is expected to have a size of
@cpp 3*(vertexCount - 2) @ce. Primitive restart is not supported.
instead of allocating a new array. The @p vertexCount is expected to be either
@cpp 0 @ce or at least @cpp 3 @ce, the @p indices array is expected to have a
size of @cpp 3*(vertexCount - 2) @ce. Primitive restart is not supported.
*/
MAGNUM_MESHTOOLS_EXPORT void generateTriangleStripIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& into);
@ -125,8 +125,8 @@ MAGNUM_MESHTOOLS_EXPORT void generateTriangleStripIndicesInto(UnsignedInt vertex
@m_since{2020,06}
Can be used to convert a @ref MeshPrimitive::TriangleFan mesh to
@ref MeshPrimitive::Triangles. The @p vertexCount is expected to be at least
@cpp 3 @ce. Primitive restart is not supported.
@ref MeshPrimitive::Triangles. The @p vertexCount is expected to be either
@cpp 0 @ce or at least @cpp 3 @ce. Primitive restart is not supported.
@see @ref generateTriangleFanIndicesInto(), @ref generateLineStripIndices(),
@ref generateLineLoopIndices(), @ref generateTriangleStripIndices(),
@ref generateIndices()
@ -138,9 +138,9 @@ MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleFanIndice
@m_since{2020,06}
A variant of @ref generateTriangleFanIndicesInto() that fills existing memory
instead of allocating a new array. The @p vertexCount is expected to be at
least @cpp 3 @ce, the @p indices array is expected to have a size of
@cpp 3*(vertexCount - 2) @ce. Primitive restart is not supported.
instead of allocating a new array. The @p vertexCount is expected to be either
@cpp 0 @ce or at least @cpp 3 @ce, the @p indices array is expected to have a
size of @cpp 3*(vertexCount - 2) @ce. Primitive restart is not supported.
*/
MAGNUM_MESHTOOLS_EXPORT void generateTriangleFanIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& into);
@ -214,9 +214,9 @@ MAGNUM_MESHTOOLS_EXPORT void generateQuadIndicesInto(const Containers::StridedAr
Expects that @p mesh is not indexed, is one of
@ref MeshPrimitive::LineStrip, @ref MeshPrimitive::LineLoop,
@ref MeshPrimitive::TriangleStrip, @ref MeshPrimitive::TriangleFan primitives
and has at least @cpp 2 @ce vertices for a line-based primitive or @cpp 3 @ce
vertices for a triangle-based primitive. Calls one of
@ref generateLineStripIndices(), @ref generateLineLoopIndices(),
and has either @cpp 0 @ce vertices or at least @cpp 2 @ce vertices for a
line-based primitive or @cpp 3 @ce vertices for a triangle-based primitive.
Calls one of @ref generateLineStripIndices(), @ref generateLineLoopIndices(),
@ref generateTriangleStripIndices() or @ref generateTriangleFanIndices()
functions to generate the index buffer. If your mesh is indexed, call
@ref duplicate(const Trade::MeshData& data, Containers::ArrayView<const Trade::MeshAttributeData>)

86
src/Magnum/MeshTools/Test/GenerateIndicesTest.cpp

@ -67,6 +67,7 @@ struct GenerateIndicesTest: TestSuite::Tester {
void generateQuadIndicesIntoWrongSize();
void generateIndicesMeshData();
void generateIndicesMeshDataEmpty();
void generateIndicesMeshDataMove();
void generateIndicesMeshDataNoAttributes();
void generateIndicesMeshDataIndexed();
@ -205,7 +206,8 @@ GenerateIndicesTest::GenerateIndicesTest() {
&GenerateIndicesTest::generateQuadIndicesIndexOutOfBounds,
&GenerateIndicesTest::generateQuadIndicesIntoWrongSize});
addInstancedTests({&GenerateIndicesTest::generateIndicesMeshData},
addInstancedTests({&GenerateIndicesTest::generateIndicesMeshData,
&GenerateIndicesTest::generateIndicesMeshDataEmpty},
Containers::arraySize(MeshDataData));
addTests({&GenerateIndicesTest::generateIndicesMeshDataMove,
@ -255,7 +257,12 @@ void GenerateIndicesTest::primitiveCountInvalidPrimitive() {
}
void GenerateIndicesTest::generateLineStripIndices() {
/* Minimal input */
/* Empty input */
CORRADE_COMPARE_AS(MeshTools::generateLineStripIndices(0),
Containers::ArrayView<const UnsignedInt>{},
TestSuite::Compare::Container);
/* Minimal non-empty input */
CORRADE_COMPARE_AS(MeshTools::generateLineStripIndices(2),
Containers::arrayView<UnsignedInt>({
0, 1
@ -288,7 +295,7 @@ void GenerateIndicesTest::generateLineStripIndicesWrongVertexCount() {
Error redirectError{&out};
MeshTools::generateLineStripIndicesInto(1, nullptr);
CORRADE_COMPARE(out.str(),
"MeshTools::generateLineStripIndicesInto(): expected at least two vertices, got 1\n");
"MeshTools::generateLineStripIndicesInto(): expected either zero or at least two vertices, got 1\n");
}
void GenerateIndicesTest::generateLineStripIndicesIntoWrongSize() {
@ -298,13 +305,20 @@ void GenerateIndicesTest::generateLineStripIndicesIntoWrongSize() {
std::ostringstream out;
Error redirectError{&out};
MeshTools::generateLineStripIndicesInto(0, indices);
MeshTools::generateLineStripIndicesInto(5, indices);
CORRADE_COMPARE(out.str(),
"MeshTools::generateLineStripIndicesInto(): bad output size, expected 0 but got 7\n"
"MeshTools::generateLineStripIndicesInto(): bad output size, expected 8 but got 7\n");
}
void GenerateIndicesTest::generateLineLoopIndices() {
/* Minimal input */
/* Empty input */
CORRADE_COMPARE_AS(MeshTools::generateLineLoopIndices(0),
Containers::ArrayView<const UnsignedInt>{},
TestSuite::Compare::Container);
/* Minimal non-empty input */
CORRADE_COMPARE_AS(MeshTools::generateLineLoopIndices(2),
Containers::arrayView<UnsignedInt>({
0, 1,
@ -340,7 +354,7 @@ void GenerateIndicesTest::generateLineLoopIndicesWrongVertexCount() {
Error redirectError{&out};
MeshTools::generateLineLoopIndicesInto(1, nullptr);
CORRADE_COMPARE(out.str(),
"MeshTools::generateLineLoopIndicesInto(): expected at least two vertices, got 1\n");
"MeshTools::generateLineLoopIndicesInto(): expected either zero or at least two vertices, got 1\n");
}
void GenerateIndicesTest::generateLineLoopIndicesIntoWrongSize() {
@ -350,13 +364,20 @@ void GenerateIndicesTest::generateLineLoopIndicesIntoWrongSize() {
std::ostringstream out;
Error redirectError{&out};
MeshTools::generateLineLoopIndicesInto(0, indices);
MeshTools::generateLineLoopIndicesInto(5, indices);
CORRADE_COMPARE(out.str(),
"MeshTools::generateLineLoopIndicesInto(): bad output size, expected 0 but got 9\n"
"MeshTools::generateLineLoopIndicesInto(): bad output size, expected 10 but got 9\n");
}
void GenerateIndicesTest::generateTriangleStripIndices() {
/* Minimal input */
/* Empty input */
CORRADE_COMPARE_AS(MeshTools::generateTriangleStripIndices(0),
Containers::ArrayView<const UnsignedInt>{},
TestSuite::Compare::Container);
/* Minimal non-empty input */
CORRADE_COMPARE_AS(MeshTools::generateTriangleStripIndices(3),
Containers::arrayView<UnsignedInt>({
0, 1, 2
@ -391,7 +412,7 @@ void GenerateIndicesTest::generateTriangleStripIndicesWrongVertexCount() {
Error redirectError{&out};
MeshTools::generateTriangleStripIndicesInto(2, nullptr);
CORRADE_COMPARE(out.str(),
"MeshTools::generateTriangleStripIndicesInto(): expected at least three vertices, got 2\n");
"MeshTools::generateTriangleStripIndicesInto(): expected either zero or at least three vertices, got 2\n");
}
void GenerateIndicesTest::generateTriangleStripIndicesIntoWrongSize() {
@ -401,13 +422,20 @@ void GenerateIndicesTest::generateTriangleStripIndicesIntoWrongSize() {
std::ostringstream out;
Error redirectError{&out};
MeshTools::generateTriangleStripIndicesInto(0, indices);
MeshTools::generateTriangleStripIndicesInto(5, indices);
CORRADE_COMPARE(out.str(),
"MeshTools::generateTriangleStripIndicesInto(): bad output size, expected 0 but got 8\n"
"MeshTools::generateTriangleStripIndicesInto(): bad output size, expected 9 but got 8\n");
}
void GenerateIndicesTest::generateTriangleFanIndices() {
/* Minimal input */
/* Empty input */
CORRADE_COMPARE_AS(MeshTools::generateTriangleFanIndices(0),
Containers::ArrayView<const UnsignedInt>{},
TestSuite::Compare::Container);
/* Minimal non-empty input */
CORRADE_COMPARE_AS(MeshTools::generateTriangleFanIndices(3),
Containers::arrayView<UnsignedInt>({
0, 1, 2
@ -442,7 +470,7 @@ void GenerateIndicesTest::generateTriangleFanIndicesWrongVertexCount() {
Error redirectError{&out};
MeshTools::generateTriangleFanIndicesInto(2, nullptr);
CORRADE_COMPARE(out.str(),
"MeshTools::generateTriangleFanIndicesInto(): expected at least three vertices, got 2\n");
"MeshTools::generateTriangleFanIndicesInto(): expected either zero or at least three vertices, got 2\n");
}
void GenerateIndicesTest::generateTriangleFanIndicesIntoWrongSize() {
@ -452,8 +480,10 @@ void GenerateIndicesTest::generateTriangleFanIndicesIntoWrongSize() {
std::ostringstream out;
Error redirectError{&out};
MeshTools::generateTriangleFanIndicesInto(0, indices);
MeshTools::generateTriangleFanIndicesInto(5, indices);
CORRADE_COMPARE(out.str(),
"MeshTools::generateTriangleFanIndicesInto(): bad output size, expected 0 but got 8\n"
"MeshTools::generateTriangleFanIndicesInto(): bad output size, expected 9 but got 8\n");
}
@ -654,6 +684,42 @@ void GenerateIndicesTest::generateIndicesMeshData() {
}), TestSuite::Compare::Container);
}
void GenerateIndicesTest::generateIndicesMeshDataEmpty() {
auto&& data = MeshDataData[testCaseInstanceId()];
{
std::ostringstream out;
Debug{&out, Debug::Flag::NoNewlineAtTheEnd} << data.primitive;
setTestCaseDescription(out.str());
}
/* Similar to generateIndicesMeshData(), just with 0 vertices. Verifying it
doesn't crash anywhere and produces an empty mesh as well. */
struct Vertex {
Vector2 position;
Short data[2];
Vector2 textureCoordinates;
};
Containers::StridedArrayView1D<const Vertex> vertices;
Trade::MeshData mesh{data.primitive, {}, nullptr, {
Trade::MeshAttributeData{Trade::MeshAttribute::Position,
vertices.slice(&Vertex::position)},
/* Array attribute to verify it's correctly propagated */
Trade::MeshAttributeData{Trade::meshAttributeCustom(42),
VertexFormat::Short,
vertices.slice(&Vertex::data), 2},
Trade::MeshAttributeData{Trade::MeshAttribute::TextureCoordinates,
vertices.slice(&Vertex::textureCoordinates)}
}};
Trade::MeshData out = generateIndices(mesh);
CORRADE_VERIFY(out.isIndexed());
CORRADE_COMPARE(out.indexCount(), 0);
CORRADE_COMPARE(out.attributeCount(), 3);
CORRADE_COMPARE(out.vertexCount(), 0);
}
void GenerateIndicesTest::generateIndicesMeshDataMove() {
struct Vertex {
Vector2 position;
@ -762,7 +828,7 @@ void GenerateIndicesTest::generateIndicesMeshDataInvalidVertexCount() {
Error redirectError{&out};
generateIndices(mesh);
CORRADE_COMPARE(out.str(), Utility::formatString(
"MeshTools::generateIndices(): expected at least {} vertices for {}, got {}\n", data.expectedVertexCount, primitiveName.str(), data.invalidVertexCount));
"MeshTools::generateIndices(): expected either zero or at least {} vertices for {}, got {}\n", data.expectedVertexCount, primitiveName.str(), data.invalidVertexCount));
}
}}}}

Loading…
Cancel
Save