Magnum::MeshTools namespace

Mesh tools.

Tools for transforming, filtering, optimizing and merging meshes.

This library is built if MAGNUM_WITH_MESHTOOLS is enabled when building Magnum. To use this library with CMake, request the MeshTools component of the Magnum package and link to the Magnum::MeshTools target:

find_package(Magnum REQUIRED MeshTools)

# ...
target_link_libraries(your-app PRIVATE Magnum::MeshTools)

Note that functionality depending on GL APIs is available only if Magnum is built with both MAGNUM_WITH_GL and MAGNUM_TARGET_GL enabled (which is done by default).

See Downloading and building, Usage with CMake and Mesh processing tools for more information.

Enums

enum class CompileFlag: UnsignedByte { GenerateFlatNormals = 1 << 0, GenerateSmoothNormals = 1 << 1, NoWarnOnCustomAttributes = 1 << 2 new in 2020.06 } new in 2019.10
Mesh compilation flag.
enum class InterleaveFlag: UnsignedInt { PreserveInterleavedAttributes = 1 << 0, PreserveStridedIndices = 1 << 1 } new in Git master
Interleaving behavior flag.

Typedefs

using CompileFlags = Containers::EnumSet<CompileFlag> new in 2019.10
Mesh compilation flags.
using InterleaveFlags = Containers::EnumSet<InterleaveFlag> new in Git master
Interleaving behavior flags.

Functions

auto boundingRange(const Containers::StridedArrayView1D<const Vector3>& positions) -> Range3D new in Git master
Calculate a bounding range.
auto boundingSphereBouncingBubble(const Containers::StridedArrayView1D<const Vector3>& positions) -> Containers::Pair<Vector3, Float> new in Git master
Calculate an approximate bounding sphere using the Bouncing Bubble algorithm.
auto combineIndexedAttributes(const Containers::Iterable<const Trade::MeshData>& meshes) -> Trade::MeshData new in 2020.06
Combine differently indexed attributes into a single mesh.
auto combineFaceAttributes(const Trade::MeshData& mesh, const Trade::MeshData& faceAttributes) -> Trade::MeshData new in 2020.06
Combine per-face attributes into an existing mesh.
auto combineFaceAttributes(const Trade::MeshData& mesh, Containers::ArrayView<const Trade::MeshAttributeData> faceAttributes) -> Trade::MeshData new in 2020.06
Combine per-face attributes into an existing mesh.
auto combineFaceAttributes(const Trade::MeshData& mesh, std::initializer_list<Trade::MeshAttributeData> faceAttributes) -> Trade::MeshData new in 2020.06
auto combineIndexArrays(const std::vector<std::reference_wrapper<std::vector<UnsignedInt>>>& arrays) -> std::vector<UnsignedInt> deprecated in 2020.06
Combine index arrays.
auto combineIndexArrays(std::initializer_list<std::reference_wrapper<std::vector<UnsignedInt>>> arrays) -> std::vector<UnsignedInt> deprecated in 2020.06
auto combineIndexArrays(const std::vector<UnsignedInt>& interleavedArrays, UnsignedInt stride) -> std::pair<std::vector<UnsignedInt>, std::vector<UnsignedInt>> deprecated in 2020.06
Combine interleaved index arrays.
template<class ... T>
auto combineIndexedArrays(const std::pair<const std::vector<UnsignedInt>&, std::vector<T>&>&... indexedArrays) -> std::vector<UnsignedInt> deprecated in 2020.06
Combine indexed arrays.
auto compile(const Trade::MeshData& mesh, CompileFlags flags) -> GL::Mesh new in 2020.06
Compile OpenGL mesh data.
auto compile(const Trade::MeshData& mesh) -> GL::Mesh new in 2020.06
auto compile(const Trade::MeshData& mesh, GL::Buffer& indices, GL::Buffer& vertices) -> GL::Mesh new in 2020.06
Compile mesh data using external buffers.
auto compile(const Trade::MeshData& mesh, GL::Buffer& indices, GL::Buffer&& vertices) -> GL::Mesh new in 2020.06
auto compile(const Trade::MeshData& mesh, GL::Buffer&& indices, GL::Buffer& vertices) -> GL::Mesh new in 2020.06
auto compile(const Trade::MeshData& mesh, GL::Buffer&& indices, GL::Buffer&& vertices) -> GL::Mesh new in 2020.06
auto compile(const Trade::MeshData2D& meshData) -> GL::Mesh deprecated in 2020.06
Compile 2D mesh data.
auto compile(const Trade::MeshData3D& meshData, CompileFlags flags = {}) -> GL::Mesh deprecated in 2020.06
Compile 3D mesh data.
auto compiledPerVertexJointCount(const Trade::MeshData& mesh) -> Containers::Pair<UnsignedInt, UnsignedInt> new in Git master
Compiled per-vertex joint count for given mesh data.
auto compileLines(const Trade::MeshData& mesh) -> GL::Mesh new in Git master
Compile a line mesh for use with Shaders::LineGL.
auto compressIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0) -> Containers::Pair<Containers::Array<char>, MeshIndexType> new in 2020.06
Compress an index array.
auto compressIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0) -> Containers::Pair<Containers::Array<char>, MeshIndexType> new in 2020.06
auto compressIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0) -> Containers::Pair<Containers::Array<char>, MeshIndexType> new in 2020.06
auto compressIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, Long offset) -> Containers::Pair<Containers::Array<char>, MeshIndexType> new in 2020.06
auto compressIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, Long offset) -> Containers::Pair<Containers::Array<char>, MeshIndexType> new in 2020.06
auto compressIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, Long offset) -> Containers::Pair<Containers::Array<char>, MeshIndexType> new in 2020.06
auto compressIndices(const Containers::StridedArrayView2D<const char>& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0) -> Containers::Pair<Containers::Array<char>, MeshIndexType> new in 2020.06
Compress a type-erased index array.
auto compressIndices(const Containers::StridedArrayView2D<const char>& indices, Long offset) -> Containers::Pair<Containers::Array<char>, MeshIndexType> new in 2020.06
auto compressIndices(const Trade::MeshData& mesh, MeshIndexType atLeast = MeshIndexType::UnsignedShort) -> Trade::MeshData new in 2020.06
Compress mesh data indices.
auto compressIndices(Trade::MeshData&& mesh, MeshIndexType atLeast = MeshIndexType::UnsignedShort) -> Trade::MeshData new in 2020.06
Compress mesh data indices.
auto compressIndices(const std::vector<UnsignedInt>& indices) -> std::tuple<Containers::Array<char>, MeshIndexType, UnsignedInt, UnsignedInt> deprecated in 2020.06
Compress vertex indices.
template<class T>
auto compressIndicesAs(const std::vector<UnsignedInt>& indices) -> Containers::Array<T> deprecated in 2020.06
Compress vertex indices as given type.
auto concatenate(const Containers::Iterable<const Trade::MeshData>& meshes, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) -> Trade::MeshData new in 2020.06
Concatenate meshes together.
template<template<class> class Allocator = Containers::ArrayAllocator>
void concatenateInto(Trade::MeshData& destination, const Containers::Iterable<const Trade::MeshData>& meshes, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) new in 2020.06
Concatenate a list of meshes into a pre-existing destination, enlarging it if necessary.
auto copy(const Trade::MeshData& mesh) -> Trade::MeshData new in Git master
Make an owned copy of the mesh.
auto copy(Trade::MeshData&& mesh) -> Trade::MeshData new in Git master
Make a mesh with owned data.
auto reference(const Trade::MeshData& mesh) -> Trade::MeshData new in 2020.06
Create an immutable reference on a Trade::MeshData.
auto mutableReference(Trade::MeshData& mesh) -> Trade::MeshData new in 2020.06
Create a mutable reference on a Trade::MeshData.
template<class IndexType, class T>
auto duplicate(const Containers::StridedArrayView1D<const IndexType>& indices, const Containers::StridedArrayView1D<const T>& data) -> Containers::Array<T> new in 2019.10
Duplicate data using given index array.
template<class T>
auto duplicate(const std::vector<UnsignedInt>& indices, const std::vector<T>& data) -> std::vector<T> deprecated in 2020.06
Duplicate data using given index array.
template<class IndexType, class T>
void duplicateInto(const Containers::StridedArrayView1D<const IndexType>& indices, const Containers::StridedArrayView1D<const T>& data, const Containers::StridedArrayView1D<T>& out) new in 2019.10
Duplicate data using an index array into given output array.
void duplicateInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView2D<const char>& data, const Containers::StridedArrayView2D<char>& out) new in 2020.06
Duplicate type-erased data using an index array into given output array.
void duplicateInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView2D<const char>& data, const Containers::StridedArrayView2D<char>& out) new in 2020.06
void duplicateInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView2D<const char>& data, const Containers::StridedArrayView2D<char>& out) new in 2020.06
void duplicateInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView2D<const char>& data, const Containers::StridedArrayView2D<char>& out) new in 2020.06
Duplicate type-erased data using a type-erased index array into given output array.
auto duplicate(const Trade::MeshData& mesh, Containers::ArrayView<const Trade::MeshAttributeData> extra = {}) -> Trade::MeshData new in 2020.06
Duplicate indexed mesh data.
auto duplicate(const Trade::MeshData& mesh, std::initializer_list<Trade::MeshAttributeData> extra) -> Trade::MeshData new in 2020.06
auto filterAttributes(const Trade::MeshData& mesh, Containers::BitArrayView attributesToKeep) -> Trade::MeshData new in Git master
Filter a mesh to contain only the selected subset of attributes.
auto filterAttributes(Trade::MeshData&& mesh, Containers::BitArrayView attributesToKeep) -> Trade::MeshData new in Git master
Filter a mesh to contain only the selected subset of attributes.
auto filterOnlyAttributes(const Trade::MeshData& mesh, Containers::ArrayView<const Trade::MeshAttribute> attributes) -> Trade::MeshData new in Git master
Filter a mesh to contain only the selected subset of named attributes.
auto filterOnlyAttributes(const Trade::MeshData& mesh, std::initializer_list<Trade::MeshAttribute> attributes) -> Trade::MeshData new in Git master
auto filterOnlyAttributes(Trade::MeshData&& mesh, Containers::ArrayView<const Trade::MeshAttribute> attributes) -> Trade::MeshData new in Git master
Filter a mesh to contain only the selected subset of named attributes.
auto filterOnlyAttributes(Trade::MeshData&& mesh, std::initializer_list<Trade::MeshAttribute> attributes) -> Trade::MeshData new in Git master
auto filterExceptAttributes(const Trade::MeshData& mesh, Containers::ArrayView<const Trade::MeshAttribute> attributes) -> Trade::MeshData new in Git master
Filter a mesh to contain everything except the selected subset of named attributes.
auto filterExceptAttributes(const Trade::MeshData& mesh, std::initializer_list<Trade::MeshAttribute> attributes) -> Trade::MeshData new in Git master
auto filterExceptAttributes(Trade::MeshData&& mesh, Containers::ArrayView<const Trade::MeshAttribute> attributes) -> Trade::MeshData new in Git master
Filter a mesh to contain everything except the selected subset of named attributes.
auto filterExceptAttributes(Trade::MeshData&& mesh, std::initializer_list<Trade::MeshAttribute> attributes) -> Trade::MeshData new in Git master
auto filterOnlyAttributes(const Trade::MeshData& mesh, Containers::ArrayView<const UnsignedInt> attributes) -> Trade::MeshData deprecated in Git master
Filter a mesh to contain only the selected subset of attributes.
auto filterOnlyAttributes(const Trade::MeshData& mesh, std::initializer_list<UnsignedInt> attributes) -> Trade::MeshData deprecated in Git master
Filter a mesh to contain only the selected subset of attributes.
auto filterExceptAttributes(const Trade::MeshData& mesh, Containers::ArrayView<const UnsignedInt> attributes) -> Trade::MeshData deprecated in Git master
Filter a mesh to contain everything except the selected subset of attributes.
auto filterExceptAttributes(const Trade::MeshData& mesh, std::initializer_list<UnsignedInt> attributes) -> Trade::MeshData deprecated in Git master
Filter a mesh to contain everything except the selected subset of attributes.
void flipNormalsInPlace(const Containers::StridedArrayView1D<UnsignedInt>& indices, const Containers::StridedArrayView1D<Vector3>& normals) new in 2020.06
Flip mesh normals and face winding in-place.
void flipNormalsInPlace(const Containers::StridedArrayView1D<UnsignedShort>& indices, const Containers::StridedArrayView1D<Vector3>& normals) new in 2020.06
void flipNormalsInPlace(const Containers::StridedArrayView1D<UnsignedByte>& indices, const Containers::StridedArrayView1D<Vector3>& normals) new in 2020.06
void flipNormalsInPlace(const Containers::StridedArrayView2D<char>& indices, const Containers::StridedArrayView1D<Vector3>& normals) new in 2020.06
Flip mesh normals and face winding in-place on a type-erased index array.
void flipNormals(std::vector<UnsignedInt>& indices, std::vector<Vector3>& normals) deprecated in 2020.06
Flip mesh normals and face winding in-place.
void flipFaceWindingInPlace(const Containers::StridedArrayView1D<UnsignedInt>& indices) new in 2020.06
Flip face winding in-place.
void flipFaceWindingInPlace(const Containers::StridedArrayView1D<UnsignedShort>& indices) new in 2020.06
void flipFaceWindingInPlace(const Containers::StridedArrayView1D<UnsignedByte>& indices) new in 2020.06
void flipFaceWindingInPlace(const Containers::StridedArrayView2D<char>& indices) new in 2020.06
Flip face winding in-place on a type-erased index array.
void flipFaceWinding(std::vector<UnsignedInt>& indices) deprecated in 2020.06
Flip face winding in-place.
void flipNormalsInPlace(const Containers::StridedArrayView1D<Vector3>& normals)
Flip mesh normals in-place.
void flipNormals(std::vector<Vector3>& normals) deprecated in 2020.06
Flip mesh normals in-place.
auto fullScreenTriangle(GL::Version version) -> GL::Mesh
Full screen triangle mesh.
auto fullScreenTriangle() -> GL::Mesh
auto primitiveCount(MeshPrimitive primitive, UnsignedInt elementCount) -> UnsignedInt new in 2020.06
Actual primitive count for given primitive type and element count.
auto generateTrivialIndices(UnsignedInt vertexCount) -> Containers::Array<UnsignedInt> new in Git master
Create a trivial index buffer.
void generateTrivialIndicesInto(const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
Create a trivial index buffer into an existing array.
auto generateLineStripIndices(UnsignedInt vertexCount) -> Containers::Array<UnsignedInt> new in 2020.06
Create index buffer for a line strip primitive.
auto generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices) -> Containers::Array<UnsignedInt> new in Git master
Create index buffer for an indexed line strip primitive.
auto generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices) -> Containers::Array<UnsignedInt> new in Git master
auto generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices) -> Containers::Array<UnsignedInt> new in Git master
auto generateLineStripIndices(const Containers::StridedArrayView2D<const char>& indices) -> Containers::Array<UnsignedInt> new in Git master
Create index buffer for a line strip primitive with a type-erased index buffer.
void generateLineStripIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output) new in 2020.06
Create index buffer for a line strip primitive into an existing array.
void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
Create index buffer for an indexed line strip primitive into an existing array.
void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
void generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
void generateLineStripIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
Create index buffer for a line strip primitive with a type-erased index buffer into an existing array.
auto generateLineLoopIndices(UnsignedInt vertexCount) -> Containers::Array<UnsignedInt> new in 2020.06
Create index buffer for a line loop primitive.
auto generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices) -> Containers::Array<UnsignedInt> new in Git master
Create index buffer for an indexed line loop primitive.
auto generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices) -> Containers::Array<UnsignedInt> new in Git master
auto generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices) -> Containers::Array<UnsignedInt> new in Git master
auto generateLineLoopIndices(const Containers::StridedArrayView2D<const char>& indices) -> Containers::Array<UnsignedInt> new in Git master
Create index buffer for a line loop primitive with a type-erased index buffer.
void generateLineLoopIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output) new in 2020.06
Create index buffer for a line loop primitive into an existing array.
void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
Create index buffer for an indexed line loop primitive into an existing array.
void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
void generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
void generateLineLoopIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
Create index buffer for a line loop primitive with a type-erased index buffer into an existing array.
auto generateTriangleStripIndices(UnsignedInt vertexCount) -> Containers::Array<UnsignedInt> new in 2020.06
Create index buffer for a triangle strip primitive.
auto generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices) -> Containers::Array<UnsignedInt> new in Git master
Create index buffer for an indexed triangle strip primitive.
auto generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices) -> Containers::Array<UnsignedInt> new in Git master
auto generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices) -> Containers::Array<UnsignedInt> new in Git master
auto generateTriangleStripIndices(const Containers::StridedArrayView2D<const char>& indices) -> Containers::Array<UnsignedInt> new in Git master
Create index buffer for a triangle strip primitive with a type-erased index buffer.
void generateTriangleStripIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output) new in 2020.06
Create index buffer for a triangle strip primitive into an existing array.
void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
Create index buffer for an indexed triangle strip primitive into an existing array.
void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
void generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
void generateTriangleStripIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
Create index buffer for a triangle strip primitive with a type-erased index buffer into an existing array.
auto generateTriangleFanIndices(UnsignedInt vertexCount) -> Containers::Array<UnsignedInt> new in 2020.06
Create index buffer for a triangle fan primitive.
auto generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices) -> Containers::Array<UnsignedInt> new in Git master
Create index buffer for an indexed triangle fan primitive.
auto generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices) -> Containers::Array<UnsignedInt> new in Git master
auto generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices) -> Containers::Array<UnsignedInt> new in Git master
auto generateTriangleFanIndices(const Containers::StridedArrayView2D<const char>& indices) -> Containers::Array<UnsignedInt> new in Git master
Create index buffer for a triangle fan primitive with a type-erased index buffer.
void generateTriangleFanIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output) new in 2020.06
Create index buffer for a triangle fan primitive into an existing array.
void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
Create index buffer for an indexed triangle fan primitive into an existing array.
void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
void generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
void generateTriangleFanIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
Create index buffer for a triangle fan primitive with a type-erased index buffer into an existing array.
auto generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedInt>& quads) -> Containers::Array<UnsignedInt> new in Git master
Create a triangle index buffer for quad primitives.
auto generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedShort>& quads) -> Containers::Array<UnsignedInt> new in Git master
auto generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedByte>& quads) -> Containers::Array<UnsignedInt> new in Git master
void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedInt>& quads, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master
Create a triangle index buffer for quad primitives into an existing array.
void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedShort>& quads, const Containers::StridedArrayView1D<UnsignedShort>& output) new in Git master
void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedByte>& quads, const Containers::StridedArrayView1D<UnsignedByte>& output) new in Git master
auto generateIndices(const Trade::MeshData& mesh) -> Trade::MeshData new in 2020.06
Convert a mesh to a plain indexed one.
auto generateIndices(Trade::MeshData&& mesh) -> Trade::MeshData new in 2020.06
Convert a mesh to a plain indexed one.
auto generateLines(const Trade::MeshData& lineMesh) -> Trade::MeshData new in Git master
Generate a line mesh for use with Shaders::LineGL.
auto generateFlatNormals(const Containers::StridedArrayView1D<const Vector3>& positions) -> Containers::Array<Vector3> new in 2019.10
Generate flat normals.
void generateFlatNormalsInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<Vector3>& normals) new in 2019.10
Generate flat normals into an existing array.
auto generateFlatNormals(const std::vector<UnsignedInt>& indices, const std::vector<Vector3>& positions) -> std::pair<std::vector<UnsignedInt>, std::vector<Vector3>> deprecated in 2019.10
Generate flat normals.
auto generateSmoothNormals(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<const Vector3>& positions) -> Containers::Array<Vector3> new in 2019.10
Generate smooth normals.
auto generateSmoothNormals(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<const Vector3>& positions) -> Containers::Array<Vector3> new in 2019.10
auto generateSmoothNormals(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<const Vector3>& positions) -> Containers::Array<Vector3> new in 2019.10
auto generateSmoothNormals(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<const Vector3>& positions) -> Containers::Array<Vector3> new in 2020.06
Generate smooth normals using a type-erased index array.
void generateSmoothNormalsInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<Vector3>& normals) new in 2019.10
Generate smooth normals into an existing array.
void generateSmoothNormalsInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<Vector3>& normals) new in 2019.10
void generateSmoothNormalsInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<Vector3>& normals) new in 2019.10
void generateSmoothNormalsInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<Vector3>& normals) new in 2020.06
Generate smooth normals into an existing array using a type-erased index array.
template<class T, class ... U>
auto interleave(const T& first, const U&... next) -> Containers::Array<char>
Interleave vertex attributes.
template<class T, class ... U>
auto interleaveInto(Containers::ArrayView<char> buffer, const T& first, const U&... next) -> std::size_t
Interleave vertex attributes into existing buffer.
auto isInterleaved(const Trade::MeshData& mesh) -> bool new in 2020.06
If the mesh data is interleaved.
auto interleavedData(const Trade::MeshData& mesh) -> Containers::StridedArrayView2D<const char> new in 2020.06
Type-erased view on interleaved mesh data.
auto interleavedMutableData(Trade::MeshData& mesh) -> Containers::StridedArrayView2D<char> new in 2020.06
Mutable type-erased view on interleaved mesh data.
auto interleavedLayout(const Trade::MeshData& mesh, UnsignedInt vertexCount, Containers::ArrayView<const Trade::MeshAttributeData> extra = {}, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) -> Trade::MeshData new in 2020.06
Create an interleaved mesh layout.
auto interleavedLayout(const Trade::MeshData& mesh, UnsignedInt vertexCount, std::initializer_list<Trade::MeshAttributeData> extra, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) -> Trade::MeshData new in 2020.06
auto interleavedLayout(Trade::MeshData&& mesh, UnsignedInt vertexCount, Containers::ArrayView<const Trade::MeshAttributeData> extra = {}, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) -> Trade::MeshData new in 2020.06
Create an interleaved mesh layout.
auto interleavedLayout(Trade::MeshData&& mesh, UnsignedInt vertexCount, std::initializer_list<Trade::MeshAttributeData> extra, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) -> Trade::MeshData new in 2020.06
auto interleave(const Trade::MeshData& mesh, Containers::ArrayView<const Trade::MeshAttributeData> extra = {}, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) -> Trade::MeshData new in 2020.06
Interleave mesh data.
auto interleave(const Trade::MeshData& mesh, std::initializer_list<Trade::MeshAttributeData> extra, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) -> Trade::MeshData new in 2020.06
auto interleave(Trade::MeshData&& mesh, Containers::ArrayView<const Trade::MeshAttributeData> extra = {}, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) -> Trade::MeshData new in 2020.06
Interleave mesh data.
auto interleave(Trade::MeshData&& mesh, std::initializer_list<Trade::MeshAttributeData> extra, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) -> Trade::MeshData new in 2020.06
auto interleave(MeshPrimitive primitive, const Trade::MeshIndexData& indices, Containers::ArrayView<const Trade::MeshAttributeData> attributes) -> Trade::MeshData new in Git master
Create an indexed interleaved mesh.
auto interleave(MeshPrimitive primitive, const Trade::MeshIndexData& indices, std::initializer_list<Trade::MeshAttributeData> attributes) -> Trade::MeshData new in Git master
auto interleave(MeshPrimitive primitive, Containers::ArrayView<const Trade::MeshAttributeData> attributes) -> Trade::MeshData new in Git master
Create a non-indexed interleaved mesh.
auto interleave(MeshPrimitive primitive, std::initializer_list<Trade::MeshAttributeData> attributes) -> Trade::MeshData new in Git master
auto owned(const Trade::MeshData& mesh) -> Trade::MeshData deprecated in Git master
Create an owned Trade::MeshData.
auto owned(Trade::MeshData&& mesh) -> Trade::MeshData deprecated in Git master
Create an owned Trade::MeshData, if not already.
auto removeDuplicatesInPlace(const Containers::StridedArrayView2D<char>& data) -> Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> new in 2020.06
Remove duplicate data from given array in-place.
auto removeDuplicatesInPlaceInto(const Containers::StridedArrayView2D<char>& data, const Containers::StridedArrayView1D<UnsignedInt>& indices) -> std::size_t new in 2020.06
Remove duplicate data from given array in-place into given output index array.
auto removeDuplicates(const Containers::StridedArrayView2D<const char>& data) -> Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> new in 2020.06
Remove duplicate data from given array.
auto removeDuplicatesInto(const Containers::StridedArrayView2D<const char>& data, const Containers::StridedArrayView1D<UnsignedInt>& indices) -> std::size_t new in 2020.06
Remove duplicate data from given array into given output index array.
auto removeDuplicatesIndexedInPlace(const Containers::StridedArrayView1D<UnsignedInt>& indices, const Containers::StridedArrayView2D<char>& data) -> std::size_t new in 2020.06
Remove duplicates from indexed data in-place.
auto removeDuplicatesIndexedInPlace(const Containers::StridedArrayView1D<UnsignedShort>& indices, const Containers::StridedArrayView2D<char>& data) -> std::size_t new in 2020.06
auto removeDuplicatesIndexedInPlace(const Containers::StridedArrayView1D<UnsignedByte>& indices, const Containers::StridedArrayView2D<char>& data) -> std::size_t new in 2020.06
auto removeDuplicatesIndexedInPlace(const Containers::StridedArrayView2D<char>& indices, const Containers::StridedArrayView2D<char>& data) -> std::size_t new in 2020.06
Remove duplicates from indexed data in-place on a type-erased index array.
auto removeDuplicatesFuzzyInPlace(const Containers::StridedArrayView2D<Float>& data, Float epsilon = Math::TypeTraits<Float>::epsilon()) -> Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> new in 2020.06
Remove duplicate data from given array using fuzzy comparison in-place.
auto removeDuplicatesFuzzyInPlace(const Containers::StridedArrayView2D<Double>& data, Double epsilon = Math::TypeTraits<Double>::epsilon()) -> Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> new in 2020.06
auto removeDuplicatesFuzzyInPlaceInto(const Containers::StridedArrayView2D<Float>& data, const Containers::StridedArrayView1D<UnsignedInt>& indices, Float epsilon = Math::TypeTraits<Float>::epsilon()) -> std::size_t new in 2020.06
Remove duplicate data from given array using fuzzy comparison in-place into given output index array.
auto removeDuplicatesFuzzyInPlaceInto(const Containers::StridedArrayView2D<Double>& data, const Containers::StridedArrayView1D<UnsignedInt>& indices, Double epsilon = Math::TypeTraits<Double>::epsilon()) -> std::size_t new in 2020.06
template<class Vector>
auto removeDuplicates(std::vector<Vector>& data, typename Vector::Type epsilon = Math::TypeTraits<typename Vector::Type>::epsilon()) -> std::vector<UnsignedInt> deprecated in 2020.06
Remove duplicate data from a STL vector using fuzzy comparison in-place.
auto removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedInt>& indices, const Containers::StridedArrayView2D<Float>& data, Float epsilon = Math::TypeTraits<Float>::epsilon()) -> std::size_t new in 2020.06
Remove duplicates from indexed data using fuzzy comparison in-place.
auto removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedShort>& indices, const Containers::StridedArrayView2D<Float>& data, Float epsilon = Math::TypeTraits<Float>::epsilon()) -> std::size_t new in 2020.06
auto removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedByte>& indices, const Containers::StridedArrayView2D<Float>& data, Float epsilon = Math::TypeTraits<Float>::epsilon()) -> std::size_t new in 2020.06
auto removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedInt>& indices, const Containers::StridedArrayView2D<Double>& data, Double epsilon = Math::TypeTraits<Double>::epsilon()) -> std::size_t new in 2020.06
auto removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedShort>& indices, const Containers::StridedArrayView2D<Double>& data, Double epsilon = Math::TypeTraits<Double>::epsilon()) -> std::size_t new in 2020.06
auto removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedByte>& indices, const Containers::StridedArrayView2D<Double>& data, Double epsilon = Math::TypeTraits<Double>::epsilon()) -> std::size_t new in 2020.06
auto removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView2D<char>& indices, const Containers::StridedArrayView2D<Float>& data, Float epsilon = Math::TypeTraits<Float>::epsilon()) -> std::size_t new in 2020.06
Remove duplicates from indexed data using fuzzy comparison in-place on a type-erased index array.
auto removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView2D<char>& indices, const Containers::StridedArrayView2D<Double>& data, Double epsilon = Math::TypeTraits<Double>::epsilon()) -> std::size_t new in 2020.06
auto removeDuplicates(const Trade::MeshData& mesh) -> Trade::MeshData new in 2020.06
Remove mesh data duplicates.
auto removeDuplicatesFuzzy(const Trade::MeshData& mesh, Float floatEpsilon = Math::TypeTraits<Float>::epsilon(), Double doubleEpsilon = Math::TypeTraits<Double>::epsilon()) -> Trade::MeshData new in 2020.06
Remove mesh data duplicates with fuzzy comparison for floating-point attributes.
template<class IndexType, class Vertex, class Interpolator>
void subdivide(Containers::Array<IndexType>& indices, Containers::Array<Vertex>& vertices, Interpolator interpolator) new in 2020.06
Subdivide a mesh.
template<class Vertex, class Interpolator>
void subdivide(std::vector<UnsignedInt>& indices, std::vector<Vertex>& vertices, Interpolator interpolator) deprecated in 2020.06
Subdivide a mesh.
template<class IndexType, class Vertex, class Interpolator>
void subdivideInPlace(const Containers::StridedArrayView1D<IndexType>& indices, const Containers::StridedArrayView1D<Vertex>& vertices, Interpolator interpolator) new in 2020.06
Subdivide a mesh in-place.
template<class IndexType, class Vertex, class Interpolator>
void subdivideInPlace(const Containers::ArrayView<IndexType>& indices, const Containers::StridedArrayView1D<Vertex>& vertices, Interpolator interpolator) new in 2020.06
void tipsifyInPlace(const Containers::StridedArrayView1D<UnsignedInt>& indices, UnsignedInt vertexCount, std::size_t cacheSize)
Tipsify the mesh in-place.
void tipsifyInPlace(const Containers::StridedArrayView1D<UnsignedShort>& indices, UnsignedInt vertexCount, std::size_t cacheSize) new in 2020.06
void tipsifyInPlace(const Containers::StridedArrayView1D<UnsignedByte>& indices, UnsignedInt vertexCount, std::size_t cacheSize) new in 2020.06
void tipsify(std::vector<UnsignedInt>& indices, UnsignedInt vertexCount, std::size_t cacheSize) deprecated in 2020.06
Tipsify the mesh in-place.
template<class T, class U>
void transformVectorsInPlace(const Math::Matrix4<T>& matrix, U&& vectors)
Transform vectors in-place using given transformation.
template<class T, class U>
void transformVectorsInPlace(const Math::Matrix3<T>& matrix, U&& vectors)
template<class T, class U>
void transformVectorsInPlace(const Math::Complex<T>& complex, U&& vectors)
template<class T, class U>
void transformVectorsInPlace(const Math::Quaternion<T>& normalizedQuaternion, U&& vectors)
template<class T, class U>
auto transformVectors(const T& transformation, U vectors) -> U
Transform vectors using given transformation.
template<class T, class U>
void transformPointsInPlace(const Math::Matrix4<T>& matrix, U&& points)
Transform points in-place using given transformation.
template<class T, class U>
void transformPointsInPlace(const Math::Matrix3<T>& matrix, U&& points)
template<class T, class U>
void transformPointsInPlace(const Math::DualComplex<T>& dualComplex, U&& points)
template<class T, class U>
void transformPointsInPlace(const Math::DualQuaternion<T>& normalizedDualQuaternion, U&& points)
template<class T, class U>
auto transformPoints(const T& transformation, U vectors) -> U
Transform points using given transformation.
auto transform2D(const Trade::MeshData& mesh, const Matrix3& transformation, UnsignedInt id = 0, Int morphTargetId = -1, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) -> Trade::MeshData new in Git master
Transform 2D positions in a mesh data.
auto transform2D(const Trade::MeshData& mesh, const Matrix3& transformation, UnsignedInt id, InterleaveFlags flags) -> Trade::MeshData deprecated in Git master
Transform 2D positions in a mesh data.
auto transform2D(Trade::MeshData&& mesh, const Matrix3& transformation, UnsignedInt id = 0, Int morphTargetId = -1, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) -> Trade::MeshData new in Git master
Transform 2D positions in a mesh data.
auto transform2D(Trade::MeshData&& mesh, const Matrix3& transformation, UnsignedInt id, InterleaveFlags flags) -> Trade::MeshData deprecated in Git master
Transform 2D positions in a mesh data.
void transform2DInPlace(Trade::MeshData& mesh, const Matrix3& transformation, UnsignedInt id = 0, Int morphTargetId = -1) new in Git master
Transform 2D positions in a mesh data in-place.
auto transform3D(const Trade::MeshData& mesh, const Matrix4& transformation, UnsignedInt id = 0, Int morphTargetId = -1, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) -> Trade::MeshData new in Git master
Transform 3D positions, normals, tangents and bitangents in a mesh data.
auto transform3D(const Trade::MeshData& mesh, const Matrix4& transformation, UnsignedInt id, InterleaveFlags flags) -> Trade::MeshData deprecated in Git master
Transform 3D positions, normals, tangents and bitangents in a mesh data.
auto transform3D(Trade::MeshData&& mesh, const Matrix4& transformation, UnsignedInt id = 0, Int morphTargetId = -1, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) -> Trade::MeshData new in Git master
Transform 3D positions, normals, tangenta and bitangents in a mesh data.
auto transform3D(Trade::MeshData&& mesh, const Matrix4& transformation, UnsignedInt id, InterleaveFlags flags) -> Trade::MeshData deprecated in Git master
Transform 3D positions, normals, tangenta and bitangents in a mesh data.
void transform3DInPlace(Trade::MeshData& mesh, const Matrix4& transformation, UnsignedInt id = 0, Int morphTargetId = -1) new in Git master
Transform 3D positions, normals, tangents and bitangents in a mesh data in-place.
auto transformTextureCoordinates2D(const Trade::MeshData& mesh, const Matrix3& transformation, UnsignedInt id = 0, Int morphTargetId = -1, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) -> Trade::MeshData new in Git master
Transform 2D texture coordinates in a mesh data.
auto transformTextureCoordinates2D(const Trade::MeshData& mesh, const Matrix3& transformation, UnsignedInt id, InterleaveFlags flags) -> Trade::MeshData deprecated in Git master
Transform 2D texture coordinates in a mesh data.
auto transformTextureCoordinates2D(Trade::MeshData&& mesh, const Matrix3& transformation, UnsignedInt id = 0, Int morphTargetId = -1, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) -> Trade::MeshData new in Git master
Transform 2D texture coordinates in a mesh data.
auto transformTextureCoordinates2D(Trade::MeshData&& mesh, const Matrix3& transformation, UnsignedInt id, InterleaveFlags flags) -> Trade::MeshData deprecated in Git master
Transform 2D texture coordinates in a mesh data.
void transformTextureCoordinates2DInPlace(Trade::MeshData& mesh, const Matrix3& transformation, UnsignedInt id = 0, Int morphTargetId = -1) new in Git master
Transform 2D texture coordinates in a mesh data in-place.

Enum documentation

enum class Magnum::MeshTools::CompileFlag: UnsignedByte new in 2019.10

Mesh compilation flag.

Enumerators
GenerateFlatNormals

If the mesh is MeshPrimitive::Triangles, generates normals using MeshTools::generateFlatNormals(). If the mesh is not a triangle mesh or doesn't have 3D positions, this flag does nothing. If the mesh already has its own normals, these get replaced. If CompileFlag::GenerateSmoothNormals is specified together with this flag, this flag gets a priority.

GenerateSmoothNormals

If the mesh MeshPrimitive::Triangles, generates normals using MeshTools::generateSmoothNormals() based on triangle adjacency information from the index buffer. If the mesh is not indexed, this behaves the same as CompileFlag::GenerateFlatNormals. If the mesh is not a triangle mesh or doesn't have 3D positions, this flag does nothing. If the mesh already has its own normals, these get replaced.

NoWarnOnCustomAttributes new in 2020.06

By default, compile() warns when it encounters custom attributes, morph target attributes and attributes with an implementation-specific format, as those get ignored by it. If you're binding those manually with compile(const Trade::MeshData&, GL::Buffer&, GL::Buffer&) or handling them in some other way on the application side already, use this flag to suppress the warning messages.

enum class Magnum::MeshTools::InterleaveFlag: UnsignedInt new in Git master

Interleaving behavior flag.

Enumerators
PreserveInterleavedAttributes

If the mesh is already interleaved, preserves existing layout of the attributes as well as any padding or aliasing among them, keeping the original stride and only removing the initial offset. This can also preserve attributes with an implementation-specific VertexFormat.

If not set or if the mesh is not interleaved to begin with, a tightly packed stride is calculated from vertex format sizes of all attributes, removing all padding. In that case an implementation-specific VertexFormat can't be used for any attribute.

PreserveStridedIndices

If a mesh is indexed, makes interleave(const Trade::MeshData&, Containers::ArrayView<const Trade::MeshAttributeData>, InterleaveFlags) preserve the index buffer even if it's not tightly packed. Since such data layouts are not commonly supported by GPU APIs, this flag is not set by default.

If not set and the index buffer is strided, a tightly packed copy with the same index type is allocated for the output, dropping also any padding before or after the original index view. In such case however, the index type is not allowed to be implementation-specific.

Has no effect when passed to interleavedLayout() as that function doesn't preserve the index buffer. Has no effect when passed to concatenate() as that function allocates a new combined index buffer anyway.

Typedef documentation

Function documentation

Containers::Pair<Vector3, Float> Magnum::MeshTools::boundingSphereBouncingBubble(const Containers::StridedArrayView1D<const Vector3>& positions) new in Git master

Calculate an approximate bounding sphere using the Bouncing Bubble algorithm.

Parameters
positions Vertex positions
Returns Sphere center and radius

The resulting bounding sphere is not usually minimal. According to the author, a 1% to 2% error can be expected. Due to the nature of the algorithm, the radius is never below Math::TypeTraits::epsilon(), even for empty or entirely overlapping lists of points. NaNs are ignored, unless the first position is NaN in which case it is propagated. Algorithm used: Bo Tian — Bouncing Bubble: A fast algorithm for Minimal Enclosing Ball problem, 2012, https://www.grin.com/document/204869.

Trade::MeshData Magnum::MeshTools::combineIndexedAttributes(const Containers::Iterable<const Trade::MeshData>& meshes) new in 2020.06

Combine differently indexed attributes into a single mesh.

Assuming all meshes contain only unique vertex data, creates an indexed mesh that contains all attributes from meshes combined, with duplicate vertices removed. For example, when you have a position and a normal array, each indexed with separate indices like this:

{pA, pB, pC, pD, pE, pF}        // positions
{nA, nB, nC, nD, nE, nF, nG}    // normals

{0, 2, 5, 0, 0, 1, 3, 2, 2}     // position indices
{1, 3, 4, 1, 4, 6, 1, 3, 1}     // normal indices

Then the first triangle in the mesh is defined as {pA, nB}, {pC, nD}, {pF, nE}. When combined together using this function, the resulting mesh stays the same but there's just one index array, indexing both positions and normals:

{{pA, nB}, {pC, nD}, {pF, nE}, {pA, nE}, {pB, nG}, {pD, nB}, {pC, nB}}
                                // unique pairs of positions and normals

{0, 1, 2, 0, 3, 4, 5, 1, 6}     // unified indices

The function preserves all attribute data including repeated or custom attributes. The resulting mesh is interleaved, with all attributes packed tightly together. If you need to add specific padding for alignment preservation, pass the result to interleave() and specify the paddings between attributes manually. Similarly, for simplicity the resulting mesh has always MeshIndexType::UnsignedInt — use compressIndices(const Trade::MeshData&, MeshIndexType) if you want to have it compressed to a smaller type.

Vertex data unreferenced by the index buffers are discarded. This means the function can be also called with just a single argument to compact a mesh with a sparse index buffer.

Expects that meshes is non-empty and all data have the same primitive and index count. All inputs have to be indexed. For non-indexed attributes combining can be done much more efficiently using duplicate(const Trade::MeshData&, Containers::ArrayView<const Trade::MeshAttributeData>), alternatively you can turn a non-indexed attribute to an indexed one first using removeDuplicatesInPlace() and then call this function. Index buffers and attributes in all meshes are expected to not have an implementation-specific format.

Trade::MeshData Magnum::MeshTools::combineFaceAttributes(const Trade::MeshData& mesh, const Trade::MeshData& faceAttributes) new in 2020.06

Combine per-face attributes into an existing mesh.

The resulting mesh will have all per-face attributes turned into per-vertex attributes, leaving only unique combinations and adjusting the index buffer accordingly. The resulting mesh has the same amount of indices, but likely more vertices.

Expects that mesh is indexed MeshPrimitive::Triangles and faceAttributes is MeshPrimitive::Faces, with face element count of the latter corresponding to triangle count of the former. If faceAttributes is indexed, it's assumed to have the data unique; if it's not indexed, it's first made unique using removeDuplicates() and in that case it's expected to be interleaved. Index buffers and attributes in both meshes are expected to not have an implementation-specific format.

The combineFaceAttributes(const Trade::MeshData&, Containers::ArrayView<const Trade::MeshAttributeData>) overload allows for more convenient addition of per-face attributes into a mesh without having to wrap them in a Trade::MeshData first. See its documentation for a usage example.

Trade::MeshData Magnum::MeshTools::combineFaceAttributes(const Trade::MeshData& mesh, Containers::ArrayView<const Trade::MeshAttributeData> faceAttributes) new in 2020.06

Combine per-face attributes into an existing mesh.

Wraps faceAttributes in a Trade::MeshData with MeshPrimitive::Faces and no index buffer and calls combineFaceAttributes(const Trade::MeshData&, const Trade::MeshData&). Example usage — adding a per-face color to an existing mesh:

Containers::ArrayView<const Color3> faceColors = ;

Trade::MeshData meshWithFaceColors = MeshTools::combineFaceAttributes(mesh, {
    Trade::MeshAttributeData{Trade::MeshAttribute::Color, faceColors}
});

Same as with combineFaceAttributes(const Trade::MeshData&, const Trade::MeshData&), faceAttributes is expected to be interleaved. Note that offset-only Trade::MeshAttributeData instances are not supported in the faceAttributes array.

Trade::MeshData Magnum::MeshTools::combineFaceAttributes(const Trade::MeshData& mesh, std::initializer_list<Trade::MeshAttributeData> faceAttributes) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

std::vector<UnsignedInt> Magnum::MeshTools::combineIndexArrays(const std::vector<std::reference_wrapper<std::vector<UnsignedInt>>>& arrays)

Combine index arrays.

Parameters
arrays in/out Index arrays to combine. These arrays are updated in-place to contain unique combinations of the original indices.
Returns Resulting combined index array

Creates new combined index array and updates the original ones with translation to new ones. For example, when you have position and normal array, each indexed with separate indices and you want to index both of them with single index array:

a b c d e f         // positions
A B C D E F G       // normals

0 2 5 0 0 1 3 2 2   // position indices
1 3 4 1 4 6 1 3 1   // normal indices

In particular, first triangle in the mesh will have positions a c f and normals B D E. You can see that not all combinations are unique and also that there are some vertices unused. When you pass the two index arrays above to this function, the following combined index array is returned:

0 1 2 0 3 4 5 1 6

And the original arrays are cleaned up to have only unique combinations:

0 2 5 0 1 3 2
1 3 4 4 6 1 1

You can use these as translation table to create new vertex and normal arrays which can be then indexed with the combined index array:

a c f a b d c
B D E E G B B

Again, first triangle in the mesh will have positions a c f and normals B D E.

This function calls combineIndexArrays(const std::vector<UnsignedInt>&, UnsignedInt) internally. See also combineIndexedArrays() which does the vertex data reordering automatically.

std::vector<UnsignedInt> Magnum::MeshTools::combineIndexArrays(std::initializer_list<std::reference_wrapper<std::vector<UnsignedInt>>> arrays)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

std::pair<std::vector<UnsignedInt>, std::vector<UnsignedInt>> Magnum::MeshTools::combineIndexArrays(const std::vector<UnsignedInt>& interleavedArrays, UnsignedInt stride)

Combine interleaved index arrays.

Unlike above, this function takes one interleaved array instead of separate index arrays. Continuing with the above example, you would call this function with the following array (odd value is vertex index, even is normal index, stride is thus 2):

0 1 2 3 5 4 0 1 0 4 1 6 3 1 2 3 2 1

Similarly to above this function will return the following combined index array as first pair value:

0 1 2 0 3 4 5 1 6

And second pair value is the cleaned up interleaved array:

0 1 2 3 5 4 0 4 1 6 3 1 2 1

template<class ... T>
std::vector<UnsignedInt> Magnum::MeshTools::combineIndexedArrays(const std::pair<const std::vector<UnsignedInt>&, std::vector<T>&>&... indexedArrays)

Combine indexed arrays.

Parameters
indexedArrays in/out Index and attribute arrays
Returns Array with resulting indices

Creates new combined index array and reorders original attribute arrays so they can be indexed with the new single index array.

The index array must be passed as const reference (to avoid copying) and attribute array as reference, so it can be replaced with combined data. To avoid explicit verbose specification of tuple type, you can write it with help of some STL functions like shown below. Also if one index array is shared by more than one attribute array, just pass the index array more times. Example:

std::vector<UnsignedInt> vertexIndices;
std::vector<Vector3> positions;
std::vector<UnsignedInt> normalTextureIndices;
std::vector<Vector3> normals;
std::vector<Vector2> textureCoordinates;

std::vector<UnsignedInt> indices = MeshTools::combineIndexedArrays(
    std::make_pair(std::cref(vertexIndices), std::ref(positions)),
    std::make_pair(std::cref(normalTextureIndices), std::ref(normals)),
    std::make_pair(std::cref(normalTextureIndices), std::ref(textureCoordinates))
);

See combineIndexArrays() documentation for more information about the procedure.

GL::Mesh Magnum::MeshTools::compile(const Trade::MeshData& mesh, CompileFlags flags) new in 2020.06

Compile OpenGL mesh data.

Configures a mesh for a Shaders::GenericGL shader with a vertex buffer and possibly also an index buffer, if the mesh is indexed.

If normal generation is not requested, Trade::MeshData::indexData() and Trade::MeshData::vertexData() are uploaded as-is without any further modifications, keeping the original layout and vertex formats. If CompileFlag::GenerateSmoothNormals is requested, vertex data is interleaved together with the generated normals; if CompileFlag::GenerateFlatNormals is requested, the mesh is first deindexed and then the vertex data is interleaved together with the generated normals.

The generated mesh owns the index and vertex buffers and there's no possibility to access them afterwards. For alternative solutions see the compile(const Trade::MeshData&, GL::Buffer&, GL::Buffer&) overloads.

GL::Mesh Magnum::MeshTools::compile(const Trade::MeshData& mesh) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

GL::Mesh Magnum::MeshTools::compile(const Trade::MeshData& mesh, GL::Buffer& indices, GL::Buffer& vertices) new in 2020.06

Compile mesh data using external buffers.

Assumes the whole vertex / index data are already uploaded to indices / vertices and sets up the mesh using those. Can be used to have a single index/vertex buffer when multiple Trade::MeshData instances share the same data arrays, or to allow buffer access later. For example:

GL::Buffer indices{meshData.indexData()};
GL::Buffer vertices{meshData.vertexData()};
GL::Mesh mesh = MeshTools::compile(meshData, indices, vertices);

Another use case is specifying additional vertex attributes that are not recognized by the function itself. You can choose among various r-value overloads depending on whether you want to have the index/vertex buffers owned by the mesh or not:

struct MyShader: GL::AbstractShaderProgram {
    typedef GL::Attribute<> MyCustomAttribute;

    
};
Trade::MeshAttribute myCustomAttribute = ;

GL::Buffer indices{meshData.indexData()};
GL::Buffer vertices{meshData.vertexData()};

/* Let compile() handle the usual attributes and configure custom ones after */
GL::Mesh mesh = MeshTools::compile(meshData, std::move(indices), vertices);
mesh.addVertexBuffer(std::move(vertices),
    meshData.attributeOffset(myCustomAttribute),
    meshData.attributeStride(myCustomAttribute),
    GL::DynamicAttribute{
        MyShader::MyCustomAttribute{},
        meshData.attributeFormat(myCustomAttribute)
    });

If mesh is not indexed, the indices parameter is ignored — in that case you can pass a NoCreate-d instance to avoid allocating an unnecessary OpenGL buffer object.

Compared to compile(const Trade::MeshData&, CompileFlags), this function implicitly enables the CompileFlag::NoWarnOnCustomAttributes flag, assuming that custom attributes and attributes with implementation-specific formats are explicitly handled on the application side.

GL::Mesh Magnum::MeshTools::compile(const Trade::MeshData& mesh, GL::Buffer& indices, GL::Buffer&& vertices) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

GL::Mesh Magnum::MeshTools::compile(const Trade::MeshData& mesh, GL::Buffer&& indices, GL::Buffer& vertices) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

GL::Mesh Magnum::MeshTools::compile(const Trade::MeshData& mesh, GL::Buffer&& indices, GL::Buffer&& vertices) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

GL::Mesh Magnum::MeshTools::compile(const Trade::MeshData2D& meshData)

Compile 2D mesh data.

Configures a mesh for Shaders::GenericGL2D shader with vertex buffer and possibly also an index buffer, if the mesh is indexed. Positions are bound to Shaders::GenericGL2D::Position attribute. If the mesh contains texture coordinates, these are bound to Shaders::GenericGL2D::TextureCoordinates attribute. If the mesh contains colors, these are bound to Shaders::GenericGL3D::Color4 attribute. No data compression or index optimization (except for index buffer packing) is done, both the vertex buffer and the index buffer (if any) is owned by the mesh, both created with GL::BufferUsage::StaticDraw.

This is just a convenience function for creating generic meshes, you might want to use interleave() and compressIndices() functions together with GL::Mesh::setPrimitive(), GL::Mesh::setCount(), GL::Mesh::addVertexBuffer(), GL::Mesh::setIndexBuffer() instead for greater flexibility.

GL::Mesh Magnum::MeshTools::compile(const Trade::MeshData3D& meshData, CompileFlags flags = {})

Compile 3D mesh data.

Configures mesh for Shaders::GenericGL3D shader with vertex buffer and possibly also index buffer, if the mesh is indexed. Positions are bound to Shaders::GenericGL3D::Position attribute. If the mesh contains normals, they are bound to Shaders::GenericGL3D::Normal attribute, texture coordinates are bound to Shaders::GenericGL3D::TextureCoordinates attribute. If the mesh contains colors, they are bound to Shaders::GenericGL3D::Color4 attribute. No data compression or index optimization (except for index buffer packing) is done, both the vertex buffer and the index buffer (if any) is owned by the mesh, both created with GL::BufferUsage::StaticDraw.

This is just a convenience function for creating generic meshes, you might want to use interleave() and compressIndices() functions together with GL::Mesh::setPrimitive(), GL::Mesh::setCount(), GL::Mesh::addVertexBuffer(), GL::Mesh::setIndexBuffer() instead for greater flexibility.

Containers::Pair<UnsignedInt, UnsignedInt> Magnum::MeshTools::compiledPerVertexJointCount(const Trade::MeshData& mesh) new in Git master

Compiled per-vertex joint count for given mesh data.

Returns the count of bound primary and secondary per-vertex joint IDs and weights that a mesh returned from compile(const Trade::MeshData&, CompileFlags) would contain. The function goes over all Trade::MeshAttribute::JointIds and Weights attributes present in the mesh and assigns them to the primary and secondary binding points:

  • If the mesh contains just one instance of joint ID and weight attributes and their Trade::MeshData::attributeArraySize() is not larger than 4, they occupy just the primary binding slot. The second returned value is 0.
  • If the mesh contains more than one instance of joint ID and weight attributes and array size of the first instance is not larger than 4, the first instance goes to the primary binding slot and the first up to 4 array components of the second instance go to the secondary slot. Remaining array components of the second instance and all remaining instances of joint ID and weight attributes are ignored.
  • If array size of the first instance of joint ID and weight attributes is larger than 4, the first slot uses the first 4 array components and the second the next up to 4 array components. Remaining array components of the first instance and all remaining instances of joint ID and weight attributes are ignored.

Useful to get subsequently fed to Shaders::FlatGL::Configuration::setJointCount() or to Shaders::FlatGL::setPerVertexJointCount() if Shaders::FlatGL::Flag::DynamicPerVertexJointCount is enabled, and similarly with other builtin shaders. See Skinning for a high-level introduction.

GL::Mesh Magnum::MeshTools::compileLines(const Trade::MeshData& mesh) new in Git master

Compile a line mesh for use with Shaders::LineGL.

Expects that the mesh is returned from generateLines(), see its documentation for more information.

Containers::Pair<Containers::Array<char>, MeshIndexType> Magnum::MeshTools::compressIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0) new in 2020.06

Compress an index array.

Parameters
indices Index array
atLeast Smallest allowed type
offset Offset to subtract from each index
Returns Compressed index array and corresponding type

This function compresses indices to the smallest possible size. For example when your indices have the maximum vertex index 463, it's wasteful to store them in array of 32-bit integers, array of 16-bit integers is sufficient. The atLeast parameter allows you to specify the smallest type to use and it defaults to MeshIndexType::UnsignedShort as 8-bit types are not friendly to many GPUs (and for example unextended Vulkan or D3D12 don't even support them). It's also possible to choose a type larger than the input type to "inflate" an index buffer of a smaller type. Example usage:

Containers::Array<UnsignedInt> indices;

Containers::Pair<Containers::Array<char>, MeshIndexType> compressed =
    MeshTools::compressIndices(indices);

GL::Buffer indexBuffer;
indexBuffer.setData(compressed.first());

GL::Mesh mesh;
mesh.setCount(indices.size())
    .setIndexBuffer(indexBuffer, 0, compressed.second());

In case the indices all start from a large offset, the offset parameter can be used to subtract it, allowing them to be compressed even further. For example, if all indices are in range $ [ 75000 ; 96000 ] $ (which fits only into a 32-bit type), subtracting 75000 makes them in range $ [ 0; 21000 ] $ which fits into 16 bits. Note that you also need to update vertex attribute offsets accordingly. Example:

Containers::ArrayView<const UnsignedInt> indices;
UnsignedInt offset = Math::min(indices);
Containers::Pair<Containers::Array<char>, MeshIndexType> compressed =
    MeshTools::compressIndices(indices, offset);

// use `offset` to adjust vertex attribute offset …

A negative offset value will do an operation inverse to the above. See also compressIndices(const Trade::MeshData&, MeshIndexType) that can do this operation directly on a Trade::MeshData instance.

The atLeast parameter is expected to not be an implementation-specific type.

Containers::Pair<Containers::Array<char>, MeshIndexType> Magnum::MeshTools::compressIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Containers::Pair<Containers::Array<char>, MeshIndexType> Magnum::MeshTools::compressIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Containers::Pair<Containers::Array<char>, MeshIndexType> Magnum::MeshTools::compressIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, Long offset) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Same as compressIndices(const Containers::StridedArrayView1D<const UnsignedInt>&, MeshIndexType, Long) with atLeast set to MeshIndexType::UnsignedShort.

Containers::Pair<Containers::Array<char>, MeshIndexType> Magnum::MeshTools::compressIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, Long offset) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Same as compressIndices(const Containers::StridedArrayView1D<const UnsignedShort>&, MeshIndexType, Long) with atLeast set to MeshIndexType::UnsignedShort.

Containers::Pair<Containers::Array<char>, MeshIndexType> Magnum::MeshTools::compressIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, Long offset) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Same as compressIndices(const Containers::StridedArrayView1D<const UnsignedByte>&, MeshIndexType, Long) with atLeast set to MeshIndexType::UnsignedShort.

Containers::Pair<Containers::Array<char>, MeshIndexType> Magnum::MeshTools::compressIndices(const Containers::StridedArrayView2D<const char>& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0) new in 2020.06

Compress a type-erased index array.

Expects that the second dimension of indices is contiguous and represents the actual 1/2/4-byte index type. Based on its size then calls one of the compressIndices(const Containers::StridedArrayView1D<const UnsignedInt>&, MeshIndexType, Long) etc. overloads.

The atLeast parameter is expected to not be an implementation-specific type.

Containers::Pair<Containers::Array<char>, MeshIndexType> Magnum::MeshTools::compressIndices(const Containers::StridedArrayView2D<const char>& indices, Long offset) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Same as compressIndices(const Containers::StridedArrayView2D<const char>&, MeshIndexType, Long) with atLeast set to MeshIndexType::UnsignedShort.

Trade::MeshData Magnum::MeshTools::compressIndices(const Trade::MeshData& mesh, MeshIndexType atLeast = MeshIndexType::UnsignedShort) new in 2020.06

Compress mesh data indices.

Does the same as compressIndices(const Containers::StridedArrayView2D<const char>&, MeshIndexType, Long), but together with adjusting vertex attribute offsets in the passed Trade::MeshData instance. By default the function will make a copy of all vertex data, pass a r-value in order to pick the compressIndices(Trade::MeshData&&, MeshIndexType) overload and avoid the copy. The function is by default using at least a 16-bit index type because while MeshIndexType::UnsignedByte can make the in-memory representation smaller, it's not supported by all GPU APIs and its usage is discouraged.

The mesh is expected to be indexed and the index type and the atLeast parameter is expected to not be implementation-specific type.

Trade::MeshData Magnum::MeshTools::compressIndices(Trade::MeshData&& mesh, MeshIndexType atLeast = MeshIndexType::UnsignedShort) new in 2020.06

Compress mesh data indices.

Compared to compressIndices(const Trade::MeshData&, MeshIndexType) this function can transfer ownership of data vertex buffer (in case it is owned) to the returned instance instead of making a copy of it. Index and attribute data are copied always.

std::tuple<Containers::Array<char>, MeshIndexType, UnsignedInt, UnsignedInt> Magnum::MeshTools::compressIndices(const std::vector<UnsignedInt>& indices)

Compress vertex indices.

Parameters
indices Index array
Returns Index range, type and compressed index array

This function takes index array and outputs them compressed to smallest possible size. For example when your indices have maximum number 463, it's wasteful to store them in array of 32bit integers, array of 16bit integers is sufficient.

Example usage:

std::vector<UnsignedInt> indices;

Containers::Array<char> indexData;
MeshIndexType indexType;
UnsignedInt indexStart, indexEnd;
std::tie(indexData, indexType, indexStart, indexEnd) =
    MeshTools::compressIndices(indices);

GL::Buffer indexBuffer;
indexBuffer.setData(indexData, GL::BufferUsage::StaticDraw);

GL::Mesh mesh;
mesh.setCount(indices.size())
    .setIndexBuffer(indexBuffer, 0, indexType, indexStart, indexEnd);

template<class T>
Containers::Array<T> Magnum::MeshTools::compressIndicesAs(const std::vector<UnsignedInt>& indices)

Compress vertex indices as given type.

The type can be either UnsignedByte, UnsignedShort or UnsignedInt. Values in the index array are expected to be representable with given type.

Example usage:

std::vector<UnsignedInt> indices;
Containers::Array<UnsignedShort> indexData =
    MeshTools::compressIndicesAs<UnsignedShort>(indices);

Trade::MeshData Magnum::MeshTools::concatenate(const Containers::Iterable<const Trade::MeshData>& meshes, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) new in 2020.06

Concatenate meshes together.

Parameters
meshes Meshes to concatenate
flags Flags to pass to interleavedLayout()

Returns a mesh that contains index and vertex data from all input meshes concatenated together. Usage example:

Trade::MeshData sphere = ;
Trade::MeshData cube = ;
Trade::MeshData cylinder = ;

Trade::MeshData primitives = MeshTools::concatenate({sphere, cube, cylinder});

Relative order of passed meshes is preserved in the resulting index and vertex data, meaning you can directly calculate their offsets for example if it's desirable to render or modify them separately. If any mesh is indexed, the resulting mesh is indexed as well, with indices adjusted for vertex offsets of particular meshes.

UnsignedInt sphereIndexOffset = 0;
UnsignedInt sphereVertexOffset = 0;
UnsignedInt cubeIndexOffset = sphereIndexOffset + sphere.indexCount(),
    cubeVertexOffset = sphereVertexOffset + sphere.vertexCount();
UnsignedInt cylinderIndexOffset = cubeIndexOffset + cube.indexCount(),
    cylinderVertexOffset = cubeVertexOffset + cube.vertexCount();

The indices, if present, are expected to not have an implementation-specific index type. The behavior is undefined if any mesh has indices out of range for its particular vertex count. Meshes with MeshPrimitive::LineStrip, MeshPrimitive::LineLoop, MeshPrimitive::TriangleStrip and MeshPrimitive::TriangleFan can't be concatenated — use generateIndices() to turn them into MeshPrimitive::Lines or MeshPrimitive::Triangles first. The meshes array is expected to have at least one item.

All attributes from the first mesh are taken, expected to not have an implementation-specific format. For each following mesh attributes present in the first are copied, superfluous attributes ignored and missing attributes zeroed out. Matching attributes are expected to have the same type, all meshes are expected to have the same primitive. In case of array attributes, attributes in subsequent meshes are expected to be arrays as well and have the same or smaller array size. Unused components at the end are zeroed out. The vertex data are concatenated in the same order as passed, with no duplicate removal. Returned instance vertex and index data flags always have both Trade::DataFlag::Owned and Trade::DataFlag::Mutable to guarante mutable access to particular parts of the concatenated mesh — for example for applying transformations.

The data layouting is done by interleavedLayout() with the flags parameter propagated to it, see its documentation for detailed behavior description.

If an index buffer is needed, MeshIndexType::UnsignedInt is always used. Call compressIndices(const Trade::MeshData&, MeshIndexType) on the result to compress it to a smaller type, if desired.

template<template<class> class Allocator = Containers::ArrayAllocator>
void Magnum::MeshTools::concatenateInto(Trade::MeshData& destination, const Containers::Iterable<const Trade::MeshData>& meshes, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) new in 2020.06

Concatenate a list of meshes into a pre-existing destination, enlarging it if necessary.

Template parameters
Allocator Allocator to use
Parameters
destination in/out Destination mesh from which the output arrays as well as desired attribute layout is taken
meshes in Meshes to concatenate
flags in Flags to pass to interleavedLayout()

Compared to concatenate(const Containers::Iterable<const Trade::MeshData>&, InterleaveFlags) this function resizes existing index and vertex buffers in destination using Containers::arrayResize() and given allocator, and reuses its atttribute data array instead of always allocating new ones. Only the attribute layout from destination is used, all vertex/index data are taken from meshes. Expects that meshes contains at least one item.

Trade::MeshData Magnum::MeshTools::copy(const Trade::MeshData& mesh) new in Git master

Make an owned copy of the mesh.

Allocates a copy of Trade::MeshData::indexData(), vertexData() and attributeData() and returns a new mesh with them. All other properties such as the primitive or importer state are passed through unchanged, the data layout isn't changed in any way. The resulting Trade::MeshData::indexDataFlags() and vertexDataFlags() are always Trade::DataFlag::Owned and Trade::DataFlag::Mutable. Attributes that were offset-only before are kept offset-only, others have offsets recalculated against the newly-allocated vertex data.

Trade::MeshData Magnum::MeshTools::copy(Trade::MeshData&& mesh) new in Git master

Make a mesh with owned data.

If Trade::MeshData::indexDataFlags() or vertexDataFlags() are not Trade::DataFlag::Owned and Trade::DataFlag::Mutable or the attribute data don't have the default deleter, allocates a copy of Trade::MeshData::indexData(), vertexData() or attributeData(), otherwise transfers their ownership. The resulting data are always owned and mutable, the data layout isn't changed in any way. Attributes that were offset-only before are kept offset-only, others have offsets recalculated against the potentially-newly-allocated vertex data.

Trade::MeshData Magnum::MeshTools::reference(const Trade::MeshData& mesh) new in 2020.06

Create an immutable reference on a Trade::MeshData.

The returned instance has empty Trade::MeshData::indexDataFlags() and Trade::MeshData::vertexDataFlags() and references attribute data from the mesh as well. The function performs no allocation or data copy. Use copy() for an inverse operation.

Trade::MeshData Magnum::MeshTools::mutableReference(Trade::MeshData& mesh) new in 2020.06

Create a mutable reference on a Trade::MeshData.

The returned instance has Trade::MeshData::indexDataFlags() and Trade::MeshData::vertexDataFlags() set to Trade::DataFlag::Mutable. The function performs no allocation or data copy. Use copy() for an inverse operation. Expects that mesh is mutable.

template<class IndexType, class T>
Containers::Array<T> Magnum::MeshTools::duplicate(const Containers::StridedArrayView1D<const IndexType>& indices, const Containers::StridedArrayView1D<const T>& data) new in 2019.10

Duplicate data using given index array.

Converts indexed array to non-indexed, for example data {a, b, c, d} with index array {1, 1, 0, 3, 2, 2} will be converted to {b, b, a, d, c, c}. The resulting array size is the same as size of indices, expects that all indices are in range for the data array.

If you want to fill an existing memory (or, for example a std::vector), use duplicateInto().

template<class IndexType, class T>
void Magnum::MeshTools::duplicateInto(const Containers::StridedArrayView1D<const IndexType>& indices, const Containers::StridedArrayView1D<const T>& data, const Containers::StridedArrayView1D<T>& out) new in 2019.10

Duplicate data using an index array into given output array.

Parameters
indices in Index array to use
data in Input data
out out Where to store the output

A variant of duplicate() that fills existing memory instead of allocating a new array. Expects that out has the same size as indices and all indices are in range for the data array.

void Magnum::MeshTools::duplicateInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView2D<const char>& data, const Containers::StridedArrayView2D<char>& out) new in 2020.06

Duplicate type-erased data using an index array into given output array.

Parameters
indices in Index array to use
data in Input data
out out Where to store the output

Compared to duplicateInto(const Containers::StridedArrayView1D<const IndexType>&, const Containers::StridedArrayView1D<const T>&, const Containers::StridedArrayView1D<T>&) accepts a 2D view, where the second dimension spans the actual type. Expects that out has the same size as indices and all indices are in range for the data array, and that the second dimension of both data and out is contiguous and has the same size.

void Magnum::MeshTools::duplicateInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView2D<const char>& data, const Containers::StridedArrayView2D<char>& out) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::duplicateInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView2D<const char>& data, const Containers::StridedArrayView2D<char>& out) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::duplicateInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView2D<const char>& data, const Containers::StridedArrayView2D<char>& out) new in 2020.06

Duplicate type-erased data using a type-erased index array into given output array.

Expects that the second dimension of indices is contiguous and represents the actual 1/2/4-byte index type. Based on its size then calls one of the duplicateInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView2D<const char>&, const Containers::StridedArrayView2D<char>&) etc. overloads.

Trade::MeshData Magnum::MeshTools::duplicate(const Trade::MeshData& mesh, Containers::ArrayView<const Trade::MeshAttributeData> extra = {}) new in 2020.06

Duplicate indexed mesh data.

Returns a copy of mesh that's not indexed and has all attributes interleaved and duplicated according to mesh's index buffer. The extra attributes, if any, are duplicated and interleaved together with existing attributes (or, in case the attribute view is empty, only the corresponding space for given attribute type is reserved, with memory left uninitialized). The data layouting is done by interleavedLayout(), see its documentation for detailed behavior description. Note that offset-only Trade::MeshAttributeData instances are not supported in the extra array.

Expects that mesh is indexed with a non-implementation-specific index type and each attribute in extra has either the same amount of elements as mesh vertex count (not index count) or has none. All attributes are expected to not have an implementation-specific format.

Trade::MeshData Magnum::MeshTools::duplicate(const Trade::MeshData& mesh, std::initializer_list<Trade::MeshAttributeData> extra) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::MeshData Magnum::MeshTools::filterAttributes(const Trade::MeshData& mesh, Containers::BitArrayView attributesToKeep) new in Git master

Filter a mesh to contain only the selected subset of attributes.

Returns a non-owning reference to the vertex and index buffer from mesh with only the attributes for which the corresponding bit in attributesToKeep was set. The index buffer, if present, is left untouched. The size of attributesToKeep is expected to be equal to Trade::MeshData::attributeCount().

This function only operates on the attribute metadata — if you'd like to have the vertex data repacked to contain just the remaining attributes as well, pass the output to interleave() without InterleaveFlag::PreserveInterleavedAttributes set.

Trade::MeshData Magnum::MeshTools::filterAttributes(Trade::MeshData&& mesh, Containers::BitArrayView attributesToKeep) new in Git master

Filter a mesh to contain only the selected subset of attributes.

Compared to filterAttributes(const Trade::MeshData&, Containers::BitArrayView), if the mesh index or vertex data is owned, the function transfers the data ownership to the returned instance instead of returning a non-owning reference. If neither the index nor the vertex data is owned, the two overloads behave the same.

Trade::MeshData Magnum::MeshTools::filterOnlyAttributes(const Trade::MeshData& mesh, Containers::ArrayView<const Trade::MeshAttribute> attributes) new in Git master

Filter a mesh to contain only the selected subset of named attributes.

Returns a non-owning reference to the vertex and index buffer from mesh with only the attributes that are listed in attributes. The index buffer, if present, is left untouched. Attributes from the list that are not present in mesh are skipped, duplicates in the list are treated the same as if given attribute was listed just once. If given attribute is present multiple times in the mesh (such as secondary colors or texture coordinates), all its occurences are kept — if you want a different behavior, use filterAttributes(const Trade::MeshData&, Containers::BitArrayView) and pick attributes by their IDs instead.

This function only operates on the attribute metadata — if you'd like to have the vertex data repacked to contain just the remaining attributes as well, pass the output to interleave() without InterleaveFlag::PreserveInterleavedAttributes set.

Trade::MeshData Magnum::MeshTools::filterOnlyAttributes(const Trade::MeshData& mesh, std::initializer_list<Trade::MeshAttribute> attributes) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::MeshData Magnum::MeshTools::filterOnlyAttributes(Trade::MeshData&& mesh, Containers::ArrayView<const Trade::MeshAttribute> attributes) new in Git master

Filter a mesh to contain only the selected subset of named attributes.

Compared to filterOnlyAttributes(const Trade::MeshData&, Containers::ArrayView<const Trade::MeshAttribute>), if the mesh index or vertex data is owned, the function transfers the data ownership to the returned instance instead of returning a non-owning reference. If neither the index nor the vertex data is owned, the two overloads behave the same.

Trade::MeshData Magnum::MeshTools::filterOnlyAttributes(Trade::MeshData&& mesh, std::initializer_list<Trade::MeshAttribute> attributes) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::MeshData Magnum::MeshTools::filterExceptAttributes(const Trade::MeshData& mesh, Containers::ArrayView<const Trade::MeshAttribute> attributes) new in Git master

Filter a mesh to contain everything except the selected subset of named attributes.

Returns a non-owning reference to the vertex and index buffer from mesh with only the attributes that are not listed in attributes. The index buffer, if present, is left untouched. Attributes from the list that are not present in mesh are skipped, duplicates in the list are treated the same as if given attribute was listed just once. If given attribute is present multiple times in the mesh (such as secondary colors or texture coordinates), all its occurences are removed — if you want a different behavior, use filterAttributes(const Trade::MeshData&, Containers::BitArrayView) and pick attributes by their IDs instead.

This function only operates on the attribute metadata — if you'd like to have the vertex mesh repacked to contain just the remaining attributes as well, pass the output to interleave() without InterleaveFlag::PreserveInterleavedAttributes set.

Trade::MeshData Magnum::MeshTools::filterExceptAttributes(const Trade::MeshData& mesh, std::initializer_list<Trade::MeshAttribute> attributes) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::MeshData Magnum::MeshTools::filterExceptAttributes(Trade::MeshData&& mesh, Containers::ArrayView<const Trade::MeshAttribute> attributes) new in Git master

Filter a mesh to contain everything except the selected subset of named attributes.

Compared to filterExceptAttributes(const Trade::MeshData&, Containers::ArrayView<const Trade::MeshAttribute>), if the mesh index or vertex data is owned, the function transfers the data ownership to the returned instance instead of returning a non-owning reference. If neither the index nor the vertex data is owned, the two overloads behave the same.

Trade::MeshData Magnum::MeshTools::filterExceptAttributes(Trade::MeshData&& mesh, std::initializer_list<Trade::MeshAttribute> attributes) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::MeshData Magnum::MeshTools::filterOnlyAttributes(const Trade::MeshData& mesh, Containers::ArrayView<const UnsignedInt> attributes)

Filter a mesh to contain only the selected subset of attributes.

Returns a non-owning reference to the vertex and index buffer from mesh with only the attribute IDs listed in attributes. IDs specified more than once don't result in given attribute being added multiple times. The index buffer, if present, is left untouched. All attribute IDs are expected to be smaller than Trade::MeshData::attributeCount() const.

This function only operates on the attribute metadata — if you'd like to have the vertex data repacked to contain just the remaining attributes as well, pass the output to interleave() without InterleaveFlag::PreserveInterleavedAttributes set.

Trade::MeshData Magnum::MeshTools::filterExceptAttributes(const Trade::MeshData& mesh, Containers::ArrayView<const UnsignedInt> attributes)

Filter a mesh to contain everything except the selected subset of attributes.

Returns a non-owning reference to the vertex and index buffer from mesh with only the attribute IDs that are not listed in attributes. IDs specified multiple times behave like if specified just once. The index buffer, if present, is left untouched. All attribute IDs are expected to be smaller than Trade::MeshData::attributeCount() const. If attributes is empty, the behavior is equivalent to reference().

This function only operates on the attribute metadata — if you'd like to have the vertex data repacked to contain just the remaining attributes as well, pass the output to interleave() without InterleaveFlag::PreserveInterleavedAttributes set.

Trade::MeshData Magnum::MeshTools::filterExceptAttributes(const Trade::MeshData& mesh, std::initializer_list<UnsignedInt> attributes)

Filter a mesh to contain everything except the selected subset of attributes.

void Magnum::MeshTools::flipNormalsInPlace(const Containers::StridedArrayView1D<UnsignedInt>& indices, const Containers::StridedArrayView1D<Vector3>& normals) new in 2020.06

Flip mesh normals and face winding in-place.

Parameters
indices in/out Index array to operate on
normals in/out Normal array to operate on

Flips normal vectors and face winding in index array for face culling to work properly too. See also flipNormalsInPlace(const Containers::StridedArrayView1D<Vector3>&) and flipFaceWindingInPlace(), which flip normals or face winding only. Expects a triangle mesh, thus the index count has to be divisible by 3.

void Magnum::MeshTools::flipNormalsInPlace(const Containers::StridedArrayView1D<UnsignedShort>& indices, const Containers::StridedArrayView1D<Vector3>& normals) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::flipNormalsInPlace(const Containers::StridedArrayView1D<UnsignedByte>& indices, const Containers::StridedArrayView1D<Vector3>& normals) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::flipNormalsInPlace(const Containers::StridedArrayView2D<char>& indices, const Containers::StridedArrayView1D<Vector3>& normals) new in 2020.06

Flip mesh normals and face winding in-place on a type-erased index array.

Expects that the second dimension of indices is contiguous and represents the actual 1/2/4-byte index type. Based on its size then calls one of the flipNormalsInPlace(const Containers::StridedArrayView1D<UnsignedInt>&, const Containers::StridedArrayView1D<Vector3>&) etc. overloads.

void Magnum::MeshTools::flipFaceWindingInPlace(const Containers::StridedArrayView1D<UnsignedInt>& indices) new in 2020.06

Flip face winding in-place.

Parameters
indices in/out Index array to operate on

Same as flipNormalsInPlace(const Containers::StridedArrayView1D<UnsignedInt>&, const Containers::StridedArrayView1D<Vector3>&), but flips only face winding. Expects a triangle mesh, thus the index count has to be divisible by 3.

void Magnum::MeshTools::flipFaceWindingInPlace(const Containers::StridedArrayView1D<UnsignedShort>& indices) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::flipFaceWindingInPlace(const Containers::StridedArrayView1D<UnsignedByte>& indices) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::flipFaceWindingInPlace(const Containers::StridedArrayView2D<char>& indices) new in 2020.06

Flip face winding in-place on a type-erased index array.

Expects that the second dimension of indices is contiguous and represents the actual 1/2/4-byte index type. Based on its size then calls one of the flipFaceWindingInPlace(const Containers::StridedArrayView1D<UnsignedInt>&) etc. overloads.

void Magnum::MeshTools::flipNormalsInPlace(const Containers::StridedArrayView1D<Vector3>& normals)

Flip mesh normals in-place.

Parameters
normals in/out Normal array to operate on

Same as flipNormalsInPlace(const Containers::StridedArrayView1D<UnsignedInt>&, const Containers::StridedArrayView1D<Vector3>&), but flips only normals, not face winding.

GL::Mesh Magnum::MeshTools::fullScreenTriangle(GL::Version version)

Full screen triangle mesh.

Returns a pre-configured mesh along with vertex buffer which can be used for full-screen post-processing effects. The mesh is a single triangle covering whole screen area ( $ (-1, -1) - (1, 1) $ in both dimensions) and provides only vertex positions, as other attributes (such as texture coordinates) can be calculated from them. The vertex positions are, in order:

\[ \begin{pmatrix} -1 \\ 1 \end{pmatrix}, \begin{pmatrix} -1 \\ -3 \end{pmatrix}, \begin{pmatrix} 3 \\ 1 \end{pmatrix} \]

Based on the version parameter, on OpenGL 2.1, OpenGL ES 2.0 and WebGL 1 the vertex positions are passed explicitly as attribute 0, contained in a vertex buffer owned by the mesh. On OpenGL 3.0+, OpenGL ES 3.0+ and WebGL 2 the mesh is attribute-less and the vertex positions can be calculated using the gl_VertexID builtin shader variable.

Calculating positions in the shader in a portable way can be done like this. For OpenGL 2.1 and OpenGL ES 2.0 you then need to bind location of the position attribute to 0.

#if (!defined(GL_ES) && __VERSION__ >= 130) || (defined(GL_ES) && __VERSION__ >= 300)
#define NEW_GLSL
#endif

#ifndef NEW_GLSL
attribute lowp vec4 position;
#endif

void main() {
    #ifdef NEW_GLSL
    gl_Position = vec4((gl_VertexID == 2) ?  3.0 : -1.0,
                       (gl_VertexID == 1) ? -3.0 :  1.0, 0.0, 1.0);
    #else
    gl_Position = position;
    #endif
}

GL::Mesh Magnum::MeshTools::fullScreenTriangle()

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

This function implicitly uses current context version.

UnsignedInt Magnum::MeshTools::primitiveCount(MeshPrimitive primitive, UnsignedInt elementCount) new in 2020.06

Actual primitive count for given primitive type and element count.

Returns how many primitives is generated for given primitive and elementCount, for example for MeshPrimitive::Triangles returns elementCount/3. Expects that primitive is valid, elementCount is either zero or at least 2 for a line-based primitive and at least 3 for a triangle-based primitive, is divisible by 2 for MeshPrimitive::Lines and by 3 for MeshPrimitive::Triangles.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateTrivialIndices(UnsignedInt vertexCount) new in Git master

Create a trivial index buffer.

Generates a 0, 1, 2, 3, 4, 5, ... sequence, i.e. what std::iota() would produce. Can be used to turn a non-indexed mesh into indexed.

void Magnum::MeshTools::generateTrivialIndicesInto(const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

Create a trivial index buffer into an existing array.

A variant of generateTrivialIndices() that fills existing memory instead of allocating a new array.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateLineStripIndices(UnsignedInt vertexCount) new in 2020.06

Create index buffer for a line strip primitive.

Generates a 0, 1, 1, 2, 3, 4, ... sequence. Can be used to convert a MeshPrimitive::LineStrip mesh to MeshPrimitive::Lines. The vertexCount is expected to be either 0 or at least 2. Primitive restart is not supported. If the mesh is already indexed, use generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>&) and overloads instead.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices) new in Git master

Create index buffer for an indexed line strip primitive.

Like generateLineStripIndices(UnsignedInt), but merges indices into the generated line strip index buffer.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateLineStripIndices(const Containers::StridedArrayView2D<const char>& indices) new in Git master

Create index buffer for a line strip primitive with a type-erased index buffer.

Expects that the second dimension of indices is contiguous and represents the actual 1/2/4-byte index type. Based on its size then calls one of the generateLineStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>&) etc. overloads.

void Magnum::MeshTools::generateLineStripIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output) new in 2020.06

Create index buffer for a line strip primitive into an existing array.

A variant of generateLineStripIndices() that fills existing memory instead of allocating a new array. The vertexCount is expected to be either 0 or at least 2, the output array is expected to have a size of 2*(vertexCount - 1). Primitive restart is not supported. If the mesh is already indexed, use generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&) and overloads instead.

void Magnum::MeshTools::generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

Create index buffer for an indexed line strip primitive into an existing array.

Like generateLineStripIndicesInto(UnsignedInt, const Containers::StridedArrayView1D<UnsignedInt>&), but merges indices into the generated line strip index buffer.

void Magnum::MeshTools::generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::generateLineStripIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

Create index buffer for a line strip primitive with a type-erased index buffer into an existing array.

Expects that the second dimension of indices is contiguous and represents the actual 1/2/4-byte index type. Based on its size then calls one of the generateLineStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&) etc. overloads.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateLineLoopIndices(UnsignedInt vertexCount) new in 2020.06

Create index buffer for a line loop primitive.

Generates a 0, 1, 1, 2, 3, ..., 0 sequence. Can be used to convert a MeshPrimitive::LineLoop mesh to MeshPrimitive::Lines. The vertexCount is expected to be either 0 or at least 2. Primitive restart is not supported. If the mesh is already indexed, use generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedInt>&) and overloads instead.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices) new in Git master

Create index buffer for an indexed line loop primitive.

Like generateLineLoopIndices(UnsignedInt), but merges indices into the generated line loop index buffer.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateLineLoopIndices(const Containers::StridedArrayView2D<const char>& indices) new in Git master

Create index buffer for a line loop primitive with a type-erased index buffer.

Expects that the second dimension of indices is contiguous and represents the actual 1/2/4-byte index type. Based on its size then calls one of the generateLineLoopIndices(const Containers::StridedArrayView1D<const UnsignedInt>&) etc. overloads.

void Magnum::MeshTools::generateLineLoopIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output) new in 2020.06

Create index buffer for a line loop primitive into an existing array.

A variant of generateLineLoopIndices() that fills existing memory instead of allocating a new array. The vertexCount is expected to be either 0 or at least 2, the output array is expected to have a size of 2*vertexCount. Primitive restart is not supported.If the mesh is already indexed, use generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&) and overloads instead.

void Magnum::MeshTools::generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

Create index buffer for an indexed line loop primitive into an existing array.

Like generateLineLoopIndicesInto(UnsignedInt, const Containers::StridedArrayView1D<UnsignedInt>&), but merges indices into the generated line loop index buffer.

void Magnum::MeshTools::generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::generateLineLoopIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

Create index buffer for a line loop primitive with a type-erased index buffer into an existing array.

Expects that the second dimension of indices is contiguous and represents the actual 1/2/4-byte index type. Based on its size then calls one of the generateLineLoopIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&) etc. overloads.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateTriangleStripIndices(UnsignedInt vertexCount) new in 2020.06

Create index buffer for a triangle strip primitive.

Generates a 0, 1, 2, 2, 1, 3, 2, 3, 4, ... sequence. Can be used to convert a MeshPrimitive::TriangleStrip mesh to MeshPrimitive::Triangles. The vertexCount is expected to be either 0 or at least 3. Primitive restart is not supported. If the mesh is already indexed, use generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>&) and overloads instead.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices) new in Git master

Create index buffer for an indexed triangle strip primitive.

Like generateTriangleStripIndices(UnsignedInt), but merges indices into the generated triangle strip index buffer.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateTriangleStripIndices(const Containers::StridedArrayView2D<const char>& indices) new in Git master

Create index buffer for a triangle strip primitive with a type-erased index buffer.

Expects that the second dimension of indices is contiguous and represents the actual 1/2/4-byte index type. Based on its size then calls one of the generateTriangleStripIndices(const Containers::StridedArrayView1D<const UnsignedInt>&) etc. overloads.

void Magnum::MeshTools::generateTriangleStripIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output) new in 2020.06

Create index buffer for a triangle strip primitive into an existing array.

A variant of generateTriangleStripIndices() that fills existing memory instead of allocating a new array. The vertexCount is expected to be either 0 or at least 3, the output array is expected to have a size of 3*(vertexCount - 2). Primitive restart is not supported. If the mesh is already indexed, use generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&) and overloads instead.

void Magnum::MeshTools::generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

Create index buffer for an indexed triangle strip primitive into an existing array.

Like generateTriangleStripIndicesInto(UnsignedInt, const Containers::StridedArrayView1D<UnsignedInt>&), but merges indices into the generated triangle strip index buffer.

void Magnum::MeshTools::generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::generateTriangleStripIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

Create index buffer for a triangle strip primitive with a type-erased index buffer into an existing array.

Expects that the second dimension of indices is contiguous and represents the actual 1/2/4-byte index type. Based on its size then calls one of the generateTriangleStripIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&) etc. overloads.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateTriangleFanIndices(UnsignedInt vertexCount) new in 2020.06

Create index buffer for a triangle fan primitive.

Generates a 0, 1, 2, 0, 2, 3, 0, 3, 4, ... sequence. Can be used to convert a MeshPrimitive::TriangleFan mesh to MeshPrimitive::Triangles. The vertexCount is expected to be either 0 or at least 3. Primitive restart is not supported. If the mesh is already indexed, use generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedInt>&) and overloads instead.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices) new in Git master

Create index buffer for an indexed triangle fan primitive.

Like generateTriangleFanIndices(UnsignedInt), but merges indices into the generated triangle fan index buffer.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateTriangleFanIndices(const Containers::StridedArrayView2D<const char>& indices) new in Git master

Create index buffer for a triangle fan primitive with a type-erased index buffer.

Expects that the second dimension of indices is contiguous and represents the actual 1/2/4-byte index type. Based on its size then calls one of the generateTriangleFanIndices(const Containers::StridedArrayView1D<const UnsignedInt>&) etc. overloads.

void Magnum::MeshTools::generateTriangleFanIndicesInto(UnsignedInt vertexCount, const Containers::StridedArrayView1D<UnsignedInt>& output) new in 2020.06

Create index buffer for a triangle fan primitive into an existing array.

A variant of generateTriangleFanIndices() that fills existing memory instead of allocating a new array. The vertexCount is expected to be either 0 or at least 3, the output array is expected to have a size of 3*(vertexCount - 2). Primitive restart is not supported. If the mesh is already indexed, use generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&) and overloads instead.

void Magnum::MeshTools::generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

Create index buffer for an indexed triangle fan primitive into an existing array.

Like generateTriangleFanIndicesInto(UnsignedInt, const Containers::StridedArrayView1D<UnsignedInt>&), but merges indices into the generated triangle fan index buffer.

void Magnum::MeshTools::generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::generateTriangleFanIndicesInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

Create index buffer for a triangle fan primitive with a type-erased index buffer into an existing array.

Expects that the second dimension of indices is contiguous and represents the actual 1/2/4-byte index type. Based on its size then calls one of the generateTriangleFanIndicesInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<UnsignedInt>&) etc. overloads.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedInt>& quads) new in Git master

Create a triangle index buffer for quad primitives.

B A C A C D B D

For each quad ABCD gives a pair of triangles that is either ABC ACD or DAB DBC, correctly handling cases of non-convex quads and avoiding thin triangles where possible. Loosely based on this SO question:

  1. If normals of triangles ABC and ACD point in opposite direction and DAB DBC not (which is equivalent to points D and B being on the same side of a diagonal AC in a two-dimensional case), split as DAB DBC
  2. Otherwise, if normals of triangles DAB and DBC point in opposite direction and ABC ACD not (which is equivalent to points A and C being on the same side of a diagonal DB in a two-dimensional case), split as ABC ACD
  3. Otherwise the normals either point in the same direction in both cases or the quad is non-planar and ambiguous, pick the case where the diagonal is shorter

Size of quads is expected to be divisible by 4 and all indices being in bounds of the positions view.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedShort>& quads) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Containers::Array<UnsignedInt> Magnum::MeshTools::generateQuadIndices(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedByte>& quads) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedInt>& quads, const Containers::StridedArrayView1D<UnsignedInt>& output) new in Git master

Create a triangle index buffer for quad primitives into an existing array.

A variant of generateQuadIndices() that fills existing memory instead of allocating a new array. Size of quads is expected to be divisible by 4 and output should have a size that's quads.size()*6/4.

void Magnum::MeshTools::generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedShort>& quads, const Containers::StridedArrayView1D<UnsignedShort>& output) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedByte>& quads, const Containers::StridedArrayView1D<UnsignedByte>& output) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::MeshData Magnum::MeshTools::generateIndices(const Trade::MeshData& mesh) new in 2020.06

Convert a mesh to a plain indexed one.

If mesh is one of MeshPrimitive::LineStrip, MeshPrimitive::LineLoop, MeshPrimitive::TriangleStrip or MeshPrimitive::TriangleFan primitives, calls one of generateLineStripIndices(), generateLineLoopIndices(), generateTriangleStripIndices() or generateTriangleFanIndices() functions or their indexed overloads to generate the index buffer. In that case expects that the mesh has either 0 vertices or at least 2 vertices for a line-based primitive and 3 vertices for a triangle-based primitive. If mesh is a different MeshPrimitive, it's passed through unchanged if already indexed, and with indices generated using generateTrivialIndices() otherwise.

If mesh is already indexed, the index type is expected to be non-implementation-specific.

The resulting mesh always has MeshIndexType::UnsignedInt, call compressIndices(const Trade::MeshData&, MeshIndexType) on the result to compress it to a smaller type, if desired. This function will unconditionally make a copy of all vertex data, use generateIndices(Trade::MeshData&&) to avoid that copy.

Trade::MeshData Magnum::MeshTools::generateIndices(Trade::MeshData&& mesh) new in 2020.06

Convert a mesh to a plain indexed one.

Compared to generateIndices(const Trade::MeshData&) this function can transfer ownership of mesh vertex buffer (in case it is owned) to the returned instance instead of making a copy of it, and index buffer as well if it's owned, doesn't need expanding and is already with MeshIndexType::UnsignedInt. Attribute data is copied always.

Trade::MeshData Magnum::MeshTools::generateLines(const Trade::MeshData& lineMesh) new in Git master

Generate a line mesh for use with Shaders::LineGL.

Creates a MeshPrimitive::Triangles mesh with MeshIndexType::UnsignedInt indices, all input attributes preserved in their original format, and additionally with custom attributes corresponding to Shaders::LineGL::PreviousPosition and Shaders::LineGL::NextPosition added in the same format as the input Trade::MeshAttribute::Position, and a custom attribute corresponding to the Shaders::LineGL::Annotation attribute as VertexFormat::UnsignedInt. See documentation of the shader for details about the internal representation.

Each line segment in the input vertices is converted to a quad, with first two vertices inheriting vertex data from the first point of the segment and second two vertices inheriting data from the second point of the segment. If the input mesh is indexed, it's deindexed first. Neighbor information from a MeshPrimitive::LineStrip or MeshPrimitive::LineLoop mesh is used to form a single contiguous strip or a loop, MeshPrimitive::Lines is treated as loose segments.

For compatibility with shaders other than Shaders::LineGL, the output mesh can be also interpreted as indexed MeshPrimitive::Lines — out of every six indices forming a quad, two will form a line segment between the two original points, and the remaining four collapse into two degenerate line segments.

Expects that the mesh contains at least a Trade::MeshAttribute::Position and is a line MeshPrimitive.

The returned Trade::MeshData instance is meant to be passed to compileLines() for use with the shader. It can however be also processed with other MeshTools first, such as compressIndices(const Trade::MeshData&, MeshIndexType) or concatenate().

Containers::Array<Vector3> Magnum::MeshTools::generateFlatNormals(const Containers::StridedArrayView1D<const Vector3>& positions) new in 2019.10

Generate flat normals.

Parameters
positions Triangle vertex positions
Returns Per-vertex normals

All vertices in each triangle face get the same normal vector. Expects that the position count is divisible by 3. If you need to generate flat normals for an indexed mesh, duplicate() the vertices first, after the operation you might want to remove the duplicates again using removeDuplicatesInPlace(). Example usage:

Containers::ArrayView<UnsignedInt> indices;
Containers::ArrayView<Vector3> indexedPositions;

Containers::Array<Vector3> positions =
    MeshTools::duplicate<UnsignedInt, Vector3>(indices, indexedPositions);

Containers::Array<Vector3> normals =
    MeshTools::generateFlatNormals(positions);

void Magnum::MeshTools::generateFlatNormalsInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<Vector3>& normals) new in 2019.10

Generate flat normals into an existing array.

Parameters
positions in Triangle vertex positions
normals out Where to put the generated normals

A variant of generateFlatNormals() that fills existing memory instead of allocating a new array. The normals array is expected to have the same size as positions.

Useful when you need to interface for example with STL containers — in that case #include Corrade/Containers/ArrayViewStl.h to get implicit conversions:

#include <Corrade/Containers/ArrayViewStl.h>

// …

std::vector<Vector3> positions;

std::vector<Vector3> normals{positions.size()};
MeshTools::generateFlatNormalsInto(positions, normals);

std::pair<std::vector<UnsignedInt>, std::vector<Vector3>> Magnum::MeshTools::generateFlatNormals(const std::vector<UnsignedInt>& indices, const std::vector<Vector3>& positions)

Generate flat normals.

Parameters
indices Triangle face indices
positions Triangle vertex positions
Returns Normal indices and vectors

All vertices in each triangle face get the same normal vector. Removes duplicates before returning. Expects that the position count is divisible by 3.

Containers::Array<Vector3> Magnum::MeshTools::generateSmoothNormals(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<const Vector3>& positions) new in 2019.10

Generate smooth normals.

Parameters
indices Triangle face indices
positions Triangle vertex positions
Returns Per-vertex normals

Uses the indices array to discover adjacent triangles and then for each vertex position calculates a normal averaged from all triangles that share it. The normal is weighted according to adjacent triangle area and angle at given vertex; hard edges are preserved where adjacent triangles don't share vertices. Triangles with zero area or triangles containing invalid positions (NaNs) don't contribute to calculated vertex normals.

Implementation is based on the article Weighted Vertex Normals by Martijn Buijs.

Containers::Array<Vector3> Magnum::MeshTools::generateSmoothNormals(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<const Vector3>& positions) new in 2019.10

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Containers::Array<Vector3> Magnum::MeshTools::generateSmoothNormals(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<const Vector3>& positions) new in 2019.10

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Containers::Array<Vector3> Magnum::MeshTools::generateSmoothNormals(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<const Vector3>& positions) new in 2020.06

Generate smooth normals using a type-erased index array.

Expects that the second dimension of indices is contiguous and represents the actual 1/2/4-byte index type. Based on its size then calls one of the generateSmoothNormals(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<const Vector3>&) etc. overloads.

void Magnum::MeshTools::generateSmoothNormalsInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<Vector3>& normals) new in 2019.10

Generate smooth normals into an existing array.

Parameters
indices in Triangle face indices
positions in Triangle vertex positions
normals out Where to put the generated normals

A variant of generateSmoothNormals() that fills existing memory instead of allocating a new array. The normals array is expected to have the same size as positions. Note that even with the output array this function isn't fully allocation-free — it still allocates three additional internal arrays for adjacent face calculation.

Useful when you need to interface for example with STL containers — in that case #include Corrade/Containers/ArrayViewStl.h to get implicit conversions:

#include <Corrade/Containers/ArrayViewStl.h>

// …

std::vector<UnsignedInt> indices;
std::vector<Vector3> positions;

std::vector<Vector3> normals{positions.size()};
MeshTools::generateSmoothNormalsInto(indices, positions, normals);

void Magnum::MeshTools::generateSmoothNormalsInto(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<Vector3>& normals) new in 2019.10

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::generateSmoothNormalsInto(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<Vector3>& normals) new in 2019.10

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::generateSmoothNormalsInto(const Containers::StridedArrayView2D<const char>& indices, const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<Vector3>& normals) new in 2020.06

Generate smooth normals into an existing array using a type-erased index array.

Expects that normals has the same size as positions and that the second dimension of indices is contiguous and represents the actual 1/2/4-byte index type. Based on its size then calls one of the generateSmoothNormalsInto(const Containers::StridedArrayView1D<const UnsignedInt>&, const Containers::StridedArrayView1D<const Vector3>&, const Containers::StridedArrayView1D<Vector3>&) etc. overloads.

template<class T, class ... U>
Containers::Array<char> Magnum::MeshTools::interleave(const T& first, const U&... next)

Interleave vertex attributes.

This function takes list of attribute arrays and returns them interleaved, so data for each attribute are in continuous place in memory. Expects that all attributes have the same element count.

Example usage:

Containers::ArrayView<const Vector3> positions;
Containers::ArrayView<const Vector2> textureCoordinates;

GL::Buffer vertexBuffer;
vertexBuffer.setData(MeshTools::interleave(positions, textureCoordinates));

GL::Mesh mesh;
mesh.setCount(positions.size())
    .addVertexBuffer(vertexBuffer, 0, MyShader::Position{},
                                      MyShader::TextureCoordinates{});

It's often desirable to align data for one vertex on 32bit boundaries. To achieve that, you can specify gaps between the attributes:

Containers::ArrayView<const Vector4> positions;
Containers::ArrayView<const UnsignedShort> weights;
Containers::ArrayView<const Color3ub> vertexColors;

auto data = MeshTools::interleave(positions, weights, 2, vertexColors, 1);

All gap bytes are set zero. This way vertex stride is 24 bytes, without gaps it would be 21 bytes, causing possible performance loss.

template<class T, class ... U>
std::size_t Magnum::MeshTools::interleaveInto(Containers::ArrayView<char> buffer, const T& first, const U&... next)

Interleave vertex attributes into existing buffer.

Returns Filled buffer size

Unlike interleave() this function interleaves the data into existing buffer and leaves gaps untouched instead of zero-initializing them. This function can thus be used for interleaving data depending on runtime parameters. Expects that all arrays have the same size and the passed buffer is large enough to contain the interleaved data.

bool Magnum::MeshTools::isInterleaved(const Trade::MeshData& mesh) new in 2020.06

If the mesh data is interleaved.

Returns true if all attributes have the same positive stride and the difference between minimal and maximal offset is not larger than the stride, false otherwise. In particular, returns true also if the mesh has just one or no attributes.

While interleaved layouts technically may also have zero or negative strides, this case is currently not implemented and such layouts are treated as non-interleaved.

Containers::StridedArrayView2D<const char> Magnum::MeshTools::interleavedData(const Trade::MeshData& mesh) new in 2020.06

Type-erased view on interleaved mesh data.

Returns a 2D view on Trade::MeshData::vertexData() that spans all interleaved attributes. Expects that the mesh is interleaved.

First dimension of the returned view has size equal to vertex count and stride equal to original stride, second dimension size is the smallest possible byte count to cover all interleaved attributes, including any padding between them but not before or after.

Containers::StridedArrayView2D<char> Magnum::MeshTools::interleavedMutableData(Trade::MeshData& mesh) new in 2020.06

Mutable type-erased view on interleaved mesh data.

Same as interleavedData(), but returns a mutable view. Expects that the mesh is interleaved and vertex data is mutable.

Trade::MeshData Magnum::MeshTools::interleavedLayout(const Trade::MeshData& mesh, UnsignedInt vertexCount, Containers::ArrayView<const Trade::MeshAttributeData> extra = {}, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) new in 2020.06

Create an interleaved mesh layout.

Returns a Trade::MeshData instance with its vertex data allocated for vertexCount vertices containing attributes from both mesh and extra interleaved together. No data is actually copied, only an interleaved layout is created. If mesh is already interleaved according to isInterleaved() and InterleaveFlag::PreserveInterleavedAttributes is set in flags, keeps the attributes in the same layout, potentially extending them with extra. The extra attributes, if any, are interleaved together with existing attributes. Returned instance vertex data flags have both Trade::DataFlag::Mutable and Trade::DataFlag::Owned, so mutable attribute access is guaranteed.

For greater control over the layout you can also pass an empty Trade::MeshData instance and fill extra with attributes cherry-picked using Trade::MeshData::attributeData(UnsignedInt) const on an existing instance. By default the attributes are tightly packed, you can add arbitrary padding using instances constructed via Trade::MeshAttributeData::MeshAttributeData(Int). Example:

Containers::ArrayView<const Trade::MeshAttributeData> attributes =
    data.attributeData();

/* Take just positions and normals and add a four-byte padding in between */
Trade::MeshData layout = MeshTools::interleavedLayout(
    Trade::MeshData{MeshPrimitive::Triangles, 0}, vertexCount, {
        attributes[data.attributeId(Trade::MeshAttribute::Position)],
        Trade::MeshAttributeData{4},
        attributes[data.attributeId(Trade::MeshAttribute::Normal)]
    });

This function doesn't preserve index data information in any way, making the output non-indexed. If you want to preserve index data, create a new indexed instance with attribute and vertex data transferred from the returned instance:

Trade::MeshData layout =
    MeshTools::interleavedLayout(data, vertexCount, extraAttributes);

Trade::MeshIndexData indices;
Trade::MeshData indexed{data.primitive(),
    std::move(indexData), indices,
    layout.releaseVertexData(), layout.releaseAttributeData()};

This function will unconditionally allocate a new array to store all Trade::MeshAttributeData, use interleavedLayout(Trade::MeshData&&, UnsignedInt, Containers::ArrayView<const Trade::MeshAttributeData>, InterleaveFlags) to avoid that allocation.

All attributes in both mesh and extra are expected to not have an implementation-specific format, except for mesh attributes in case mesh is already interleaved, then the layout is untouched.

Trade::MeshData Magnum::MeshTools::interleavedLayout(const Trade::MeshData& mesh, UnsignedInt vertexCount, std::initializer_list<Trade::MeshAttributeData> extra, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::MeshData Magnum::MeshTools::interleavedLayout(Trade::MeshData&& mesh, UnsignedInt vertexCount, Containers::ArrayView<const Trade::MeshAttributeData> extra = {}, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) new in 2020.06

Create an interleaved mesh layout.

Compared to interleavedLayout(const Trade::MeshData&, UnsignedInt, Containers::ArrayView<const Trade::MeshAttributeData>, InterleaveFlags) this function can reuse the Trade::MeshAttributeData array from mesh instead of allocating a new one if there are no attributes passed in extra, the attribute array is owned by the mesh and InterleaveFlag::PreserveInterleavedAttributes is set in flags.

Trade::MeshData Magnum::MeshTools::interleavedLayout(Trade::MeshData&& mesh, UnsignedInt vertexCount, std::initializer_list<Trade::MeshAttributeData> extra, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::MeshData Magnum::MeshTools::interleave(const Trade::MeshData& mesh, Containers::ArrayView<const Trade::MeshAttributeData> extra = {}, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) new in 2020.06

Interleave mesh data.

Returns a copy of mesh with all attributes interleaved. The extra attributes, if any, are interleaved together with existing attributes (or, in case the attribute view is null, only the corresponding space for given attribute type is reserved, with memory left uninitialized). See the interleave(MeshPrimitive, const Trade::MeshIndexData&, Containers::ArrayView<const Trade::MeshAttributeData>) overload if you only have loose attributes and want to interleave them together.

The data layouting is done by interleavedLayout() with the flags parameter propagated to it, see its documentation for detailed behavior description. Note that offset-only Trade::MeshAttributeData instances are not supported in the extra array. Indices (if any) are kept as-is only if they're tightly packed and not with an implementation-specific type. Otherwise the behavior depends on presence of InterleaveFlag::PreserveStridedIndices.

Expects that each attribute in extra has either the same amount of elements as mesh vertex count or has none. This function will unconditionally make a copy of all data even if mesh is already interleaved and needs no change, use interleave(Trade::MeshData&&, Containers::ArrayView<const Trade::MeshAttributeData>, InterleaveFlags) to avoid that copy.

All attributes in both mesh and extra are expected to not have an implementation-specific format, except for mesh attributes in case data is already interleaved, then the layout is untouched.

Trade::MeshData Magnum::MeshTools::interleave(const Trade::MeshData& mesh, std::initializer_list<Trade::MeshAttributeData> extra, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::MeshData Magnum::MeshTools::interleave(Trade::MeshData&& mesh, Containers::ArrayView<const Trade::MeshAttributeData> extra = {}, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) new in 2020.06

Interleave mesh data.

Compared to interleave(const Trade::MeshData&, Containers::ArrayView<const Trade::MeshAttributeData>, InterleaveFlags) this function can transfer ownership of mesh index buffer (in case it is owned) and vertex buffer (in case it is owned, already interleaved, there's no extra attributes and InterleaveFlag::PreserveInterleavedAttributes is set in flags) to the returned instance instead of making copies of them.

Trade::MeshData Magnum::MeshTools::interleave(Trade::MeshData&& mesh, std::initializer_list<Trade::MeshAttributeData> extra, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::MeshData Magnum::MeshTools::interleave(MeshPrimitive primitive, const Trade::MeshIndexData& indices, Containers::ArrayView<const Trade::MeshAttributeData> attributes) new in Git master

Create an indexed interleaved mesh.

Creates a mesh data instance out of given indices and attributes. Usage example:

Containers::ArrayView<const UnsignedInt> indices = ;
Containers::ArrayView<const Vector3> positions = ;
Containers::ArrayView<const Vector3> normals = ;

Trade::MeshData mesh = MeshTools::interleave(
    MeshPrimitive::Triangles,
    Trade::MeshIndexData{indices}, {
        Trade::MeshAttributeData{Trade::MeshAttribute::Position, positions},
        Trade::MeshAttributeData{Trade::MeshAttribute::Normal, normals},
    });

The interleave(MeshPrimitive, Containers::ArrayView<const Trade::MeshAttributeData>) overload creates a non-indexed mesh. This function is a convenience shorthand for calling interleave(const Trade::MeshData&, Containers::ArrayView<const Trade::MeshAttributeData>, InterleaveFlags) with a Trade::MeshData instance created out of primitive and indices and vertex count matching attributes. If a particular attribute view is null, only the corresponding space for given attribute type is reserved, with memory left uninitialized. The attribute can also be a are a padding value created with Trade::MeshAttributeData::MeshAttributeData(Int), see documentation of interleavedLayout() for an example snippet.

Expects that attributes all have the same amount of elements or have none, there's at least one non-padding attribute, none of them have an implementation-specific format and none of them are offset-only Trade::MeshAttributeData instances. The indices, if present, are assumed to not have an implementation-specific type. Returned instance vertex and index data flags have both Trade::DataFlag::Mutable and Trade::DataFlag::Owned, so mutable attribute access is guaranteed.

Trade::MeshData Magnum::MeshTools::interleave(MeshPrimitive primitive, const Trade::MeshIndexData& indices, std::initializer_list<Trade::MeshAttributeData> attributes) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::MeshData Magnum::MeshTools::interleave(MeshPrimitive primitive, Containers::ArrayView<const Trade::MeshAttributeData> attributes) new in Git master

Create a non-indexed interleaved mesh.

Same as calling interleave(MeshPrimitive, const Trade::MeshIndexData&, Containers::ArrayView<const Trade::MeshAttributeData>) with a default-constructed Trade::MeshIndexData instance. See its documentation for more information and a usage example.

Trade::MeshData Magnum::MeshTools::interleave(MeshPrimitive primitive, std::initializer_list<Trade::MeshAttributeData> attributes) new in Git master

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::MeshData Magnum::MeshTools::owned(Trade::MeshData&& mesh)

Create an owned Trade::MeshData, if not already.

Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> Magnum::MeshTools::removeDuplicatesInPlace(const Containers::StridedArrayView2D<char>& data) new in 2020.06

Remove duplicate data from given array in-place.

Parameters
data in/out Data array. Unique items get moved to the front, preserving their relative order.
Returns Resulting index array and size of the unique prefix in the processed data array

Removes duplicate data from given array by comparing the second dimension of each item. Usage example:

Containers::ArrayView<Vector3i> data;

Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> unique =
    MeshTools::removeDuplicatesInPlace(Containers::arrayCast<2, char>(data));
data = data.prefix(unique.second());

For a visual example, assuming the following (two-dimensional) input, the function puts the four unique items at the front of the array, preserving their order. The returned index array then maps the unique back to the input locations, the second returned value is the count of unique items left in the input, thus four:

// Original input
{{172, 26}, {212, -183}, {172, 26}, {42, 13}, {112, 9}, {112, 9}, {212, -183}}

// After processing, contents following the unique prefix are left unspecified
{{172, 26}, {212, -183}, {42, 13}, {112, 9}, ...}

// Matching index array and number of unique items
{{0, 1, 0, 2, 3, 3, 1}, 4}

The second dimension is expected to be contiguous. A plain bit-exact matching is used, if you need fuzzy comparison for floating-point data, use removeDuplicatesFuzzyInPlace() instead. If you want to remove duplicate data from an already indexed array, use removeDuplicatesIndexedInPlace(const Containers::StridedArrayView1D<UnsignedInt>&, const Containers::StridedArrayView2D<char>&) instead. See removeDuplicates(const Containers::StridedArrayView2D<const char>&) for a variant that doesn't modify the input data in any way but instead returns an index array pointing to original data locations. Use removeDuplicatesInPlaceInto() to place the indices into existing memory instead of allocating a new array.

std::size_t Magnum::MeshTools::removeDuplicatesInPlaceInto(const Containers::StridedArrayView2D<char>& data, const Containers::StridedArrayView1D<UnsignedInt>& indices) new in 2020.06

Remove duplicate data from given array in-place into given output index array.

Parameters
data in/out Data array, duplicate items will be cut away with order preserved
indices out Where to put the resulting index array
Returns Size of unique prefix in the cleaned up data array

Like removeDuplicatesInPlace(), except that the index array is not allocated but put into indices instead. Expects that indices has the same size as data.

Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> Magnum::MeshTools::removeDuplicates(const Containers::StridedArrayView2D<const char>& data) new in 2020.06

Remove duplicate data from given array.

Parameters
data in Data array
Returns The resulting index array and count of unique items in the original data array

Compared to removeDuplicatesInPlace(const Containers::StridedArrayView2D<char>&) this function doesn't modify the input data array in any way but instead returns an index array pointing to original data locations. Use removeDuplicatesInto() to place the indices into existing memory instead of allocating a new array.

Compared to removeDuplicatesInPlace() the returned index buffer would look like this with the same input:

// Input that doesn't get modified
{{172, 26}, {212, -183}, {172, 26}, {42, 13}, {112, 9}, {112, 9}, {212, -183}}

// Matching index array that points back to the input, number of unique items
{{0, 1, 0, 3, 4, 4, 1}, 4}

std::size_t Magnum::MeshTools::removeDuplicatesInto(const Containers::StridedArrayView2D<const char>& data, const Containers::StridedArrayView1D<UnsignedInt>& indices) new in 2020.06

Remove duplicate data from given array into given output index array.

Parameters
data in Data array
indices out Where to put the resulting index array
Returns Count of unique items in the original data array

Compared to removeDuplicatesInPlaceInto(const Containers::StridedArrayView2D<char>&, const Containers::StridedArrayView1D<UnsignedInt>&) this function doesn't modify the input data array in any way but instead makes an index array pointing to original data locations.

std::size_t Magnum::MeshTools::removeDuplicatesIndexedInPlace(const Containers::StridedArrayView1D<UnsignedInt>& indices, const Containers::StridedArrayView2D<char>& data) new in 2020.06

Remove duplicates from indexed data in-place.

Parameters
indices in/out Index array, which will get remapped to list just unique data
data in/out Data array, duplicate items will be cut away with order preserved
Returns Size of unique prefix in the cleaned up data array

Compared to removeDuplicatesInPlace(const Containers::StridedArrayView2D<char>&) this variant is more suited for data that is already indexed as it works on the existing index array instead of allocating a new one.

std::size_t Magnum::MeshTools::removeDuplicatesIndexedInPlace(const Containers::StridedArrayView1D<UnsignedShort>& indices, const Containers::StridedArrayView2D<char>& data) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

std::size_t Magnum::MeshTools::removeDuplicatesIndexedInPlace(const Containers::StridedArrayView1D<UnsignedByte>& indices, const Containers::StridedArrayView2D<char>& data) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

std::size_t Magnum::MeshTools::removeDuplicatesIndexedInPlace(const Containers::StridedArrayView2D<char>& indices, const Containers::StridedArrayView2D<char>& data) new in 2020.06

Remove duplicates from indexed data in-place on a type-erased index array.

Expects that the second dimension of indices is contiguous and represents the actual 1/2/4-byte index type. Based on its size then calls one of the removeDuplicatesIndexedInPlace(const Containers::StridedArrayView1D<UnsignedInt>&, const Containers::StridedArrayView2D<char>&) etc. overloads.

Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> Magnum::MeshTools::removeDuplicatesFuzzyInPlace(const Containers::StridedArrayView2D<Float>& data, Float epsilon = Math::TypeTraits<Float>::epsilon()) new in 2020.06

Remove duplicate data from given array using fuzzy comparison in-place.

Parameters
data in/out Data array to process. Unique items get moved to the front, preserving their relative order.
epsilon in Epsilon value, data closer than this distance will be deduplicated
Returns Resulting index array and size of the unique prefix in the processed data array

Removes duplicate data from the array by collapsing them into buckets of size epsilon. First vector in given bucket is used, other ones are thrown away, no interpolation is done. Usage example:

Containers::ArrayView<Vector3> positions;

Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> unique =
    MeshTools::removeDuplicatesFuzzyInPlace(
        Containers::arrayCast<2, Float>(positions));
positions = positions.prefix(unique.second());

Assuming the following input and an epsilon of 0.01f, the function puts the five unique items at the front of the array, preserving their order. The returned index array then maps the unique back to the input locations, the second returned value is the count of unique items left in the input, thus five:

// Original input
{1.720f, 21.199f, 1.729f, 42.2f, 1.121f, 1.120f, 21.2f, 1.705f}

// After processing, contents following the unique prefix are left unspecified
{1.720f, 21.199f, 42.2f, 1.121f, 1.705f, ...}

// Matching index array and number of unique items
{{0, 1, 0, 2, 3, 3, 1, 4}, 5}

Note that this function is meant to be used for floating-point data (or generally with non-zero epsilon), for data where bit-exact matching is sufficient use removeDuplicatesInPlace(const Containers::StridedArrayView2D<char>&) instead. If you want to remove duplicate data from an already indexed array, use removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedInt>&, const Containers::StridedArrayView2D<Float>&, Float) and friends instead. Use removeDuplicatesFuzzyInPlaceInto() to place the indices into existing memory instead of allocating a new array.

If you want to remove duplicates in multiple incidental arrays, first remove duplicates in each array separately and then combine the resulting index arrays back into a single one using combineIndexedAttributes().

Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> Magnum::MeshTools::removeDuplicatesFuzzyInPlace(const Containers::StridedArrayView2D<Double>& data, Double epsilon = Math::TypeTraits<Double>::epsilon()) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

std::size_t Magnum::MeshTools::removeDuplicatesFuzzyInPlaceInto(const Containers::StridedArrayView2D<Float>& data, const Containers::StridedArrayView1D<UnsignedInt>& indices, Float epsilon = Math::TypeTraits<Float>::epsilon()) new in 2020.06

Remove duplicate data from given array using fuzzy comparison in-place into given output index array.

Parameters
data in/out Data array to process. Unique items get moved to the front, preserving their relative order.
indices out Where to put the resulting index array
epsilon in Epsilon value, data closer than this distance will be deduplicated
Returns Size of unique prefix in the cleaned up data array

Like removeDuplicatesFuzzyInPlace(), except that the index array is not allocated but put into indices instead. Expects that indices has the same size as data.

std::size_t Magnum::MeshTools::removeDuplicatesFuzzyInPlaceInto(const Containers::StridedArrayView2D<Double>& data, const Containers::StridedArrayView1D<UnsignedInt>& indices, Double epsilon = Math::TypeTraits<Double>::epsilon()) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class Vector>
std::vector<UnsignedInt> Magnum::MeshTools::removeDuplicates(std::vector<Vector>& data, typename Vector::Type epsilon = Math::TypeTraits<typename Vector::Type>::epsilon())

Remove duplicate data from a STL vector using fuzzy comparison in-place.

Parameters
data in/out Data array, duplicate items will be cut away with order preserved and the size shrunk to just the unique prefix
epsilon in Epsilon value, vertices closer than this distance will be melt together
Returns Resulting index array

Similar to the above, except that it's operating on a std::vector, which gets shrunk as a result (instead of the prefix size being returned). This variant is useful together with combineIndexedArrays() to remove duplicates in multiple incidental arrays — first remove duplicates in each array separately and then combine the resulting index arrays to single index array, and reorder the data accordingly:

std::vector<Vector3> positions;
std::vector<Vector2> texCoords;

std::vector<UnsignedInt> positionIndices = MeshTools::removeDuplicates(positions);
std::vector<UnsignedInt> texCoordIndices = MeshTools::removeDuplicates(texCoords);

std::vector<UnsignedInt> indices = MeshTools::combineIndexedArrays(
    std::make_pair(std::cref(positionIndices), std::ref(positions)),
    std::make_pair(std::cref(texCoordIndices), std::ref(texCoords))
);

std::size_t Magnum::MeshTools::removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedInt>& indices, const Containers::StridedArrayView2D<Float>& data, Float epsilon = Math::TypeTraits<Float>::epsilon()) new in 2020.06

Remove duplicates from indexed data using fuzzy comparison in-place.

Parameters
indices in/out Index array, which will get remapped to list just unique vertices
data in/out Data array to process. Unique items get moved to the front, preserving their relative order.
epsilon in Epsilon value, items closer than this distance will be deduplicated
Returns Size of unique prefix in the processed up data array

Compared to removeDuplicatesFuzzyInPlace(const Containers::StridedArrayView2D<Float>&, Float) this variant is more suited for data that is already indexed as it works on the existing index array instead of allocating a new one.

std::size_t Magnum::MeshTools::removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedShort>& indices, const Containers::StridedArrayView2D<Float>& data, Float epsilon = Math::TypeTraits<Float>::epsilon()) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

std::size_t Magnum::MeshTools::removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedByte>& indices, const Containers::StridedArrayView2D<Float>& data, Float epsilon = Math::TypeTraits<Float>::epsilon()) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

std::size_t Magnum::MeshTools::removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedInt>& indices, const Containers::StridedArrayView2D<Double>& data, Double epsilon = Math::TypeTraits<Double>::epsilon()) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

std::size_t Magnum::MeshTools::removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedShort>& indices, const Containers::StridedArrayView2D<Double>& data, Double epsilon = Math::TypeTraits<Double>::epsilon()) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

std::size_t Magnum::MeshTools::removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedByte>& indices, const Containers::StridedArrayView2D<Double>& data, Double epsilon = Math::TypeTraits<Double>::epsilon()) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

std::size_t Magnum::MeshTools::removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView2D<char>& indices, const Containers::StridedArrayView2D<Float>& data, Float epsilon = Math::TypeTraits<Float>::epsilon()) new in 2020.06

Remove duplicates from indexed data using fuzzy comparison in-place on a type-erased index array.

Calls removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedInt>&, const Containers::StridedArrayView2D<Float>&, Float) or the other overloads based on size of the second dimension of indices. Expects that the second dimension is contiguous and represents the actual 1/2/4-byte index type.

std::size_t Magnum::MeshTools::removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView2D<char>& indices, const Containers::StridedArrayView2D<Double>& data, Double epsilon = Math::TypeTraits<Double>::epsilon()) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Trade::MeshData Magnum::MeshTools::removeDuplicates(const Trade::MeshData& mesh) new in 2020.06

Remove mesh data duplicates.

Equivalent to calling removeDuplicatesInPlace() (or removeDuplicatesIndexedInPlace(), in case the mesh is indexed) on a mutable copy of every attribute and then putting the unique prefix and newly generated index buffer into a new Trade::MeshData instance. If the mesh is indexed, the original index type is preserved, otherwise the mesh gets MeshIndexType::UnsignedInt indices. The resulting mesh is always interleaved and owned, if the input is already interleaved attribute offsets and paddings are preserved. An index buffer, if present, is expected to not have an implementation-specific index type. All attributes are expected to not have an implementation-specific format.

In order to remove random padding values from the input and make the vertices suitable for fast in-place duplicate removal, this function unconditionally copies and interleaves the input vertex and index data.

Trade::MeshData Magnum::MeshTools::removeDuplicatesFuzzy(const Trade::MeshData& mesh, Float floatEpsilon = Math::TypeTraits<Float>::epsilon(), Double doubleEpsilon = Math::TypeTraits<Double>::epsilon()) new in 2020.06

Remove mesh data duplicates with fuzzy comparison for floating-point attributes.

Compared to removeDuplicates(const Trade::MeshData&), calls removeDuplicatesFuzzyInPlace() or removeDuplicatesFuzzyIndexedInPlace() on floating-point attributes. For attributes with a known range (such as Trade::MeshAttribute::Normal being always $ [-1, 1] $ in each direction) the floatEpsilon / doubleEpsilon is scaled appropriately, otherwise it's scaled to calculated value range.

template<class IndexType, class Vertex, class Interpolator>
void Magnum::MeshTools::subdivide(Containers::Array<IndexType>& indices, Containers::Array<Vertex>& vertices, Interpolator interpolator) new in 2020.06

Subdivide a mesh.

Template parameters
Vertex Vertex data type
Interpolator See the interpolator function parameter
Parameters
indices in/out Index array to operate on
vertices in/out Vertex array to operate on
interpolator Functor or function pointer which interpolates two adjacent vertices: Vertex interpolator(Vertex a, Vertex b)

Goes through all triangle faces and subdivides them into four new, enlarging the indices and vertices arrays as appropriate. Removing duplicate vertices in the mesh is up to the user.

template<class Vertex, class Interpolator>
void Magnum::MeshTools::subdivide(std::vector<UnsignedInt>& indices, std::vector<Vertex>& vertices, Interpolator interpolator)

Subdivide a mesh.

template<class IndexType, class Vertex, class Interpolator>
void Magnum::MeshTools::subdivideInPlace(const Containers::StridedArrayView1D<IndexType>& indices, const Containers::StridedArrayView1D<Vertex>& vertices, Interpolator interpolator) new in 2020.06

Subdivide a mesh in-place.

Template parameters
Vertex Vertex data type
Interpolator See the interpolator function parameter
Parameters
indices in/out Index array to operate on
vertices in/out Vertex array to operate on
interpolator Functor or function pointer which interpolates two adjacent vertices: Vertex interpolator(Vertex a, Vertex b)

Assuming the original mesh has $ i $ indices and $ v $ vertices, expects the indices array to have a size of $ 4i $ (as every triangle face would be divided into four new), with the original indices being in the first quarter, and the vertices array to have a size of $ v + i $ (as every original triangle face will get three new vertices). Removing duplicate vertices in the mesh is up to the user.

Generally, for $ k $ subsequent subdivisions, the resulting index and vertex array sizes $ i' $ and $ v' $ will be as following. To subdivide the mesh multiple times in-place, pass correctly sized prefix of the arrays to each step.

\[ \begin{array}{rcl} i' & = & 4^k i \\ v' & = & v + \frac{1}{3}(i' - i) \end{array} \]

template<class IndexType, class Vertex, class Interpolator>
void Magnum::MeshTools::subdivideInPlace(const Containers::ArrayView<IndexType>& indices, const Containers::StridedArrayView1D<Vertex>& vertices, Interpolator interpolator) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::tipsifyInPlace(const Containers::StridedArrayView1D<UnsignedInt>& indices, UnsignedInt vertexCount, std::size_t cacheSize)

Tipsify the mesh in-place.

Parameters
indices in/out Indices array to operate on
vertexCount in Vertex count
cacheSize in Post-transform vertex cache size

Optimizes the mesh for vertex-bound applications by rearranging its index array for beter usage of post-transform vertex cache. Algorithm used: Pedro V. Sander, Diego Nehab, and Joshua Barczak — Fast Triangle Reordering for Vertex Locality and Reduced Overdraw, SIGGRAPH 2007, https://gfx.cs.princeton.edu/pubs/Sander_2007_%3eTR/tipsy.pdf.

void Magnum::MeshTools::tipsifyInPlace(const Containers::StridedArrayView1D<UnsignedShort>& indices, UnsignedInt vertexCount, std::size_t cacheSize) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::tipsifyInPlace(const Containers::StridedArrayView1D<UnsignedByte>& indices, UnsignedInt vertexCount, std::size_t cacheSize) new in 2020.06

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::MeshTools::tipsify(std::vector<UnsignedInt>& indices, UnsignedInt vertexCount, std::size_t cacheSize)

Tipsify the mesh in-place.

template<class T, class U>
void Magnum::MeshTools::transformVectorsInPlace(const Math::Matrix4<T>& matrix, U&& vectors)

Transform vectors in-place using given transformation.

Usable for one-time mesh transformations that would otherwise negatively affect dependent objects, such as (uneven) scaling. Accepts any forward-iterable type with compatible vector type as vectors. Expects that Quaternion is normalized, no further requirements are for other transformation representations.

Unlike in transformPointsInPlace(), the transformation does not involve translation.

Example usage:

std::vector<Vector3> vectors;
auto transformation = Quaternion::rotation(35.0_degf, Vector3::yAxis());
MeshTools::transformVectorsInPlace(transformation, vectors);

template<class T, class U>
void Magnum::MeshTools::transformVectorsInPlace(const Math::Matrix3<T>& matrix, U&& vectors)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class T, class U>
void Magnum::MeshTools::transformVectorsInPlace(const Math::Complex<T>& complex, U&& vectors)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class T, class U>
void Magnum::MeshTools::transformVectorsInPlace(const Math::Quaternion<T>& normalizedQuaternion, U&& vectors)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class T, class U>
U Magnum::MeshTools::transformVectors(const T& transformation, U vectors)

Transform vectors using given transformation.

Returns transformed vectors instead of modifying them in-place. See transformVectorsInPlace() for more information.

template<class T, class U>
void Magnum::MeshTools::transformPointsInPlace(const Math::Matrix4<T>& matrix, U&& points)

Transform points in-place using given transformation.

Usable for one-time mesh transformations that would otherwise negatively affect dependent objects, such as (uneven) scaling. Accepts any forward-iterable type with compatible vector type as vectors. Expects that DualQuaternion is normalized, no further requirements are for other transformation representations.

Unlike in transformVectorsInPlace(), the transformation also involves translation.

Example usage:

std::vector<Vector3> points;
auto transformation =
    DualQuaternion::rotation(35.0_degf, Vector3::yAxis())*
    DualQuaternion::translation({0.5f, -1.0f, 3.0f});
MeshTools::transformPointsInPlace(transformation, points);

template<class T, class U>
void Magnum::MeshTools::transformPointsInPlace(const Math::Matrix3<T>& matrix, U&& points)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class T, class U>
void Magnum::MeshTools::transformPointsInPlace(const Math::DualComplex<T>& dualComplex, U&& points)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class T, class U>
void Magnum::MeshTools::transformPointsInPlace(const Math::DualQuaternion<T>& normalizedDualQuaternion, U&& points)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class T, class U>
U Magnum::MeshTools::transformPoints(const T& transformation, U vectors)

Transform points using given transformation.

Returns transformed points instead of modifying them in-place. See transformPointsInPlace() for more information.

Trade::MeshData Magnum::MeshTools::transform2D(const Trade::MeshData& mesh, const Matrix3& transformation, UnsignedInt id = 0, Int morphTargetId = -1, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) new in Git master

Transform 2D positions in a mesh data.

Expects that the mesh contains a two-dimensional Trade::MeshAttribute::Position with index id (and in morph target morphTargetId if not -1) and that the attribute does not have an implementation-specific format. To avoid data loss with packed types, the positions are converted to VertexFormat::Vector2 if not already. In that case the data layouting is done by interleavedLayout() with the flags parameter propagated to it, see its documentation for detailed behavior description. Other attributes, position attributes other than id or with different morphTargetId, and indices (if any) are passed through untouched.

See also transform2D(Trade::MeshData&&, const Matrix3&, UnsignedInt, Int, InterleaveFlags) for a potentially more efficient operation instead of always performing a full copy, you can also do an in-place transformation using transform2DInPlace().

Trade::MeshData Magnum::MeshTools::transform2D(Trade::MeshData&& mesh, const Matrix3& transformation, UnsignedInt id = 0, Int morphTargetId = -1, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) new in Git master

Transform 2D positions in a mesh data.

Compared to transform2D(const Trade::MeshData&, const Matrix3&, UnsignedInt, Int, InterleaveFlags) this function can can perform the transformation in-place, transferring the data ownership to the returned instance, if both vertex and index data is owned, vertex data is mutable and the positions with index id in morphTargetId are VertexFormat::Vector2.

void Magnum::MeshTools::transform2DInPlace(Trade::MeshData& mesh, const Matrix3& transformation, UnsignedInt id = 0, Int morphTargetId = -1) new in Git master

Transform 2D positions in a mesh data in-place.

Expects that the mesh has mutable vertex data and contains a two-dimensional Trade::MeshAttribute::Position with index id (and in morph target morphTargetId if not -1). To avoid data loss with packed types, the in-place operation requires the position type to be VertexFormat::Vector2 — if you can't guarantee that, use transform2D() instead. Other attributes, position attributes other than id or with different morphTargetId, and indices (if any) are left untouched.

Trade::MeshData Magnum::MeshTools::transform3D(const Trade::MeshData& mesh, const Matrix4& transformation, UnsignedInt id = 0, Int morphTargetId = -1, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) new in Git master

Transform 3D positions, normals, tangents and bitangents in a mesh data.

Expects that the mesh contains a three-dimensional Trade::MeshAttribute::Position with index id (and in morph target morphTargetId if not -1). If Trade::MeshAttribute::Normal, Trade::MeshAttribute::Tangent or Trade::MeshAttribute::Bitangent with index id in morphTargetId are present as well, those get transformed with Matrix4::normalMatrix() extracted out of transformation. All these attributes are expected to not have an implementation-specific format. To avoid data loss with packed types, the positions, normals and bitangents are converted to VertexFormat::Vector3 if not already, tangents to either VertexFormat::Vector3 or VertexFormat::Vector4 if not already. In that case the data layouting is done by interleavedLayout() with the flags parameter propagated to it, see its documentation for detailed behavior description. Other attributes, additional position/TBN attributes other than id or with different morphTargetId, and indices (if any) are passed through untouched.

If you're applying negative scaling, you may want to also flip face winding afterwards using flipFaceWindingInPlace().

See also transform3D(Trade::MeshData&&, const Matrix4&, UnsignedInt, Int, InterleaveFlags) for a potentially more efficient operation instead of always performing a full copy, you can also do an in-place transformation using transform3DInPlace().

Trade::MeshData Magnum::MeshTools::transform3D(const Trade::MeshData& mesh, const Matrix4& transformation, UnsignedInt id, InterleaveFlags flags)

Transform 3D positions, normals, tangents and bitangents in a mesh data.

Trade::MeshData Magnum::MeshTools::transform3D(Trade::MeshData&& mesh, const Matrix4& transformation, UnsignedInt id = 0, Int morphTargetId = -1, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) new in Git master

Transform 3D positions, normals, tangenta and bitangents in a mesh data.

Compared to transform3D(const Trade::MeshData&, const Matrix4&, UnsignedInt, Int, InterleaveFlags) this function can can perform the transformation in-place, transferring the data ownership to the returned instance, if both vertex and index data is owned, vertex data is mutable, positions, normals and bitangents with index id in morphTargetId (if present) are VertexFormat::Vector3 and tangents with index id in morphTargetId (if present) are either VertexFormat::Vector3 or VertexFormat::Vector4.

Trade::MeshData Magnum::MeshTools::transform3D(Trade::MeshData&& mesh, const Matrix4& transformation, UnsignedInt id, InterleaveFlags flags)

Transform 3D positions, normals, tangenta and bitangents in a mesh data.

void Magnum::MeshTools::transform3DInPlace(Trade::MeshData& mesh, const Matrix4& transformation, UnsignedInt id = 0, Int morphTargetId = -1) new in Git master

Transform 3D positions, normals, tangents and bitangents in a mesh data in-place.

Expects that the mesh has mutable vertex data and contains at least a three-dimensional Trade::MeshAttribute::Position with index id (and in morph target morphTargetId if not -1); optionally also Trade::MeshAttribute::Normal, Trade::MeshAttribute::Tangent or Trade::MeshAttribute::Bitangent with index id in morphTargetId, those get transformed with Matrix4::normalMatrix() extracted out of transformation. To avoid data loss with packed types, the in-place operation requires the position, normal and bitangent types to be VertexFormat::Vector3 and tangent either VertexFormat::Vector3 or VertexFormat::Vector4 — if you can't guarantee that, use transform3D() instead. Other attributes, position/TBN attributes other than id or with different morphTargetId, and indices (if any) are left untouched.

Trade::MeshData Magnum::MeshTools::transformTextureCoordinates2D(const Trade::MeshData& mesh, const Matrix3& transformation, UnsignedInt id = 0, Int morphTargetId = -1, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) new in Git master

Transform 2D texture coordinates in a mesh data.

Expects that the mesh contains a Trade::MeshAttribute::TextureCoordinates with index id (and in morph target morphTargetId if not -1). To avoid data loss with packed types, the coordinattes are converted to VertexFormat::Vector2 if not already. In that case the data layouting is done by interleavedLayout() with the flags parameter propagated to it, see its documentation for detailed behavior description. Other attributes, texture coordinate attributes other than id or with different morphTargetId, and indices (if any) are passed through untouched.

See also transformTextureCoordinates2D(Trade::MeshData&&, const Matrix3&, UnsignedInt, Int, InterleaveFlags) for a potentially more efficient operation instead of always performing a full copy, you can also do an in-place transformation using transformTextureCoordinates2DInPlace().

Trade::MeshData Magnum::MeshTools::transformTextureCoordinates2D(Trade::MeshData&& mesh, const Matrix3& transformation, UnsignedInt id = 0, Int morphTargetId = -1, InterleaveFlags flags = InterleaveFlag::PreserveInterleavedAttributes) new in Git master

Transform 2D texture coordinates in a mesh data.

Compared to transformTextureCoordinates2D(const Trade::MeshData&, const Matrix3&, UnsignedInt, Int, InterleaveFlags) this function can can perform the transformation in-place, transferring the data ownership to the returned instance, if both vertex and index data is owned, vertex data is mutable and the coordinates with index id in morphTargetId are VertexFormat::Vector2.

void Magnum::MeshTools::transformTextureCoordinates2DInPlace(Trade::MeshData& mesh, const Matrix3& transformation, UnsignedInt id = 0, Int morphTargetId = -1) new in Git master

Transform 2D texture coordinates in a mesh data in-place.

Expects that the mesh has mutable vertex data and contains a Trade::MeshAttribute::TextureCoordinates with index id (and in morph target morphTargetId if not -1) and that the attribute does not have an implementation-specific format. To avoid data loss with packed types, the in-place operation requires the coordinate type to be VertexFormat::Vector2 — if you can't guarantee that, use transformTextureCoordinates2D() instead. Other attributes, texture coordinate attributes other than id or with different morphTargetId, and indices (if any) are passed through untouched.