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, {});
}
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)
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};
generateTrivialIndicesInto(output);
generateTrivialIndicesInto(output, offset);
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,
"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
*/
for(std::size_t i = 0; i != iMax; ++i) {
output[i*2 + 0] = i;
output[i*2 + 1] = i + 1;
output[i*2 + 0] = offset + i;
output[i*2 + 1] = offset + i + 1;
}
}
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,
"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
indirection on top */
for(std::size_t i = 0; i != iMax; ++i) {
output[i*2 + 0] = indices[i];
output[i*2 + 1] = indices[i + 1];
output[i*2 + 0] = offset + indices[i];
output[i*2 + 1] = offset + indices[i + 1];
}
}
}
void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) {
generateLineStripIndicesIntoImplementation(indices, output);
void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateLineStripIndicesIntoImplementation(indices, output, offset);
}
void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) {
generateLineStripIndicesIntoImplementation(indices, output);
void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateLineStripIndicesIntoImplementation(indices, output, offset);
}
void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) {
generateLineStripIndicesIntoImplementation(indices, output);
void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
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", );
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)
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)
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], );
}
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)};
generateLineStripIndicesInto(vertexCount, output);
generateLineStripIndicesInto(vertexCount, output, offset);
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)};
generateLineStripIndicesInto(indices, output);
generateLineStripIndicesInto(indices, output, offset);
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)};
generateLineStripIndicesInto(indices, output);
generateLineStripIndicesInto(indices, output, offset);
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)};
generateLineStripIndicesInto(indices, output);
generateLineStripIndicesInto(indices, output, offset);
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)};
generateLineStripIndicesInto(indices, output);
generateLineStripIndicesInto(indices, output, offset);
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,
"MeshTools::generateLineLoopIndicesInto(): expected either zero or at least two vertices, got" << vertexCount, );
CORRADE_ASSERT(output.size() == 2*vertexCount,
@ -206,18 +206,18 @@ void generateLineLoopIndicesInto(const UnsignedInt vertexCount, const Containers
0 ----------- 3 0 7 ----------- 6 5
*/
for(std::size_t i = 0, iMax = Math::max(vertexCount, 1u) - 1; i != iMax; ++i) {
output[i*2 + 0] = i;
output[i*2 + 1] = i + 1;
output[i*2 + 0] = offset + i;
output[i*2 + 1] = offset + i + 1;
}
if(vertexCount >= 2) {
output[2*vertexCount - 2] = vertexCount - 1;
output[2*vertexCount - 1] = 0;
output[2*vertexCount - 2] = offset + vertexCount - 1;
output[2*vertexCount - 1] = offset + 0;
}
}
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,
"MeshTools::generateLineLoopIndicesInto(): expected either zero or at least two indices, got" << 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
indirection on top */
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 + 1] = indices[i + 1];
output[i*2 + 0] = offset + indices[i];
output[i*2 + 1] = offset + indices[i + 1];
}
if(indices.size() >= 2) {
output[2*indices.size() - 2] = indices[indices.size() - 1];
output[2*indices.size() - 1] = indices[0];
output[2*indices.size() - 2] = offset + indices[indices.size() - 1];
output[2*indices.size() - 1] = offset + indices[0];
}
}
}
void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) {
generateLineLoopIndicesIntoImplementation(indices, output);
void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateLineLoopIndicesIntoImplementation(indices, output, offset);
}
void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) {
generateLineLoopIndicesIntoImplementation(indices, output);
void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateLineLoopIndicesIntoImplementation(indices, output, offset);
}
void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) {
generateLineLoopIndicesIntoImplementation(indices, output);
void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
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", );
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)
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)
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], );
}
Containers::Array<UnsignedInt> generateLineLoopIndices(const UnsignedInt vertexCount) {
Containers::Array<UnsignedInt> generateLineLoopIndices(const UnsignedInt vertexCount, const UnsignedInt offset) {
Containers::Array<UnsignedInt> output{NoInit, 2*vertexCount};
generateLineLoopIndicesInto(vertexCount, output);
generateLineLoopIndicesInto(vertexCount, output, offset);
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()};
generateLineLoopIndicesInto(indices, output);
generateLineLoopIndicesInto(indices, output, offset);
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()};
generateLineLoopIndicesInto(indices, output);
generateLineLoopIndicesInto(indices, output, offset);
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()};
generateLineLoopIndicesInto(indices, output);
generateLineLoopIndicesInto(indices, output, offset);
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]};
generateLineLoopIndicesInto(indices, output);
generateLineLoopIndicesInto(indices, output, offset);
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,
"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
*/
for(std::size_t i = 0; i != iMax; ++i) {
output[i*3 + 0] = i % 2 ? i + 1 : i;
output[i*3 + 1] = i % 2 ? i : i + 1;
output[i*3 + 2] = i + 2;
output[i*3 + 0] = offset + (i % 2 ? i + 1 : i);
output[i*3 + 1] = offset + (i % 2 ? i : i + 1);
output[i*3 + 2] = offset + i + 2;
}
}
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,
"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
array indirection on top */
for(std::size_t i = 0; i != iMax; ++i) {
output[i*3 + 0] = indices[i % 2 ? i + 1 : i];
output[i*3 + 1] = indices[i % 2 ? i : i + 1];
output[i*3 + 2] = indices[i + 2];
output[i*3 + 0] = offset + indices[i % 2 ? i + 1 : i];
output[i*3 + 1] = offset + indices[i % 2 ? i : i + 1];
output[i*3 + 2] = offset + indices[i + 2];
}
}
}
void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) {
generateTriangleStripIndicesIntoImplementation(indices, output);
void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateTriangleStripIndicesIntoImplementation(indices, output, offset);
}
void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) {
generateTriangleStripIndicesIntoImplementation(indices, output);
void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateTriangleStripIndicesIntoImplementation(indices, output, offset);
}
void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) {
generateTriangleStripIndicesIntoImplementation(indices, output);
void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
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", );
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)
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)
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], );
}
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)};
generateTriangleStripIndicesInto(vertexCount, output);
generateTriangleStripIndicesInto(vertexCount, output, offset);
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)};
generateTriangleStripIndicesInto(indices, output);
generateTriangleStripIndicesInto(indices, output, offset);
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)};
generateTriangleStripIndicesInto(indices, output);
generateTriangleStripIndicesInto(indices, output, offset);
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)};
generateTriangleStripIndicesInto(indices, output);
generateTriangleStripIndicesInto(indices, output, offset);
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)};
generateTriangleStripIndicesInto(indices, output);
generateTriangleStripIndicesInto(indices, output, offset);
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,
"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
*/
for(std::size_t i = 0; i != iMax; ++i) {
output[i*3 + 0] = 0;
output[i*3 + 1] = i + 1;
output[i*3 + 2] = i + 2;
output[i*3 + 0] = offset + 0;
output[i*3 + 1] = offset + i + 1;
output[i*3 + 2] = offset + i + 2;
}
}
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,
"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
array indirection on top */
for(std::size_t i = 0; i != iMax; ++i) {
output[i*3 + 0] = indices[0];
output[i*3 + 1] = indices[i + 1];
output[i*3 + 2] = indices[i + 2];
output[i*3 + 0] = offset + indices[0];
output[i*3 + 1] = offset + indices[i + 1];
output[i*3 + 2] = offset + indices[i + 2];
}
}
}
void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) {
generateTriangleFanIndicesIntoImplementation(indices, output);
void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateTriangleFanIndicesIntoImplementation(indices, output, offset);
}
void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) {
generateTriangleFanIndicesIntoImplementation(indices, output);
void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
generateTriangleFanIndicesIntoImplementation(indices, output, offset);
}
void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) {
generateTriangleFanIndicesIntoImplementation(indices, output);
void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output, const UnsignedInt offset) {
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", );
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)
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)
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], );
}
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)};
generateTriangleFanIndicesInto(vertexCount, output);
generateTriangleFanIndicesInto(vertexCount, output, offset);
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)};
generateTriangleFanIndicesInto(indices, output);
generateTriangleFanIndicesInto(indices, output, offset);
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)};
generateTriangleFanIndicesInto(indices, output);
generateTriangleFanIndicesInto(indices, output, offset);
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)};
generateTriangleFanIndicesInto(indices, output);
generateTriangleFanIndicesInto(indices, output, offset);
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)};
generateTriangleFanIndicesInto(indices, output);
generateTriangleFanIndicesInto(indices, output, offset);
return output;
}
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,
"MeshTools::generateQuadIndicesInto(): quad index count" << quads.size() << "not divisible by 4", );
CORRADE_ASSERT(quads.size()*6/4 == output.size(),
@ -528,20 +528,20 @@ template<class T> inline void generateQuadIndicesIntoImplementation(const Contai
/* Assign the two triangles */
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 */
Containers::Array<UnsignedInt> out{NoInit, quads.size()*6/4};
generateQuadIndicesIntoImplementation(positions, quads, Containers::stridedArrayView(out));
generateQuadIndicesIntoImplementation(positions, quads, Containers::stridedArrayView(out), offset);
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 */
Containers::Array<UnsignedInt> out{ValueInit, quads.size()*6/4};
generateQuadIndicesIntoImplementation(positions, quads,
@ -554,12 +554,12 @@ Containers::Array<UnsignedInt> generateQuadIndices(const Containers::StridedArra
#ifdef CORRADE_BIG_ENDIAN
+ 1
#endif
, out.size(), 4}
);
, out.size(), 4},
offset);
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 */
Containers::Array<UnsignedInt> out{ValueInit, quads.size()*6/4};
generateQuadIndicesIntoImplementation(positions, quads,
@ -572,21 +572,21 @@ Containers::Array<UnsignedInt> generateQuadIndices(const Containers::StridedArra
#ifdef CORRADE_BIG_ENDIAN
+ 3
#endif
, out.size(), 4}
);
, out.size(), 4},
offset);
return out;
}
void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedInt>& quads, const Containers::StridedArrayView1D<UnsignedInt>& output) {
return generateQuadIndicesIntoImplementation(positions, quads, 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, offset);
}
void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedShort>& quads, const Containers::StridedArrayView1D<UnsignedShort>& output) {
return generateQuadIndicesIntoImplementation(positions, quads, 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, offset);
}
void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedByte>& quads, const Containers::StridedArrayView1D<UnsignedByte>& output) {
return generateQuadIndicesIntoImplementation(positions, quads, 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, offset);
}
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
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(),
@ref generateLineLoopIndices(), @ref generateTriangleStripIndices(),
@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
@ -69,44 +70,44 @@ MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTrivialIndices(Un
A variant of @ref generateTrivialIndices() that fills existing memory
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
@m_since{2020,06}
Generates a @cpp 0, 1, 1, 2, 3, 4, ... @ce sequence. Can be used to convert a
@ref MeshPrimitive::LineStrip mesh to @ref MeshPrimitive::Lines. The
@p vertexCount is expected to be either @cpp 0 @ce or at least @cpp 2 @ce.
Primitive restart is not supported. If the mesh is already indexed, use
@ref generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>&)
Generates a @cpp 0, 1, 1, 2, 3, 4, ... @ce sequence, optionally with @p offset
added to each index. Can be used to convert a @ref MeshPrimitive::LineStrip
mesh to @ref MeshPrimitive::Lines. The @p vertexCount is expected to be either
@cpp 0 @ce or at least @cpp 2 @ce. Primitive restart is not supported. If the
mesh is already indexed, use @ref generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>&, UnsignedInt)
and overloads instead.
@see @ref generateLineStripIndicesInto(), @ref generateLineLoopIndices(),
@ref generateTriangleStripIndices(), @ref generateTriangleFanIndices(),
@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
@m_since_latest
Like @ref generateLineStripIndices(UnsignedInt), but merges @p indices into the
generated line strip index buffer.
Like @ref generateLineStripIndices(UnsignedInt, UnsignedInt), but merges
@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
* @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
* @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
@ -114,10 +115,10 @@ MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineStripIndices(
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
@ref generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>&)
@ref generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>&, UnsignedInt)
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
@ -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
@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
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.
*/
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
@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.
*/
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
* @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
* @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
@ -159,25 +160,26 @@ MAGNUM_MESHTOOLS_EXPORT void generateLineStripIndicesInto(const Containers::Stri
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
@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.
*/
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
@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
@p vertexCount is expected to be either @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>&)
Generates a @cpp 0, 1, 1, 2, 3, ..., 0 @ce sequence, optionally with @p offset
added to each index. Can be used to convert a @ref MeshPrimitive::LineLoop mesh
to @ref MeshPrimitive::Lines. The @p vertexCount is expected to be either
@cpp 0 @ce or at least @cpp 2 @ce. Primitive restart is not supported. If the
mesh is already indexed, use @ref generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedInt>&)
and overloads instead.
@see @ref generateLineLoopIndicesInto(), @ref generateLineStripIndices(),
@ref generateTriangleStripIndices(), @ref generateTriangleFanIndices(),
@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
@ -186,19 +188,19 @@ MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateLineLoopIndices(U
Like @ref generateLineLoopIndices(UnsignedInt), but merges @p indices into the
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
* @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
* @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
@ -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>&)
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
@ -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>&)
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
@ -231,19 +233,19 @@ MAGNUM_MESHTOOLS_EXPORT void generateLineLoopIndicesInto(UnsignedInt vertexCount
Like @ref generateLineLoopIndicesInto(UnsignedInt, const Containers::StridedArrayView1D<UnsignedInt>&),
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
* @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
* @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
@ -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>&)
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
@ -270,7 +272,7 @@ and overloads instead.
@ref generateLineLoopIndices(), @ref generateTriangleFanIndices(),
@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
@ -279,19 +281,19 @@ MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleStripIndi
Like @ref generateTriangleStripIndices(UnsignedInt), but merges @p indices into
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
* @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
* @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
@ -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>&)
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
@ -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
@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
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.
*/
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
@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.
*/
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
* @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
* @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
@ -344,47 +346,48 @@ MAGNUM_MESHTOOLS_EXPORT void generateTriangleStripIndicesInto(const Containers::
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
@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.
*/
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
@m_since{2020,06}
Generates a @cpp 0, 1, 2, 0, 2, 3, 0, 3, 4, ... @ce sequence. Can be used to
convert a @ref MeshPrimitive::TriangleFan mesh to
@ref MeshPrimitive::Triangles. The @p vertexCount is expected to be either
@cpp 0 @ce or at least @cpp 3 @ce. Primitive restart is not supported. If the
mesh is already indexed, use @ref generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedInt>&)
Generates a @cpp 0, 1, 2, 0, 2, 3, 0, 3, 4, ... @ce sequence, optionally with
@p offset added to each index. Can be used to convert a
@ref MeshPrimitive::TriangleFan mesh to @ref MeshPrimitive::Triangles. The
@p vertexCount is expected to be either @cpp 0 @ce or at least @cpp 3 @ce.
Primitive restart is not supported. If the mesh is already indexed, use
@ref generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedInt>&, UnsignedInt)
and overloads instead.
@see @ref generateTriangleFanIndicesInto(), @ref generateLineStripIndices(),
@ref generateLineLoopIndices(), @ref generateTriangleStripIndices(),
@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
@m_since_latest
Like @ref generateTriangleFanIndices(UnsignedInt), but merges @p indices into
the generated triangle fan index buffer.
Like @ref generateTriangleFanIndices(UnsignedInt, UnsignedInt), but merges
@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
* @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
* @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
@ -392,10 +395,10 @@ MAGNUM_MESHTOOLS_EXPORT Containers::Array<UnsignedInt> generateTriangleFanIndice
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
@ref generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedInt>&)
@ref generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedInt>&, UnsignedInt)
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
@ -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
@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
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.
*/
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
@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.
*/
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
* @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
* @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
@ -437,10 +440,10 @@ MAGNUM_MESHTOOLS_EXPORT void generateTriangleFanIndicesInto(const Containers::St
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
@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.
*/
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
@ -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
shorter
Size of @p quads is expected to be divisible by @cpp 4 @ce and all indices
being in bounds of the @p positions view.
Optionally adds @p offset to each index. Size of @p quads is expected to be
divisible by @cpp 4 @ce and all indices being in bounds of the @p positions
view.
@see @ref generateQuadIndicesInto(), \n
@ref Math::cross(const Vector3<T>&, const Vector3<T>&), \n
@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
* @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
* @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
@ -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
@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
* @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
* @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

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

@ -100,59 +100,67 @@ using namespace Math::Literals;
const struct {
const char* name;
UnsignedInt offset;
Matrix4 transformation;
UnsignedInt remap[4];
UnsignedInt expected[6*5];
} QuadData[] {
{"", {}, {0, 1, 2, 3}, {
{"", 0, {}, {0, 1, 2, 3}, {
0, 2, 3, 0, 3, 4, // ABC ACD
9, 5, 6, 9, 6, 7, // DAB DBC
10, 11, 14, 10, 14, 15, // ABC ACD
19, 16, 17, 19, 17, 18, // DAB DBC
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)
6, 7, 9, 6, 9, 5, // BCD BDA
10, 11, 14, 10, 14, 15, // ABC ACD
17, 18, 19, 17, 19, 16, // BCD BDA
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
6, 7, 9, 6, 9, 5, // BCD BDA
14, 15, 10, 14, 10, 11, // CDA CAB
17, 18, 19, 17, 19, 16, // BCD BDA
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)
9, 5, 6, 9, 6, 7, // DAB DBC
14, 15, 10, 14, 10, 11, // CDA CAB
19, 16, 17, 19, 17, 18, // DAB DBC
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)
9, 7, 6, 9, 6, 5, // DCB DBA
10, 15, 14, 10, 14, 11, // ADC ACB
19, 18, 17, 19, 17, 16, // DCB DBA
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
9, 5, 6, 9, 6, 7, // DAB DBC
10, 11, 14, 10, 14, 15, // ABC ACD
19, 16, 17, 19, 17, 18, // DAB DBC
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
9, 5, 6, 9, 6, 7, // DAB DBC
10, 11, 14, 10, 14, 15, // ABC ACD
19, 16, 17, 19, 17, 18, // DAB DBC
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 {
@ -366,6 +374,12 @@ void GenerateIndicesTest::generateTrivialIndices() {
Containers::arrayView<UnsignedInt>({
0, 1, 2, 3, 4, 5, 6
}), 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() {
@ -398,6 +412,15 @@ void GenerateIndicesTest::generateLineStripIndices() {
3, 4,
4, 5
}), 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() {
@ -438,6 +461,16 @@ template<class T> void GenerateIndicesTest::generateLineStripIndicesIndexed() {
93, 44,
44, 85
}), 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() {
@ -459,6 +492,16 @@ template<class T> void GenerateIndicesTest::generateLineStripIndicesIndexed2D()
72, 93,
93, 44
}), 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() {
@ -541,6 +584,16 @@ void GenerateIndicesTest::generateLineLoopIndices() {
4, 5,
5, 0
}), 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() {
@ -584,6 +637,17 @@ template<class T> void GenerateIndicesTest::generateLineLoopIndicesIndexed() {
44, 85,
85, 60
}), 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() {
@ -606,6 +670,17 @@ template<class T> void GenerateIndicesTest::generateLineLoopIndicesIndexed2D() {
93, 44,
44, 60
}), 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() {
@ -687,6 +762,16 @@ void GenerateIndicesTest::generateTriangleStripIndices() {
4, 5, 6,
6, 5, 7 /* Reversed */
}), 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() {
@ -729,6 +814,16 @@ template<class T> void GenerateIndicesTest::generateTriangleStripIndicesIndexed(
44, 85, 36,
36, 85, 17 /* Reversed */
}), 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() {
@ -751,6 +846,17 @@ template<class T> void GenerateIndicesTest::generateTriangleStripIndicesIndexed2
44, 93, 85, /* Reversed */
44, 85, 36
}), 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() {
@ -832,6 +938,17 @@ void GenerateIndicesTest::generateTriangleFanIndices() {
0, 5, 6,
0, 6, 7
}), 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() {
@ -874,6 +991,16 @@ template<class T> void GenerateIndicesTest::generateTriangleFanIndicesIndexed()
60, 85, 36,
60, 36, 17
}), 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() {
@ -896,6 +1023,17 @@ template<class T> void GenerateIndicesTest::generateTriangleFanIndicesIndexed2D(
60, 44, 85,
60, 85, 36
}), 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() {
@ -1023,8 +1161,11 @@ template<class T> void GenerateIndicesTest::generateQuadIndices() {
for(std::size_t j = 0; j != 4; ++j)
remappedIndices[i*4 + j] = QuadIndices[i*4 + data.remap[j]];
Containers::Array<UnsignedInt> triangleIndices =
MeshTools::generateQuadIndices(transformedPositions, remappedIndices);
Containers::Array<UnsignedInt> triangleIndices;
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);
}
@ -1040,8 +1181,8 @@ template<class T> void GenerateIndicesTest::generateQuadIndicesInto() {
indices[i] = QuadIndices[i];
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>({
0, 2, 3, 0, 3, 4, // ABC ACD
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
20, 21, 22, 20, 22, 23 // ABC ACD
}), 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() {

Loading…
Cancel
Save