Browse Source

MeshTools: support extra offset in all generate*Indices() APIs.

So these are usable for example when concatenating meshes together.
pull/659/head
Vladimír Vondruš 1 year ago
parent
commit
226bbe9ffc
  1. 264
      src/Magnum/MeshTools/GenerateIndices.cpp
  2. 164
      src/Magnum/MeshTools/GenerateIndices.h
  3. 173
      src/Magnum/MeshTools/Test/GenerateIndicesTest.cpp

264
src/Magnum/MeshTools/GenerateIndices.cpp

@ -85,18 +85,18 @@ UnsignedInt primitiveCount(const MeshPrimitive primitive, const UnsignedInt elem
CORRADE_ASSERT_UNREACHABLE("MeshTools::primitiveCount(): invalid primitive" << primitive, {}); CORRADE_ASSERT_UNREACHABLE("MeshTools::primitiveCount(): invalid primitive" << primitive, {});
} }
void generateTrivialIndicesInto(const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateTrivialIndicesInto(const Containers::StridedArrayView1D<UnsignedInt>& output, /*mutable*/ UnsignedInt offset) {
for(std::size_t i = 0; i != output.size(); ++i) for(std::size_t i = 0; i != output.size(); ++i)
output[i] = i; output[i] = offset++;
} }
Containers::Array<UnsignedInt> generateTrivialIndices(const UnsignedInt vertexCount) { Containers::Array<UnsignedInt> generateTrivialIndices(const UnsignedInt vertexCount, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, vertexCount}; Containers::Array<UnsignedInt> output{NoInit, vertexCount};
generateTrivialIndicesInto(output); generateTrivialIndicesInto(output, offset);
return output; return output;
} }
void generateLineStripIndicesInto(const UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateLineStripIndicesInto(const UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
CORRADE_ASSERT(vertexCount == 0 || vertexCount >= 2, CORRADE_ASSERT(vertexCount == 0 || vertexCount >= 2,
"MeshTools::generateLineStripIndicesInto(): expected either zero or at least two vertices, got" << vertexCount, ); "MeshTools::generateLineStripIndicesInto(): expected either zero or at least two vertices, got" << vertexCount, );
@ -112,14 +112,14 @@ void generateLineStripIndicesInto(const UnsignedInt vertexCount, const Container
0 3 0 5 0 3 0 5
*/ */
for(std::size_t i = 0; i != iMax; ++i) { for(std::size_t i = 0; i != iMax; ++i) {
output[i*2 + 0] = i; output[i*2 + 0] = offset + i;
output[i*2 + 1] = i + 1; output[i*2 + 1] = offset + i + 1;
} }
} }
namespace { namespace {
template<class T> void generateLineStripIndicesIntoImplementation(const Containers::StridedArrayView1D<const T>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { template<class T> void generateLineStripIndicesIntoImplementation(const Containers::StridedArrayView1D<const T>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
CORRADE_ASSERT(indices.size() == 0 || indices.size() >= 2, CORRADE_ASSERT(indices.size() == 0 || indices.size() >= 2,
"MeshTools::generateLineStripIndicesInto(): expected either zero or at least two indices, got" << indices.size(), ); "MeshTools::generateLineStripIndicesInto(): expected either zero or at least two indices, got" << indices.size(), );
@ -130,67 +130,67 @@ template<class T> void generateLineStripIndicesIntoImplementation(const Containe
/* Same as generateLineStripIndicesInto() above, just with the index array /* Same as generateLineStripIndicesInto() above, just with the index array
indirection on top */ indirection on top */
for(std::size_t i = 0; i != iMax; ++i) { for(std::size_t i = 0; i != iMax; ++i) {
output[i*2 + 0] = indices[i]; output[i*2 + 0] = offset + indices[i];
output[i*2 + 1] = indices[i + 1]; output[i*2 + 1] = offset + indices[i + 1];
} }
} }
} }
void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateLineStripIndicesIntoImplementation(indices, output); generateLineStripIndicesIntoImplementation(indices, output, offset);
} }
void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateLineStripIndicesIntoImplementation(indices, output); generateLineStripIndicesIntoImplementation(indices, output, offset);
} }
void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateLineStripIndicesIntoImplementation(indices, output); generateLineStripIndicesIntoImplementation(indices, output, offset);
} }
void generateLineStripIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateLineStripIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
CORRADE_ASSERT(indices.isContiguous<1>(), "MeshTools::generateLineStripIndicesInto(): second index view dimension is not contiguous", ); CORRADE_ASSERT(indices.isContiguous<1>(), "MeshTools::generateLineStripIndicesInto(): second index view dimension is not contiguous", );
if(indices.size()[1] == 4) if(indices.size()[1] == 4)
return generateLineStripIndicesInto(Containers::arrayCast<1, const UnsignedInt>(indices), output); return generateLineStripIndicesInto(Containers::arrayCast<1, const UnsignedInt>(indices), output, offset);
else if(indices.size()[1] == 2) else if(indices.size()[1] == 2)
return generateLineStripIndicesInto(Containers::arrayCast<1, const UnsignedShort>(indices), output); return generateLineStripIndicesInto(Containers::arrayCast<1, const UnsignedShort>(indices), output, offset);
else if(indices.size()[1] == 1) else if(indices.size()[1] == 1)
return generateLineStripIndicesInto(Containers::arrayCast<1, const UnsignedByte>(indices), output); return generateLineStripIndicesInto(Containers::arrayCast<1, const UnsignedByte>(indices), output, offset);
else CORRADE_ASSERT_UNREACHABLE("MeshTools::generateLineStripIndicesInto(): expected index type size 1, 2 or 4 but got" << indices.size()[1], ); else CORRADE_ASSERT_UNREACHABLE("MeshTools::generateLineStripIndicesInto(): expected index type size 1, 2 or 4 but got" << indices.size()[1], );
} }
Containers::Array<UnsignedInt> generateLineStripIndices(const UnsignedInt vertexCount) { Containers::Array<UnsignedInt> generateLineStripIndices(const UnsignedInt vertexCount, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 2*(Math::max(vertexCount, 1u) - 1)}; Containers::Array<UnsignedInt> output{NoInit, 2*(Math::max(vertexCount, 1u) - 1)};
generateLineStripIndicesInto(vertexCount, output); generateLineStripIndicesInto(vertexCount, output, offset);
return output; return output;
} }
Containers::Array<UnsignedInt> generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices) { Containers::Array<UnsignedInt> generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 2*(Math::max(indices.size(), std::size_t{1}) - 1)}; Containers::Array<UnsignedInt> output{NoInit, 2*(Math::max(indices.size(), std::size_t{1}) - 1)};
generateLineStripIndicesInto(indices, output); generateLineStripIndicesInto(indices, output, offset);
return output; return output;
} }
Containers::Array<UnsignedInt> generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices) { Containers::Array<UnsignedInt> generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 2*(Math::max(indices.size(), std::size_t{1}) - 1)}; Containers::Array<UnsignedInt> output{NoInit, 2*(Math::max(indices.size(), std::size_t{1}) - 1)};
generateLineStripIndicesInto(indices, output); generateLineStripIndicesInto(indices, output, offset);
return output; return output;
} }
Containers::Array<UnsignedInt> generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices) { Containers::Array<UnsignedInt> generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 2*(Math::max(indices.size(), std::size_t{1}) - 1)}; Containers::Array<UnsignedInt> output{NoInit, 2*(Math::max(indices.size(), std::size_t{1}) - 1)};
generateLineStripIndicesInto(indices, output); generateLineStripIndicesInto(indices, output, offset);
return output; return output;
} }
Containers::Array<UnsignedInt> generateLineStripIndices(const Containers::StridedArrayView2D<const char>& indices) { Containers::Array<UnsignedInt> generateLineStripIndices(const Containers::StridedArrayView2D<const char>& indices, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 2*(Math::max(indices.size()[0], std::size_t{1}) - 1)}; Containers::Array<UnsignedInt> output{NoInit, 2*(Math::max(indices.size()[0], std::size_t{1}) - 1)};
generateLineStripIndicesInto(indices, output); generateLineStripIndicesInto(indices, output, offset);
return output; return output;
} }
void generateLineLoopIndicesInto(const UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateLineLoopIndicesInto(const UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
CORRADE_ASSERT(vertexCount == 0 || vertexCount >= 2, CORRADE_ASSERT(vertexCount == 0 || vertexCount >= 2,
"MeshTools::generateLineLoopIndicesInto(): expected either zero or at least two vertices, got" << vertexCount, ); "MeshTools::generateLineLoopIndicesInto(): expected either zero or at least two vertices, got" << vertexCount, );
CORRADE_ASSERT(output.size() == 2*vertexCount, CORRADE_ASSERT(output.size() == 2*vertexCount,
@ -206,18 +206,18 @@ void generateLineLoopIndicesInto(const UnsignedInt vertexCount, const Containers
0 ----------- 3 0 7 ----------- 6 5 0 ----------- 3 0 7 ----------- 6 5
*/ */
for(std::size_t i = 0, iMax = Math::max(vertexCount, 1u) - 1; i != iMax; ++i) { for(std::size_t i = 0, iMax = Math::max(vertexCount, 1u) - 1; i != iMax; ++i) {
output[i*2 + 0] = i; output[i*2 + 0] = offset + i;
output[i*2 + 1] = i + 1; output[i*2 + 1] = offset + i + 1;
} }
if(vertexCount >= 2) { if(vertexCount >= 2) {
output[2*vertexCount - 2] = vertexCount - 1; output[2*vertexCount - 2] = offset + vertexCount - 1;
output[2*vertexCount - 1] = 0; output[2*vertexCount - 1] = offset + 0;
} }
} }
namespace { namespace {
template<class T> void generateLineLoopIndicesIntoImplementation(const Containers::StridedArrayView1D<const T>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { template<class T> void generateLineLoopIndicesIntoImplementation(const Containers::StridedArrayView1D<const T>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
CORRADE_ASSERT(indices.size() == 0 || indices.size() >= 2, CORRADE_ASSERT(indices.size() == 0 || indices.size() >= 2,
"MeshTools::generateLineLoopIndicesInto(): expected either zero or at least two indices, got" << indices.size(), ); "MeshTools::generateLineLoopIndicesInto(): expected either zero or at least two indices, got" << indices.size(), );
CORRADE_ASSERT(output.size() == 2*indices.size(), CORRADE_ASSERT(output.size() == 2*indices.size(),
@ -226,71 +226,71 @@ template<class T> void generateLineLoopIndicesIntoImplementation(const Container
/* Same as generateLineLoopIndicesInto() above, just with the index array /* Same as generateLineLoopIndicesInto() above, just with the index array
indirection on top */ indirection on top */
for(std::size_t i = 0, iMax = Math::max(indices.size(), std::size_t{1}) - 1; i != iMax; ++i) { for(std::size_t i = 0, iMax = Math::max(indices.size(), std::size_t{1}) - 1; i != iMax; ++i) {
output[i*2 + 0] = indices[i]; output[i*2 + 0] = offset + indices[i];
output[i*2 + 1] = indices[i + 1]; output[i*2 + 1] = offset + indices[i + 1];
} }
if(indices.size() >= 2) { if(indices.size() >= 2) {
output[2*indices.size() - 2] = indices[indices.size() - 1]; output[2*indices.size() - 2] = offset + indices[indices.size() - 1];
output[2*indices.size() - 1] = indices[0]; output[2*indices.size() - 1] = offset + indices[0];
} }
} }
} }
void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateLineLoopIndicesIntoImplementation(indices, output); generateLineLoopIndicesIntoImplementation(indices, output, offset);
} }
void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateLineLoopIndicesIntoImplementation(indices, output); generateLineLoopIndicesIntoImplementation(indices, output, offset);
} }
void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateLineLoopIndicesIntoImplementation(indices, output); generateLineLoopIndicesIntoImplementation(indices, output, offset);
} }
void generateLineLoopIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateLineLoopIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
CORRADE_ASSERT(indices.isContiguous<1>(), "MeshTools::generateLineLoopIndicesInto(): second index view dimension is not contiguous", ); CORRADE_ASSERT(indices.isContiguous<1>(), "MeshTools::generateLineLoopIndicesInto(): second index view dimension is not contiguous", );
if(indices.size()[1] == 4) if(indices.size()[1] == 4)
return generateLineLoopIndicesInto(Containers::arrayCast<1, const UnsignedInt>(indices), output); return generateLineLoopIndicesInto(Containers::arrayCast<1, const UnsignedInt>(indices), output, offset);
else if(indices.size()[1] == 2) else if(indices.size()[1] == 2)
return generateLineLoopIndicesInto(Containers::arrayCast<1, const UnsignedShort>(indices), output); return generateLineLoopIndicesInto(Containers::arrayCast<1, const UnsignedShort>(indices), output, offset);
else if(indices.size()[1] == 1) else if(indices.size()[1] == 1)
return generateLineLoopIndicesInto(Containers::arrayCast<1, const UnsignedByte>(indices), output); return generateLineLoopIndicesInto(Containers::arrayCast<1, const UnsignedByte>(indices), output, offset);
else CORRADE_ASSERT_UNREACHABLE("MeshTools::generateLineLoopIndicesInto(): expected index type size 1, 2 or 4 but got" << indices.size()[1], ); else CORRADE_ASSERT_UNREACHABLE("MeshTools::generateLineLoopIndicesInto(): expected index type size 1, 2 or 4 but got" << indices.size()[1], );
} }
Containers::Array<UnsignedInt> generateLineLoopIndices(const UnsignedInt vertexCount) { Containers::Array<UnsignedInt> generateLineLoopIndices(const UnsignedInt vertexCount, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 2*vertexCount}; Containers::Array<UnsignedInt> output{NoInit, 2*vertexCount};
generateLineLoopIndicesInto(vertexCount, output); generateLineLoopIndicesInto(vertexCount, output, offset);
return output; return output;
} }
Containers::Array<UnsignedInt> generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices) { Containers::Array<UnsignedInt> generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 2*indices.size()}; Containers::Array<UnsignedInt> output{NoInit, 2*indices.size()};
generateLineLoopIndicesInto(indices, output); generateLineLoopIndicesInto(indices, output, offset);
return output; return output;
} }
Containers::Array<UnsignedInt> generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices) { Containers::Array<UnsignedInt> generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 2*indices.size()}; Containers::Array<UnsignedInt> output{NoInit, 2*indices.size()};
generateLineLoopIndicesInto(indices, output); generateLineLoopIndicesInto(indices, output, offset);
return output; return output;
} }
Containers::Array<UnsignedInt> generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices) { Containers::Array<UnsignedInt> generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 2*indices.size()}; Containers::Array<UnsignedInt> output{NoInit, 2*indices.size()};
generateLineLoopIndicesInto(indices, output); generateLineLoopIndicesInto(indices, output, offset);
return output; return output;
} }
Containers::Array<UnsignedInt> generateLineLoopIndices(const Containers::StridedArrayView2D<const char>& indices) { Containers::Array<UnsignedInt> generateLineLoopIndices(const Containers::StridedArrayView2D<const char>& indices, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 2*indices.size()[0]}; Containers::Array<UnsignedInt> output{NoInit, 2*indices.size()[0]};
generateLineLoopIndicesInto(indices, output); generateLineLoopIndicesInto(indices, output, offset);
return output; return output;
} }
void generateTriangleStripIndicesInto(const UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateTriangleStripIndicesInto(const UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
CORRADE_ASSERT(vertexCount == 0 || vertexCount >= 3, CORRADE_ASSERT(vertexCount == 0 || vertexCount >= 3,
"MeshTools::generateTriangleStripIndicesInto(): expected either zero or at least three vertices, got" << vertexCount, ); "MeshTools::generateTriangleStripIndicesInto(): expected either zero or at least three vertices, got" << vertexCount, );
@ -309,15 +309,15 @@ void generateTriangleStripIndicesInto(const UnsignedInt vertexCount, const Conta
1 ----- 3 ----- 5 1 4 ----- 5 7 10 ---- 11 1 ----- 3 ----- 5 1 4 ----- 5 7 10 ---- 11
*/ */
for(std::size_t i = 0; i != iMax; ++i) { for(std::size_t i = 0; i != iMax; ++i) {
output[i*3 + 0] = i % 2 ? i + 1 : i; output[i*3 + 0] = offset + (i % 2 ? i + 1 : i);
output[i*3 + 1] = i % 2 ? i : i + 1; output[i*3 + 1] = offset + (i % 2 ? i : i + 1);
output[i*3 + 2] = i + 2; output[i*3 + 2] = offset + i + 2;
} }
} }
namespace { namespace {
template<class T> void generateTriangleStripIndicesIntoImplementation(const Containers::StridedArrayView1D<const T>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { template<class T> void generateTriangleStripIndicesIntoImplementation(const Containers::StridedArrayView1D<const T>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
CORRADE_ASSERT(indices.size() == 0 || indices.size() >= 3, CORRADE_ASSERT(indices.size() == 0 || indices.size() >= 3,
"MeshTools::generateTriangleStripIndicesInto(): expected either zero or at least three indices, got" << indices.size(), ); "MeshTools::generateTriangleStripIndicesInto(): expected either zero or at least three indices, got" << indices.size(), );
@ -328,68 +328,68 @@ template<class T> void generateTriangleStripIndicesIntoImplementation(const Cont
/* Same as generateTriangleStripIndicesInto() above, just with the index /* Same as generateTriangleStripIndicesInto() above, just with the index
array indirection on top */ array indirection on top */
for(std::size_t i = 0; i != iMax; ++i) { for(std::size_t i = 0; i != iMax; ++i) {
output[i*3 + 0] = indices[i % 2 ? i + 1 : i]; output[i*3 + 0] = offset + indices[i % 2 ? i + 1 : i];
output[i*3 + 1] = indices[i % 2 ? i : i + 1]; output[i*3 + 1] = offset + indices[i % 2 ? i : i + 1];
output[i*3 + 2] = indices[i + 2]; output[i*3 + 2] = offset + indices[i + 2];
} }
} }
} }
void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateTriangleStripIndicesIntoImplementation(indices, output); generateTriangleStripIndicesIntoImplementation(indices, output, offset);
} }
void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateTriangleStripIndicesIntoImplementation(indices, output); generateTriangleStripIndicesIntoImplementation(indices, output, offset);
} }
void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateTriangleStripIndicesIntoImplementation(indices, output); generateTriangleStripIndicesIntoImplementation(indices, output, offset);
} }
void generateTriangleStripIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateTriangleStripIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
CORRADE_ASSERT(indices.isContiguous<1>(), "MeshTools::generateTriangleStripIndicesInto(): second index view dimension is not contiguous", ); CORRADE_ASSERT(indices.isContiguous<1>(), "MeshTools::generateTriangleStripIndicesInto(): second index view dimension is not contiguous", );
if(indices.size()[1] == 4) if(indices.size()[1] == 4)
return generateTriangleStripIndicesInto(Containers::arrayCast<1, const UnsignedInt>(indices), output); return generateTriangleStripIndicesInto(Containers::arrayCast<1, const UnsignedInt>(indices), output, offset);
else if(indices.size()[1] == 2) else if(indices.size()[1] == 2)
return generateTriangleStripIndicesInto(Containers::arrayCast<1, const UnsignedShort>(indices), output); return generateTriangleStripIndicesInto(Containers::arrayCast<1, const UnsignedShort>(indices), output, offset);
else if(indices.size()[1] == 1) else if(indices.size()[1] == 1)
return generateTriangleStripIndicesInto(Containers::arrayCast<1, const UnsignedByte>(indices), output); return generateTriangleStripIndicesInto(Containers::arrayCast<1, const UnsignedByte>(indices), output, offset);
else CORRADE_ASSERT_UNREACHABLE("MeshTools::generateTriangleStripIndicesInto(): expected index type size 1, 2 or 4 but got" << indices.size()[1], ); else CORRADE_ASSERT_UNREACHABLE("MeshTools::generateTriangleStripIndicesInto(): expected index type size 1, 2 or 4 but got" << indices.size()[1], );
} }
Containers::Array<UnsignedInt> generateTriangleStripIndices(const UnsignedInt vertexCount) { Containers::Array<UnsignedInt> generateTriangleStripIndices(const UnsignedInt vertexCount, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(vertexCount, 2u) - 2u)}; Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(vertexCount, 2u) - 2u)};
generateTriangleStripIndicesInto(vertexCount, output); generateTriangleStripIndicesInto(vertexCount, output, offset);
return output; return output;
} }
Containers::Array<UnsignedInt> generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices) { Containers::Array<UnsignedInt> generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(indices.size(), std::size_t{2}) - 2)}; Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(indices.size(), std::size_t{2}) - 2)};
generateTriangleStripIndicesInto(indices, output); generateTriangleStripIndicesInto(indices, output, offset);
return output; return output;
} }
Containers::Array<UnsignedInt> generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices) { Containers::Array<UnsignedInt> generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(indices.size(), std::size_t{2}) - 2)}; Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(indices.size(), std::size_t{2}) - 2)};
generateTriangleStripIndicesInto(indices, output); generateTriangleStripIndicesInto(indices, output, offset);
return output; return output;
} }
Containers::Array<UnsignedInt> generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices) { Containers::Array<UnsignedInt> generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(indices.size(), std::size_t{2}) - 2)}; Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(indices.size(), std::size_t{2}) - 2)};
generateTriangleStripIndicesInto(indices, output); generateTriangleStripIndicesInto(indices, output, offset);
return output; return output;
} }
Containers::Array<UnsignedInt> generateTriangleStripIndices(const Containers::StridedArrayView2D<const char>& indices) { Containers::Array<UnsignedInt> generateTriangleStripIndices(const Containers::StridedArrayView2D<const char>& indices, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(indices.size()[0], std::size_t{2}) - 2)}; Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(indices.size()[0], std::size_t{2}) - 2)};
generateTriangleStripIndicesInto(indices, output); generateTriangleStripIndicesInto(indices, output, offset);
return output; return output;
} }
void generateTriangleFanIndicesInto(const UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateTriangleFanIndicesInto(const UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
CORRADE_ASSERT(vertexCount == 0 || vertexCount >= 3, CORRADE_ASSERT(vertexCount == 0 || vertexCount >= 3,
"MeshTools::generateTriangleFanIndicesInto(): expected either zero or at least three vertices, got" << vertexCount, ); "MeshTools::generateTriangleFanIndicesInto(): expected either zero or at least three vertices, got" << vertexCount, );
@ -409,15 +409,15 @@ void generateTriangleFanIndicesInto(const UnsignedInt vertexCount, const Contain
1 1 1 1
*/ */
for(std::size_t i = 0; i != iMax; ++i) { for(std::size_t i = 0; i != iMax; ++i) {
output[i*3 + 0] = 0; output[i*3 + 0] = offset + 0;
output[i*3 + 1] = i + 1; output[i*3 + 1] = offset + i + 1;
output[i*3 + 2] = i + 2; output[i*3 + 2] = offset + i + 2;
} }
} }
namespace { namespace {
template<class T> void generateTriangleFanIndicesIntoImplementation(const Containers::StridedArrayView1D<const T>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { template<class T> void generateTriangleFanIndicesIntoImplementation(const Containers::StridedArrayView1D<const T>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
CORRADE_ASSERT(indices.size() == 0 || indices.size() >= 3, CORRADE_ASSERT(indices.size() == 0 || indices.size() >= 3,
"MeshTools::generateTriangleFanIndicesInto(): expected either zero or at least three indices, got" << indices.size(), ); "MeshTools::generateTriangleFanIndicesInto(): expected either zero or at least three indices, got" << indices.size(), );
@ -428,70 +428,70 @@ template<class T> void generateTriangleFanIndicesIntoImplementation(const Contai
/* Same as generateTriangleStripIndicesInto() above, just with the index /* Same as generateTriangleStripIndicesInto() above, just with the index
array indirection on top */ array indirection on top */
for(std::size_t i = 0; i != iMax; ++i) { for(std::size_t i = 0; i != iMax; ++i) {
output[i*3 + 0] = indices[0]; output[i*3 + 0] = offset + indices[0];
output[i*3 + 1] = indices[i + 1]; output[i*3 + 1] = offset + indices[i + 1];
output[i*3 + 2] = indices[i + 2]; output[i*3 + 2] = offset + indices[i + 2];
} }
} }
} }
void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateTriangleFanIndicesIntoImplementation(indices, output); generateTriangleFanIndicesIntoImplementation(indices, output, offset);
} }
void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateTriangleFanIndicesIntoImplementation(indices, output); generateTriangleFanIndicesIntoImplementation(indices, output, offset);
} }
void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateTriangleFanIndicesIntoImplementation(indices, output); generateTriangleFanIndicesIntoImplementation(indices, output, offset);
} }
void generateTriangleFanIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateTriangleFanIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
CORRADE_ASSERT(indices.isContiguous<1>(), "MeshTools::generateTriangleFanIndicesInto(): second index view dimension is not contiguous", ); CORRADE_ASSERT(indices.isContiguous<1>(), "MeshTools::generateTriangleFanIndicesInto(): second index view dimension is not contiguous", );
if(indices.size()[1] == 4) if(indices.size()[1] == 4)
return generateTriangleFanIndicesInto(Containers::arrayCast<1, const UnsignedInt>(indices), output); return generateTriangleFanIndicesInto(Containers::arrayCast<1, const UnsignedInt>(indices), output, offset);
else if(indices.size()[1] == 2) else if(indices.size()[1] == 2)
return generateTriangleFanIndicesInto(Containers::arrayCast<1, const UnsignedShort>(indices), output); return generateTriangleFanIndicesInto(Containers::arrayCast<1, const UnsignedShort>(indices), output, offset);
else if(indices.size()[1] == 1) else if(indices.size()[1] == 1)
return generateTriangleFanIndicesInto(Containers::arrayCast<1, const UnsignedByte>(indices), output); return generateTriangleFanIndicesInto(Containers::arrayCast<1, const UnsignedByte>(indices), output, offset);
else CORRADE_ASSERT_UNREACHABLE("MeshTools::generateTriangleFanIndicesInto(): expected index type size 1, 2 or 4 but got" << indices.size()[1], ); else CORRADE_ASSERT_UNREACHABLE("MeshTools::generateTriangleFanIndicesInto(): expected index type size 1, 2 or 4 but got" << indices.size()[1], );
} }
Containers::Array<UnsignedInt> generateTriangleFanIndices(const UnsignedInt vertexCount) { Containers::Array<UnsignedInt> generateTriangleFanIndices(const UnsignedInt vertexCount, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(vertexCount, 2u) - 2)}; Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(vertexCount, 2u) - 2)};
generateTriangleFanIndicesInto(vertexCount, output); generateTriangleFanIndicesInto(vertexCount, output, offset);
return output; return output;
} }
Containers::Array<UnsignedInt> generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices) { Containers::Array<UnsignedInt> generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(indices.size(), std::size_t{2}) - 2)}; Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(indices.size(), std::size_t{2}) - 2)};
generateTriangleFanIndicesInto(indices, output); generateTriangleFanIndicesInto(indices, output, offset);
return output; return output;
} }
Containers::Array<UnsignedInt> generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices) { Containers::Array<UnsignedInt> generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(indices.size(), std::size_t{2}) - 2)}; Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(indices.size(), std::size_t{2}) - 2)};
generateTriangleFanIndicesInto(indices, output); generateTriangleFanIndicesInto(indices, output, offset);
return output; return output;
} }
Containers::Array<UnsignedInt> generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices) { Containers::Array<UnsignedInt> generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(indices.size(), std::size_t{2}) - 2)}; Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(indices.size(), std::size_t{2}) - 2)};
generateTriangleFanIndicesInto(indices, output); generateTriangleFanIndicesInto(indices, output, offset);
return output; return output;
} }
Containers::Array<UnsignedInt> generateTriangleFanIndices(const Containers::StridedArrayView2D<const char>& indices) { Containers::Array<UnsignedInt> generateTriangleFanIndices(const Containers::StridedArrayView2D<const char>& indices, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(indices.size()[0], std::size_t{2}) - 2)}; Containers::Array<UnsignedInt> output{NoInit, 3*(Math::max(indices.size()[0], std::size_t{2}) - 2)};
generateTriangleFanIndicesInto(indices, output); generateTriangleFanIndicesInto(indices, output, offset);
return output; return output;
} }
namespace { namespace {
template<class T> inline void generateQuadIndicesIntoImplementation(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const T>& quads, const Containers::StridedArrayView1D<T>& output) { template<class T> inline void generateQuadIndicesIntoImplementation(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const T>& quads, const Containers::StridedArrayView1D<T>& output, const UnsignedInt offset) {
CORRADE_ASSERT(quads.size() % 4 == 0, CORRADE_ASSERT(quads.size() % 4 == 0,
"MeshTools::generateQuadIndicesInto(): quad index count" << quads.size() << "not divisible by 4", ); "MeshTools::generateQuadIndicesInto(): quad index count" << quads.size() << "not divisible by 4", );
CORRADE_ASSERT(quads.size()*6/4 == output.size(), CORRADE_ASSERT(quads.size()*6/4 == output.size(),
@ -528,20 +528,20 @@ template<class T> inline void generateQuadIndicesIntoImplementation(const Contai
/* Assign the two triangles */ /* Assign the two triangles */
for(std::size_t j = 0; j != 6; ++j) for(std::size_t j = 0; j != 6; ++j)
output[6*i + j] = quads[4*i + split[j]]; output[6*i + j] = offset + quads[4*i + split[j]];
} }
} }
} }
Containers::Array<UnsignedInt> generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedInt>& quads) { Containers::Array<UnsignedInt> generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedInt>& quads, const UnsignedInt offset) {
/* We can skip zero-initialization here */ /* We can skip zero-initialization here */
Containers::Array<UnsignedInt> out{NoInit, quads.size()*6/4}; Containers::Array<UnsignedInt> out{NoInit, quads.size()*6/4};
generateQuadIndicesIntoImplementation(positions, quads, Containers::stridedArrayView(out)); generateQuadIndicesIntoImplementation(positions, quads, Containers::stridedArrayView(out), offset);
return out; return out;
} }
Containers::Array<UnsignedInt> generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedShort>& quads) { Containers::Array<UnsignedInt> generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedShort>& quads, const UnsignedInt offset) {
/* Explicitly ensure we have the unused bytes zeroed out */ /* Explicitly ensure we have the unused bytes zeroed out */
Containers::Array<UnsignedInt> out{ValueInit, quads.size()*6/4}; Containers::Array<UnsignedInt> out{ValueInit, quads.size()*6/4};
generateQuadIndicesIntoImplementation(positions, quads, generateQuadIndicesIntoImplementation(positions, quads,
@ -554,12 +554,12 @@ Containers::Array<UnsignedInt> generateQuadIndices(const Containers::StridedArra
#ifdef CORRADE_BIG_ENDIAN #ifdef CORRADE_BIG_ENDIAN
+ 1 + 1
#endif #endif
, out.size(), 4} , out.size(), 4},
); offset);
return out; return out;
} }
Containers::Array<UnsignedInt> generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedByte>& quads) { Containers::Array<UnsignedInt> generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedByte>& quads, const UnsignedInt offset) {
/* Explicitly ensure we have the unused bytes zeroed out */ /* Explicitly ensure we have the unused bytes zeroed out */
Containers::Array<UnsignedInt> out{ValueInit, quads.size()*6/4}; Containers::Array<UnsignedInt> out{ValueInit, quads.size()*6/4};
generateQuadIndicesIntoImplementation(positions, quads, generateQuadIndicesIntoImplementation(positions, quads,
@ -572,21 +572,21 @@ Containers::Array<UnsignedInt> generateQuadIndices(const Containers::StridedArra
#ifdef CORRADE_BIG_ENDIAN #ifdef CORRADE_BIG_ENDIAN
+ 3 + 3
#endif #endif
, out.size(), 4} , out.size(), 4},
); offset);
return out; return out;
} }
void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedInt>& quads, const Containers::StridedArrayView1D<UnsignedInt>& output) { void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedInt>& quads, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
return generateQuadIndicesIntoImplementation(positions, quads, output); return generateQuadIndicesIntoImplementation(positions, quads, output, offset);
} }
void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedShort>& quads, const Containers::StridedArrayView1D<UnsignedShort>& output) { void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedShort>& quads, const Containers::StridedArrayView1D<UnsignedShort>& output, const UnsignedInt offset) {
return generateQuadIndicesIntoImplementation(positions, quads, output); return generateQuadIndicesIntoImplementation(positions, quads, output, offset);
} }
void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedByte>& quads, const Containers::StridedArrayView1D<UnsignedByte>& output) { void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedByte>& quads, const Containers::StridedArrayView1D<UnsignedByte>& output, const UnsignedInt offset) {
return generateQuadIndicesIntoImplementation(positions, quads, output); return generateQuadIndicesIntoImplementation(positions, quads, output, offset);
} }
Trade::MeshData generateIndices(Trade::MeshData&& mesh) { Trade::MeshData generateIndices(Trade::MeshData&& mesh) {

164
src/Magnum/MeshTools/GenerateIndices.h

@ -55,12 +55,13 @@ MAGNUM_MESHTOOLS_EXPORT UnsignedInt primitiveCount(MeshPrimitive primitive, Unsi
@m_since_latest @m_since_latest
Generates a @cpp 0, 1, 2, 3, 4, 5, ... @ce sequence, i.e. what @ref std::iota() Generates a @cpp 0, 1, 2, 3, 4, 5, ... @ce sequence, i.e. what @ref std::iota()
would produce. Can be used to turn a non-indexed mesh into indexed. would produce, optionally with @p offset added to each index. Can be used to
turn a non-indexed mesh into indexed.
@see @ref generateTrivialIndicesInto(), @ref generateLineStripIndices(), @see @ref generateTrivialIndicesInto(), @ref generateLineStripIndices(),
@ref generateLineLoopIndices(), @ref generateTriangleStripIndices(), @ref generateLineLoopIndices(), @ref generateTriangleStripIndices(),
@ref generateTriangleFanIndices(), @ref generateIndices() @ref generateTriangleFanIndices(), @ref generateIndices()
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTrivialIndices(UnsignedInt vertexCount); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTrivialIndices(UnsignedInt vertexCount, UnsignedInt offset = 0);
/** /**
@brief Create a trivial index buffer into an existing array @brief Create a trivial index buffer into an existing array
@ -69,44 +70,44 @@ MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTrivialIndices(Un
A variant of @ref generateTrivialIndices() that fills existing memory A variant of @ref generateTrivialIndices() that fills existing memory
instead of allocating a new array. instead of allocating a new array.
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateTrivialIndicesInto(const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateTrivialIndicesInto(const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for a line strip primitive @brief Create index buffer for a line strip primitive
@m_since{2020,06} @m_since{2020,06}
Generates a @cpp 0, 1, 1, 2, 3, 4, ... @ce sequence. Can be used to convert a Generates a @cpp 0, 1, 1, 2, 3, 4, ... @ce sequence, optionally with @p offset
@ref MeshPrimitive::LineStrip mesh to @ref MeshPrimitive::Lines. The added to each index. Can be used to convert a @ref MeshPrimitive::LineStrip
@p vertexCount is expected to be either @cpp 0 @ce or at least @cpp 2 @ce. mesh to @ref MeshPrimitive::Lines. The @p vertexCount is expected to be either
Primitive restart is not supported. If the mesh is already indexed, use @cpp 0 @ce or at least @cpp 2 @ce. Primitive restart is not supported. If the
@ref generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>&) mesh is already indexed, use @ref generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>&, UnsignedInt)
and overloads instead. and overloads instead.
@see @ref generateLineStripIndicesInto(), @ref generateLineLoopIndices(), @see @ref generateLineStripIndicesInto(), @ref generateLineLoopIndices(),
@ref generateTriangleStripIndices(), @ref generateTriangleFanIndices(), @ref generateTriangleStripIndices(), @ref generateTriangleFanIndices(),
@ref generateTrivialIndices(), @ref generateIndices() @ref generateTrivialIndices(), @ref generateIndices()
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineStripIndices(UnsignedInt vertexCount); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineStripIndices(UnsignedInt vertexCount, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for an indexed line strip primitive @brief Create index buffer for an indexed line strip primitive
@m_since_latest @m_since_latest
Like @ref generateLineStripIndices(UnsignedInt), but merges @p indices into the Like @ref generateLineStripIndices(UnsignedInt, UnsignedInt), but merges
generated line strip index buffer. @p indices into the generated line strip index buffer.
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for a line strip primitive with a type-erased index buffer @brief Create index buffer for a line strip primitive with a type-erased index buffer
@ -114,10 +115,10 @@ MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineStripIndices(
Expects that the second dimension of @p indices is contiguous and represents Expects that the second dimension of @p indices is contiguous and represents
the actual 1/2/4-byte index type. Based on its size then calls one of the the actual 1/2/4-byte index type. Based on its size then calls one of the
@ref generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>&) @ref generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>&, UnsignedInt)
etc. overloads. etc. overloads.
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineStripIndices(const Containers::StridedArrayView2D<const char>& indices); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineStripIndices(const Containers::StridedArrayView2D<const char>& indices, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for a line strip primitive into an existing array @brief Create index buffer for a line strip primitive into an existing array
@ -127,31 +128,31 @@ A variant of @ref generateLineStripIndices() that fills existing memory instead
of allocating a new array. The @p vertexCount is expected to be either of allocating a new array. The @p vertexCount is expected to be either
@cpp 0 @ce or at least @cpp 2 @ce, the @p output array is expected to have a @cpp 0 @ce or at least @cpp 2 @ce, the @p output array is expected to have a
size of @cpp 2*(vertexCount - 1) @ce. Primitive restart is not supported. If size of @cpp 2*(vertexCount - 1) @ce. Primitive restart is not supported. If
the mesh is already indexed, use @ref generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&) the mesh is already indexed, use @ref generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&, UnsignedInt)
and overloads instead. and overloads instead.
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateLineStripIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateLineStripIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for an indexed line strip primitive into an existing array @brief Create index buffer for an indexed line strip primitive into an existing array
@m_since_latest @m_since_latest
Like @ref generateLineStripIndicesInto(UnsignedInt, const Containers::StridedArrayView1D<UnsignedInt>&), Like @ref generateLineStripIndicesInto(UnsignedInt, const Containers::StridedArrayView1D<UnsignedInt>&, UnsignedInt),
but merges @p indices into the generated line strip index buffer. but merges @p indices into the generated line strip index buffer.
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for a line strip primitive with a type-erased index buffer into an existing array @brief Create index buffer for a line strip primitive with a type-erased index buffer into an existing array
@ -159,25 +160,26 @@ MAGNUM_MESHTOOLS_EXPORT void generateLineStripIndicesInto(const Containers::Stri
Expects that the second dimension of @p indices is contiguous and represents Expects that the second dimension of @p indices is contiguous and represents
the actual 1/2/4-byte index type. Based on its size then calls one of the the actual 1/2/4-byte index type. Based on its size then calls one of the
@ref generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&) @ref generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&, UnsignedInt)
etc. overloads. etc. overloads.
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateLineStripIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateLineStripIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for a line loop primitive @brief Create index buffer for a line loop primitive
@m_since{2020,06} @m_since{2020,06}
Generates a @cpp 0, 1, 1, 2, 3, ..., 0 @ce sequence. Can be used to convert a @ref MeshPrimitive::LineLoop mesh to @ref MeshPrimitive::Lines. The Generates a @cpp 0, 1, 1, 2, 3, ..., 0 @ce sequence, optionally with @p offset
@p vertexCount is expected to be either @cpp 0 @ce or at least @cpp 2 @ce. added to each index. Can be used to convert a @ref MeshPrimitive::LineLoop mesh
Primitive restart is not supported. If the mesh is already indexed, use to @ref MeshPrimitive::Lines. The @p vertexCount is expected to be either
@ref generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedInt>&) @cpp 0 @ce or at least @cpp 2 @ce. Primitive restart is not supported. If the
mesh is already indexed, use @ref generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedInt>&)
and overloads instead. and overloads instead.
@see @ref generateLineLoopIndicesInto(), @ref generateLineStripIndices(), @see @ref generateLineLoopIndicesInto(), @ref generateLineStripIndices(),
@ref generateTriangleStripIndices(), @ref generateTriangleFanIndices(), @ref generateTriangleStripIndices(), @ref generateTriangleFanIndices(),
@ref generateTrivialIndices(), @ref generateIndices() @ref generateTrivialIndices(), @ref generateIndices()
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineLoopIndices(UnsignedInt vertexCount); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineLoopIndices(UnsignedInt vertexCount, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for an indexed line loop primitive @brief Create index buffer for an indexed line loop primitive
@ -186,19 +188,19 @@ MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineLoopIndices(U
Like @ref generateLineLoopIndices(UnsignedInt), but merges @p indices into the Like @ref generateLineLoopIndices(UnsignedInt), but merges @p indices into the
generated line loop index buffer. generated line loop index buffer.
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for a line loop primitive with a type-erased index buffer @brief Create index buffer for a line loop primitive with a type-erased index buffer
@ -209,7 +211,7 @@ the actual 1/2/4-byte index type. Based on its size then calls one of the
@ref generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedInt>&) @ref generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedInt>&)
etc. overloads. etc. overloads.
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineLoopIndices(const Containers::StridedArrayView2D<const char>& indices); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineLoopIndices(const Containers::StridedArrayView2D<const char>& indices, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for a line loop primitive into an existing array @brief Create index buffer for a line loop primitive into an existing array
@ -222,7 +224,7 @@ size of @cpp 2*vertexCount @ce. Primitive restart is not supported.If
the mesh is already indexed, use @ref generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&) the mesh is already indexed, use @ref generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&)
and overloads instead. and overloads instead.
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateLineLoopIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateLineLoopIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for an indexed line loop primitive into an existing array @brief Create index buffer for an indexed line loop primitive into an existing array
@ -231,19 +233,19 @@ MAGNUM_MESHTOOLS_EXPORT void generateLineLoopIndicesInto(UnsignedInt vertexCount
Like @ref generateLineLoopIndicesInto(UnsignedInt, const Containers::StridedArrayView1D<UnsignedInt>&), Like @ref generateLineLoopIndicesInto(UnsignedInt, const Containers::StridedArrayView1D<UnsignedInt>&),
but merges @p indices into the generated line loop index buffer. but merges @p indices into the generated line loop index buffer.
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for a line loop primitive with a type-erased index buffer into an existing array @brief Create index buffer for a line loop primitive with a type-erased index buffer into an existing array
@ -254,7 +256,7 @@ the actual 1/2/4-byte index type. Based on its size then calls one of the
@ref generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&) @ref generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&)
etc. overloads. etc. overloads.
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateLineLoopIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateLineLoopIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for a triangle strip primitive @brief Create index buffer for a triangle strip primitive
@ -270,7 +272,7 @@ and overloads instead.
@ref generateLineLoopIndices(), @ref generateTriangleFanIndices(), @ref generateLineLoopIndices(), @ref generateTriangleFanIndices(),
@ref generateTrivialIndices(), @ref generateIndices() @ref generateTrivialIndices(), @ref generateIndices()
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleStripIndices(UnsignedInt vertexCount); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleStripIndices(UnsignedInt vertexCount, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for an indexed triangle strip primitive @brief Create index buffer for an indexed triangle strip primitive
@ -279,19 +281,19 @@ MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleStripIndi
Like @ref generateTriangleStripIndices(UnsignedInt), but merges @p indices into Like @ref generateTriangleStripIndices(UnsignedInt), but merges @p indices into
the generated triangle strip index buffer. the generated triangle strip index buffer.
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for a triangle strip primitive with a type-erased index buffer @brief Create index buffer for a triangle strip primitive with a type-erased index buffer
@ -302,7 +304,7 @@ the actual 1/2/4-byte index type. Based on its size then calls one of the
@ref generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>&) @ref generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>&)
etc. overloads. etc. overloads.
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleStripIndices(const Containers::StridedArrayView2D<const char>& indices); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleStripIndices(const Containers::StridedArrayView2D<const char>& indices, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for a triangle strip primitive into an existing array @brief Create index buffer for a triangle strip primitive into an existing array
@ -312,31 +314,31 @@ A variant of @ref generateTriangleStripIndices() that fills existing memory
instead of allocating a new array. The @p vertexCount is expected to be either 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 output array is expected to have a @cpp 0 @ce or at least @cpp 3 @ce, the @p output array is expected to have a
size of @cpp 3*(vertexCount - 2) @ce. Primitive restart is not supported. If size of @cpp 3*(vertexCount - 2) @ce. Primitive restart is not supported. If
the mesh is already indexed, use @ref generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&) the mesh is already indexed, use @ref generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&, UnsignedInt)
and overloads instead. and overloads instead.
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateTriangleStripIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateTriangleStripIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for an indexed triangle strip primitive into an existing array @brief Create index buffer for an indexed triangle strip primitive into an existing array
@m_since_latest @m_since_latest
Like @ref generateTriangleStripIndicesInto(UnsignedInt, const Containers::StridedArrayView1D<UnsignedInt>&), Like @ref generateTriangleStripIndicesInto(UnsignedInt, const Containers::StridedArrayView1D<UnsignedInt>&, UnsignedInt),
but merges @p indices into the generated triangle strip index buffer. but merges @p indices into the generated triangle strip index buffer.
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for a triangle strip primitive with a type-erased index buffer into an existing array @brief Create index buffer for a triangle strip primitive with a type-erased index buffer into an existing array
@ -344,47 +346,48 @@ MAGNUM_MESHTOOLS_EXPORT void generateTriangleStripIndicesInto(const Containers::
Expects that the second dimension of @p indices is contiguous and represents Expects that the second dimension of @p indices is contiguous and represents
the actual 1/2/4-byte index type. Based on its size then calls one of the the actual 1/2/4-byte index type. Based on its size then calls one of the
@ref generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&) @ref generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&, UnsignedInt)
etc. overloads. etc. overloads.
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateTriangleStripIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateTriangleStripIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for a triangle fan primitive @brief Create index buffer for a triangle fan primitive
@m_since{2020,06} @m_since{2020,06}
Generates a @cpp 0, 1, 2, 0, 2, 3, 0, 3, 4, ... @ce sequence. Can be used to Generates a @cpp 0, 1, 2, 0, 2, 3, 0, 3, 4, ... @ce sequence, optionally with
convert a @ref MeshPrimitive::TriangleFan mesh to @p offset added to each index. Can be used to convert a
@ref MeshPrimitive::Triangles. The @p vertexCount is expected to be either @ref MeshPrimitive::TriangleFan mesh to @ref MeshPrimitive::Triangles. The
@cpp 0 @ce or at least @cpp 3 @ce. Primitive restart is not supported. If the @p vertexCount is expected to be either @cpp 0 @ce or at least @cpp 3 @ce.
mesh is already indexed, use @ref generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedInt>&) Primitive restart is not supported. If the mesh is already indexed, use
@ref generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedInt>&, UnsignedInt)
and overloads instead. and overloads instead.
@see @ref generateTriangleFanIndicesInto(), @ref generateLineStripIndices(), @see @ref generateTriangleFanIndicesInto(), @ref generateLineStripIndices(),
@ref generateLineLoopIndices(), @ref generateTriangleStripIndices(), @ref generateLineLoopIndices(), @ref generateTriangleStripIndices(),
@ref generateTrivialIndices(), @ref generateIndices() @ref generateTrivialIndices(), @ref generateIndices()
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleFanIndices(UnsignedInt vertexCount); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleFanIndices(UnsignedInt vertexCount, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for an indexed triangle fan primitive @brief Create index buffer for an indexed triangle fan primitive
@m_since_latest @m_since_latest
Like @ref generateTriangleFanIndices(UnsignedInt), but merges @p indices into Like @ref generateTriangleFanIndices(UnsignedInt, UnsignedInt), but merges
the generated triangle fan index buffer. @p indices into the generated triangle fan index buffer.
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for a triangle fan primitive with a type-erased index buffer @brief Create index buffer for a triangle fan primitive with a type-erased index buffer
@ -392,10 +395,10 @@ MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleFanIndice
Expects that the second dimension of @p indices is contiguous and represents Expects that the second dimension of @p indices is contiguous and represents
the actual 1/2/4-byte index type. Based on its size then calls one of the the actual 1/2/4-byte index type. Based on its size then calls one of the
@ref generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedInt>&) @ref generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedInt>&, UnsignedInt)
etc. overloads. etc. overloads.
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleFanIndices(const Containers::StridedArrayView2D<const char>& indices); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleFanIndices(const Containers::StridedArrayView2D<const char>& indices, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for a triangle fan primitive into an existing array @brief Create index buffer for a triangle fan primitive into an existing array
@ -405,31 +408,31 @@ A variant of @ref generateTriangleFanIndices() that fills existing memory
instead of allocating a new array. The @p vertexCount is expected to be either 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 output array is expected to have a @cpp 0 @ce or at least @cpp 3 @ce, the @p output array is expected to have a
size of @cpp 3*(vertexCount - 2) @ce. Primitive restart is not supported. If size of @cpp 3*(vertexCount - 2) @ce. Primitive restart is not supported. If
the mesh is already indexed, use @ref generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&) the mesh is already indexed, use @ref generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&, UnsignedInt)
and overloads instead. and overloads instead.
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateTriangleFanIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateTriangleFanIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for an indexed triangle fan primitive into an existing array @brief Create index buffer for an indexed triangle fan primitive into an existing array
@m_since_latest @m_since_latest
Like @ref generateTriangleFanIndicesInto(UnsignedInt, const Containers::StridedArrayView1D<UnsignedInt>&), Like @ref generateTriangleFanIndicesInto(UnsignedInt, const Containers::StridedArrayView1D<UnsignedInt>&, UnsignedInt),
but merges @p indices into the generated triangle fan index buffer. but merges @p indices into the generated triangle fan index buffer.
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
@brief Create index buffer for a triangle fan primitive with a type-erased index buffer into an existing array @brief Create index buffer for a triangle fan primitive with a type-erased index buffer into an existing array
@ -437,10 +440,10 @@ MAGNUM_MESHTOOLS_EXPORT void generateTriangleFanIndicesInto(const Containers::St
Expects that the second dimension of @p indices is contiguous and represents Expects that the second dimension of @p indices is contiguous and represents
the actual 1/2/4-byte index type. Based on its size then calls one of the the actual 1/2/4-byte index type. Based on its size then calls one of the
@ref generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&) @ref generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&, UnsignedInt)
etc. overloads. etc. overloads.
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateTriangleFanIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateTriangleFanIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
@brief Create a triangle index buffer for quad primitives @brief Create a triangle index buffer for quad primitives
@ -463,25 +466,26 @@ triangles where possible. Loosely based on [this SO question](https://stackoverf
the quad is non-planar and ambiguous, pick the case where the diagonal is the quad is non-planar and ambiguous, pick the case where the diagonal is
shorter shorter
Size of @p quads is expected to be divisible by @cpp 4 @ce and all indices Optionally adds @p offset to each index. Size of @p quads is expected to be
being in bounds of the @p positions view. divisible by @cpp 4 @ce and all indices being in bounds of the @p positions
view.
@see @ref generateQuadIndicesInto(), \n @see @ref generateQuadIndicesInto(), \n
@ref Math::cross(const Vector3<T>&, const Vector3<T>&), \n @ref Math::cross(const Vector3<T>&, const Vector3<T>&), \n
@ref Math::dot(const Vector<size, T>&, const Vector<size, T>&) @ref Math::dot(const Vector<size, T>&, const Vector<size, T>&)
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedInt>& quads); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedInt>& quads, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedShort>& quads); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedShort>& quads, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedByte>& quads); MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedByte>& quads, UnsignedInt offset = 0);
/** /**
@brief Create a triangle index buffer for quad primitives into an existing array @brief Create a triangle index buffer for quad primitives into an existing array
@ -491,19 +495,19 @@ A variant of @ref generateQuadIndices() that fills existing memory instead of
allocating a new array. Size of @p quads is expected to be divisible by allocating a new array. Size of @p quads is expected to be divisible by
@cpp 4 @ce and @p output should have a size that's @cpp quads.size()*6/4 @ce. @cpp 4 @ce and @p output should have a size that's @cpp quads.size()*6/4 @ce.
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedInt>& quads, const Containers::StridedArrayView1D<UnsignedInt>& output); MAGNUM_MESHTOOLS_EXPORT void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedInt>& quads, const Containers::StridedArrayView1D<UnsignedInt>& output, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedShort>& quads, const Containers::StridedArrayView1D<UnsignedShort>& output); MAGNUM_MESHTOOLS_EXPORT void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedShort>& quads, const Containers::StridedArrayView1D<UnsignedShort>& output, UnsignedInt offset = 0);
/** /**
* @overload * @overload
* @m_since_latest * @m_since_latest
*/ */
MAGNUM_MESHTOOLS_EXPORT void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedByte>& quads, const Containers::StridedArrayView1D<UnsignedByte>& output); MAGNUM_MESHTOOLS_EXPORT void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedByte>& quads, const Containers::StridedArrayView1D<UnsignedByte>& output, UnsignedInt offset = 0);
/** /**
@brief Convert a mesh to a plain indexed one @brief Convert a mesh to a plain indexed one

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

@ -100,59 +100,67 @@ using namespace Math::Literals;
const struct { const struct {
const char* name; const char* name;
UnsignedInt offset;
Matrix4 transformation; Matrix4 transformation;
UnsignedInt remap[4]; UnsignedInt remap[4];
UnsignedInt expected[6*5]; UnsignedInt expected[6*5];
} QuadData[] { } QuadData[] {
{"", {}, {0, 1, 2, 3}, { {"", 0, {}, {0, 1, 2, 3}, {
0, 2, 3, 0, 3, 4, // ABC ACD 0, 2, 3, 0, 3, 4, // ABC ACD
9, 5, 6, 9, 6, 7, // DAB DBC 9, 5, 6, 9, 6, 7, // DAB DBC
10, 11, 14, 10, 14, 15, // ABC ACD 10, 11, 14, 10, 14, 15, // ABC ACD
19, 16, 17, 19, 17, 18, // DAB DBC 19, 16, 17, 19, 17, 18, // DAB DBC
20, 21, 22, 20, 22, 23 // ABC ACD 20, 21, 22, 20, 22, 23 // ABC ACD
}}, }},
{"rotated indices 1", {}, {1, 2, 3, 0}, { {"rotated indices 1", 0, {}, {1, 2, 3, 0}, {
2, 3, 4, 2, 4, 0, // BCD BDA (both splits are fine) 2, 3, 4, 2, 4, 0, // BCD BDA (both splits are fine)
6, 7, 9, 6, 9, 5, // BCD BDA 6, 7, 9, 6, 9, 5, // BCD BDA
10, 11, 14, 10, 14, 15, // ABC ACD 10, 11, 14, 10, 14, 15, // ABC ACD
17, 18, 19, 17, 19, 16, // BCD BDA 17, 18, 19, 17, 19, 16, // BCD BDA
20, 21, 22, 20, 22, 23 // ABC ACD 20, 21, 22, 20, 22, 23 // ABC ACD
}}, }},
{"rotated indices 2", {}, {2, 3, 0, 1}, { {"rotated indices 2", 0, {}, {2, 3, 0, 1}, {
3, 4, 0, 3, 0, 2, // CDA CAB 3, 4, 0, 3, 0, 2, // CDA CAB
6, 7, 9, 6, 9, 5, // BCD BDA 6, 7, 9, 6, 9, 5, // BCD BDA
14, 15, 10, 14, 10, 11, // CDA CAB 14, 15, 10, 14, 10, 11, // CDA CAB
17, 18, 19, 17, 19, 16, // BCD BDA 17, 18, 19, 17, 19, 16, // BCD BDA
22, 23, 20, 22, 20, 21 // CDA CAB 22, 23, 20, 22, 20, 21 // CDA CAB
}}, }},
{"rotated indices 3", {}, {3, 0, 1, 2}, { {"rotated indices 3", 0, {}, {3, 0, 1, 2}, {
4, 0, 2, 4, 2, 3, // DAB DBC (both splits are fine) 4, 0, 2, 4, 2, 3, // DAB DBC (both splits are fine)
9, 5, 6, 9, 6, 7, // DAB DBC 9, 5, 6, 9, 6, 7, // DAB DBC
14, 15, 10, 14, 10, 11, // CDA CAB 14, 15, 10, 14, 10, 11, // CDA CAB
19, 16, 17, 19, 17, 18, // DAB DBC 19, 16, 17, 19, 17, 18, // DAB DBC
22, 23, 20, 22, 20, 21 // CDA CAB 22, 23, 20, 22, 20, 21 // CDA CAB
}}, }},
{"reversed indices", {}, {3, 2, 1, 0}, { {"reversed indices", 0, {}, {3, 2, 1, 0}, {
4, 3, 2, 4, 2, 0, // DCB DBA (both splits are fine) 4, 3, 2, 4, 2, 0, // DCB DBA (both splits are fine)
9, 7, 6, 9, 6, 5, // DCB DBA 9, 7, 6, 9, 6, 5, // DCB DBA
10, 15, 14, 10, 14, 11, // ADC ACB 10, 15, 14, 10, 14, 11, // ADC ACB
19, 18, 17, 19, 17, 16, // DCB DBA 19, 18, 17, 19, 17, 16, // DCB DBA
20, 23, 22, 20, 22, 21 // ADC ACB 20, 23, 22, 20, 22, 21 // ADC ACB
}}, }},
{"rotated positions", Matrix4::rotation(130.0_degf, Vector3{1.0f/Constants::sqrt3()}), {0, 1, 2, 3}, { {"rotated positions", 0, Matrix4::rotation(130.0_degf, Vector3{1.0f/Constants::sqrt3()}), {0, 1, 2, 3}, {
0, 2, 3, 0, 3, 4, // ABC ACD 0, 2, 3, 0, 3, 4, // ABC ACD
9, 5, 6, 9, 6, 7, // DAB DBC 9, 5, 6, 9, 6, 7, // DAB DBC
10, 11, 14, 10, 14, 15, // ABC ACD 10, 11, 14, 10, 14, 15, // ABC ACD
19, 16, 17, 19, 17, 18, // DAB DBC 19, 16, 17, 19, 17, 18, // DAB DBC
20, 21, 22, 20, 22, 23 // ABC ACD 20, 21, 22, 20, 22, 23 // ABC ACD
}}, }},
{"mirrored positions", Matrix4::scaling(Vector3::xScale(-1.0f)), {0, 1, 2, 3}, { {"mirrored positions", 0, Matrix4::scaling(Vector3::xScale(-1.0f)), {0, 1, 2, 3}, {
0, 2, 3, 0, 3, 4, // ABC ACD 0, 2, 3, 0, 3, 4, // ABC ACD
9, 5, 6, 9, 6, 7, // DAB DBC 9, 5, 6, 9, 6, 7, // DAB DBC
10, 11, 14, 10, 14, 15, // ABC ACD 10, 11, 14, 10, 14, 15, // ABC ACD
19, 16, 17, 19, 17, 18, // DAB DBC 19, 16, 17, 19, 17, 18, // DAB DBC
20, 21, 22, 20, 22, 23 // ABC ACD 20, 21, 22, 20, 22, 23 // ABC ACD
}} }},
{"additional offset", 100, {}, {0, 1, 2, 3}, {
100, 102, 103, 100, 103, 104, // ABC ACD
109, 105, 106, 109, 106, 107, // DAB DBC
110, 111, 114, 110, 114, 115, // ABC ACD
119, 116, 117, 119, 117, 118, // DAB DBC
120, 121, 122, 120, 122, 123 // ABC ACD
}},
}; };
const struct { const struct {
@ -366,6 +374,12 @@ void GenerateIndicesTest::generateTrivialIndices() {
Containers::arrayView<UnsignedInt>({ Containers::arrayView<UnsignedInt>({
0, 1, 2, 3, 4, 5, 6 0, 1, 2, 3, 4, 5, 6
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
/* Additional offset */
CORRADE_COMPARE_AS(MeshTools::generateTrivialIndices(7, 100),
Containers::arrayView<UnsignedInt>({
100, 101, 102, 103, 104, 105, 106
}), TestSuite::Compare::Container);
} }
void GenerateIndicesTest::generateLineStripIndices() { void GenerateIndicesTest::generateLineStripIndices() {
@ -398,6 +412,15 @@ void GenerateIndicesTest::generateLineStripIndices() {
3, 4, 3, 4,
4, 5 4, 5
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
/* Additional offset */
CORRADE_COMPARE_AS(MeshTools::generateLineStripIndices(5, 100),
Containers::arrayView<UnsignedInt>({
100, 101,
101, 102,
102, 103,
103, 104
}), TestSuite::Compare::Container);
} }
template<class T> void GenerateIndicesTest::generateLineStripIndicesIndexed() { template<class T> void GenerateIndicesTest::generateLineStripIndicesIndexed() {
@ -438,6 +461,16 @@ template<class T> void GenerateIndicesTest::generateLineStripIndicesIndexed() {
93, 44, 93, 44,
44, 85 44, 85
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
/* Additional offset */
CORRADE_COMPARE_AS(MeshTools::generateLineStripIndices(indices, 10000),
Containers::arrayView<UnsignedInt>({
10060, 10021,
10021, 10072,
10072, 10093,
10093, 10044,
10044, 10085
}), TestSuite::Compare::Container);
} }
template<class T> void GenerateIndicesTest::generateLineStripIndicesIndexed2D() { template<class T> void GenerateIndicesTest::generateLineStripIndicesIndexed2D() {
@ -459,6 +492,16 @@ template<class T> void GenerateIndicesTest::generateLineStripIndicesIndexed2D()
72, 93, 72, 93,
93, 44 93, 44
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
/* Additional offset */
CORRADE_COMPARE_AS(MeshTools::generateLineStripIndices(indices, 10000),
Containers::arrayView<UnsignedInt>({
10060, 10021,
10021, 10072,
10072, 10093,
10093, 10044,
10044, 10085
}), TestSuite::Compare::Container);
} }
void GenerateIndicesTest::generateLineStripIndicesWrongVertexCount() { void GenerateIndicesTest::generateLineStripIndicesWrongVertexCount() {
@ -541,6 +584,16 @@ void GenerateIndicesTest::generateLineLoopIndices() {
4, 5, 4, 5,
5, 0 5, 0
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
/* Additional offset */
CORRADE_COMPARE_AS(MeshTools::generateLineLoopIndices(5, 100),
Containers::arrayView<UnsignedInt>({
100, 101,
101, 102,
102, 103,
103, 104,
104, 100
}), TestSuite::Compare::Container);
} }
template<class T> void GenerateIndicesTest::generateLineLoopIndicesIndexed() { template<class T> void GenerateIndicesTest::generateLineLoopIndicesIndexed() {
@ -584,6 +637,17 @@ template<class T> void GenerateIndicesTest::generateLineLoopIndicesIndexed() {
44, 85, 44, 85,
85, 60 85, 60
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
/* Additional offset */
CORRADE_COMPARE_AS(MeshTools::generateLineLoopIndices(indices, 10000),
Containers::arrayView<UnsignedInt>({
10060, 10021,
10021, 10072,
10072, 10093,
10093, 10044,
10044, 10085,
10085, 10060
}), TestSuite::Compare::Container);
} }
template<class T> void GenerateIndicesTest::generateLineLoopIndicesIndexed2D() { template<class T> void GenerateIndicesTest::generateLineLoopIndicesIndexed2D() {
@ -606,6 +670,17 @@ template<class T> void GenerateIndicesTest::generateLineLoopIndicesIndexed2D() {
93, 44, 93, 44,
44, 60 44, 60
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
/* Additional offset */
CORRADE_COMPARE_AS(MeshTools::generateLineLoopIndices(indices, 10000),
Containers::arrayView<UnsignedInt>({
10060, 10021,
10021, 10072,
10072, 10093,
10093, 10044,
10044, 10085,
10085, 10060
}), TestSuite::Compare::Container);
} }
void GenerateIndicesTest::generateLineLoopIndicesWrongVertexCount() { void GenerateIndicesTest::generateLineLoopIndicesWrongVertexCount() {
@ -687,6 +762,16 @@ void GenerateIndicesTest::generateTriangleStripIndices() {
4, 5, 6, 4, 5, 6,
6, 5, 7 /* Reversed */ 6, 5, 7 /* Reversed */
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
/* Additional offset */
CORRADE_COMPARE_AS(MeshTools::generateTriangleStripIndices(7, 100),
Containers::arrayView<UnsignedInt>({
100, 101, 102,
102, 101, 103, /* Reversed */
102, 103, 104,
104, 103, 105, /* Reversed */
104, 105, 106
}), TestSuite::Compare::Container);
} }
template<class T> void GenerateIndicesTest::generateTriangleStripIndicesIndexed() { template<class T> void GenerateIndicesTest::generateTriangleStripIndicesIndexed() {
@ -729,6 +814,16 @@ template<class T> void GenerateIndicesTest::generateTriangleStripIndicesIndexed(
44, 85, 36, 44, 85, 36,
36, 85, 17 /* Reversed */ 36, 85, 17 /* Reversed */
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
/* Additional offset */
CORRADE_COMPARE_AS(MeshTools::generateTriangleStripIndices(indices.prefix(7), 10000),
Containers::arrayView<UnsignedInt>({
10060, 10021, 10072,
10072, 10021, 10093, /* Reversed */
10072, 10093, 10044,
10044, 10093, 10085, /* Reversed */
10044, 10085, 10036
}), TestSuite::Compare::Container);
} }
template<class T> void GenerateIndicesTest::generateTriangleStripIndicesIndexed2D() { template<class T> void GenerateIndicesTest::generateTriangleStripIndicesIndexed2D() {
@ -751,6 +846,17 @@ template<class T> void GenerateIndicesTest::generateTriangleStripIndicesIndexed2
44, 93, 85, /* Reversed */ 44, 93, 85, /* Reversed */
44, 85, 36 44, 85, 36
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
/* Additional offset */
CORRADE_COMPARE_AS(MeshTools::generateTriangleStripIndices(indices, 10000),
Containers::arrayView<UnsignedInt>({
10060, 10021, 10072,
10072, 10021, 10093, /* Reversed */
10072, 10093, 10044,
10044, 10093, 10085, /* Reversed */
10044, 10085, 10036,
10036, 10085, 10017 /* Reversed */
}), TestSuite::Compare::Container);
} }
void GenerateIndicesTest::generateTriangleStripIndicesWrongVertexCount() { void GenerateIndicesTest::generateTriangleStripIndicesWrongVertexCount() {
@ -832,6 +938,17 @@ void GenerateIndicesTest::generateTriangleFanIndices() {
0, 5, 6, 0, 5, 6,
0, 6, 7 0, 6, 7
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
/* Additional offset */
CORRADE_COMPARE_AS(MeshTools::generateTriangleFanIndices(8, 100),
Containers::arrayView<UnsignedInt>({
100, 101, 102,
100, 102, 103,
100, 103, 104,
100, 104, 105,
100, 105, 106,
100, 106, 107
}), TestSuite::Compare::Container);
} }
template<class T> void GenerateIndicesTest::generateTriangleFanIndicesIndexed() { template<class T> void GenerateIndicesTest::generateTriangleFanIndicesIndexed() {
@ -874,6 +991,16 @@ template<class T> void GenerateIndicesTest::generateTriangleFanIndicesIndexed()
60, 85, 36, 60, 85, 36,
60, 36, 17 60, 36, 17
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
/* Additional offset */
CORRADE_COMPARE_AS(MeshTools::generateTriangleFanIndices(indices.prefix(7), 10000),
Containers::arrayView<UnsignedInt>({
10060, 10021, 10072,
10060, 10072, 10093,
10060, 10093, 10044,
10060, 10044, 10085,
10060, 10085, 10036
}), TestSuite::Compare::Container);
} }
template<class T> void GenerateIndicesTest::generateTriangleFanIndicesIndexed2D() { template<class T> void GenerateIndicesTest::generateTriangleFanIndicesIndexed2D() {
@ -896,6 +1023,17 @@ template<class T> void GenerateIndicesTest::generateTriangleFanIndicesIndexed2D(
60, 44, 85, 60, 44, 85,
60, 85, 36 60, 85, 36
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
/* Additional offset */
CORRADE_COMPARE_AS(MeshTools::generateTriangleFanIndices(indices, 10000),
Containers::arrayView<UnsignedInt>({
10060, 10021, 10072,
10060, 10072, 10093,
10060, 10093, 10044,
10060, 10044, 10085,
10060, 10085, 10036,
10060, 10036, 10017
}), TestSuite::Compare::Container);
} }
void GenerateIndicesTest::generateTriangleFanIndicesWrongVertexCount() { void GenerateIndicesTest::generateTriangleFanIndicesWrongVertexCount() {
@ -1023,8 +1161,11 @@ template<class T> void GenerateIndicesTest::generateQuadIndices() {
for(std::size_t j = 0; j != 4; ++j) for(std::size_t j = 0; j != 4; ++j)
remappedIndices[i*4 + j] = QuadIndices[i*4 + data.remap[j]]; remappedIndices[i*4 + j] = QuadIndices[i*4 + data.remap[j]];
Containers::Array<UnsignedInt> triangleIndices = Containers::Array<UnsignedInt> triangleIndices;
MeshTools::generateQuadIndices(transformedPositions, remappedIndices); if(data.offset)
triangleIndices = MeshTools::generateQuadIndices(transformedPositions, remappedIndices, data.offset);
else
triangleIndices = MeshTools::generateQuadIndices(transformedPositions, remappedIndices);
CORRADE_COMPARE_AS(Containers::arrayView(triangleIndices), Containers::arrayView(data.expected), TestSuite::Compare::Container); CORRADE_COMPARE_AS(Containers::arrayView(triangleIndices), Containers::arrayView(data.expected), TestSuite::Compare::Container);
} }
@ -1040,8 +1181,8 @@ template<class T> void GenerateIndicesTest::generateQuadIndicesInto() {
indices[i] = QuadIndices[i]; indices[i] = QuadIndices[i];
T triangleIndices[Containers::arraySize(QuadIndices)*6/4]; T triangleIndices[Containers::arraySize(QuadIndices)*6/4];
MeshTools::generateQuadIndicesInto(QuadPositions, indices, triangleIndices);
MeshTools::generateQuadIndicesInto(QuadPositions, indices, triangleIndices);
CORRADE_COMPARE_AS(Containers::arrayView(triangleIndices), Containers::arrayView<T>({ CORRADE_COMPARE_AS(Containers::arrayView(triangleIndices), Containers::arrayView<T>({
0, 2, 3, 0, 3, 4, // ABC ACD 0, 2, 3, 0, 3, 4, // ABC ACD
9, 5, 6, 9, 6, 7, // DAB DBC 9, 5, 6, 9, 6, 7, // DAB DBC
@ -1049,6 +1190,16 @@ template<class T> void GenerateIndicesTest::generateQuadIndicesInto() {
19, 16, 17, 19, 17, 18, // DAB DBC 19, 16, 17, 19, 17, 18, // DAB DBC
20, 21, 22, 20, 22, 23 // ABC ACD 20, 21, 22, 20, 22, 23 // ABC ACD
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
/* With additional offset */
MeshTools::generateQuadIndicesInto(QuadPositions, indices, triangleIndices, 100);
CORRADE_COMPARE_AS(Containers::arrayView(triangleIndices), Containers::arrayView<T>({
100, 102, 103, 100, 103, 104, // ABC ACD
109, 105, 106, 109, 106, 107, // DAB DBC
110, 111, 114, 110, 114, 115, // ABC ACD
119, 116, 117, 119, 117, 118, // DAB DBC
120, 121, 122, 120, 122, 123 // ABC ACD
}), TestSuite::Compare::Container);
} }
void GenerateIndicesTest::generateQuadIndicesWrongIndexCount() { void GenerateIndicesTest::generateQuadIndicesWrongIndexCount() {

Loading…
Cancel
Save