Browse Source

MeshTools: doc++

Not too great yet, but at least the most common operations have an
example snippet that shows real use, instead of jumping off a cliff
right into the most detailed description.
pull/659/head
Vladimír Vondruš 2 years ago
parent
commit
f237bb3c9c
  1. 46
      doc/snippets/MeshTools.cpp
  2. 16
      src/Magnum/MeshTools/Combine.h
  3. 3
      src/Magnum/MeshTools/Compile.h
  4. 11
      src/Magnum/MeshTools/CompressIndices.h
  5. 31
      src/Magnum/MeshTools/Concatenate.h
  6. 12
      src/Magnum/MeshTools/Filter.h
  7. 4
      src/Magnum/MeshTools/GenerateIndices.h
  8. 58
      src/Magnum/MeshTools/RemoveDuplicates.h
  9. 1
      src/Magnum/MeshTools/Tipsify.h
  10. 17
      src/Magnum/MeshTools/Transform.h

46
doc/snippets/MeshTools.cpp

@ -29,6 +29,7 @@
#include "Magnum/Math/Color.h"
#include "Magnum/Math/FunctionsBatch.h"
#include "Magnum/MeshTools/Combine.h"
#include "Magnum/MeshTools/CompressIndices.h"
#include "Magnum/MeshTools/Concatenate.h"
#include "Magnum/MeshTools/Duplicate.h"
@ -45,6 +46,8 @@
#include "Magnum/MeshTools/CombineIndexedArrays.h"
#endif
#define DOXYGEN_ELLIPSIS(...) __VA_ARGS__
using namespace Magnum;
using namespace Magnum::Math::Literals;
@ -53,6 +56,17 @@ using namespace Magnum::Math::Literals;
avoid -Wmisssing-prototypes */
void mainMeshTools();
void mainMeshTools() {
{
Trade::MeshData mesh{{}, 0};
/* [combineFaceAttributes] */
Containers::ArrayView<const Color3> faceColors = DOXYGEN_ELLIPSIS({});
Trade::MeshData meshWithFaceColors = MeshTools::combineFaceAttributes(mesh, {
Trade::MeshAttributeData{Trade::MeshAttribute::Color, faceColors}
});
/* [combineFaceAttributes] */
}
#ifdef MAGNUM_BUILD_DEPRECATED
{
CORRADE_IGNORE_DEPRECATED_PUSH
@ -96,6 +110,27 @@ CORRADE_IGNORE_DEPRECATED_POP
}
#endif
{
/* [concatenate] */
Trade::MeshData sphere = DOXYGEN_ELLIPSIS(Trade::MeshData{{}, 0});
Trade::MeshData cube = DOXYGEN_ELLIPSIS(Trade::MeshData{{}, 0});
Trade::MeshData cylinder = DOXYGEN_ELLIPSIS(Trade::MeshData{{}, 0});
Trade::MeshData primitives = MeshTools::concatenate({sphere, cube, cylinder});
/* [concatenate] */
/* [concatenate-offsets] */
UnsignedInt sphereIndexOffset = 0;
UnsignedInt sphereVertexOffset = 0;
UnsignedInt cubeIndexOffset = sphereIndexOffset + sphere.indexCount(),
cubeVertexOffset = sphereVertexOffset + sphere.vertexCount();
UnsignedInt cylinderIndexOffset = cubeIndexOffset + cube.indexCount(),
cylinderVertexOffset = cubeVertexOffset + cube.vertexCount();
/* [concatenate-offsets] */
static_cast<void>(cylinderIndexOffset);
static_cast<void>(cylinderVertexOffset);
}
{
/* [generateFlatNormals] */
Containers::ArrayView<UnsignedInt> indices;
@ -163,6 +198,17 @@ data = data.prefix(unique.second());
/* [removeDuplicates] */
}
{
/* [removeDuplicatesFuzzy] */
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());
/* [removeDuplicatesFuzzy] */
}
#ifdef MAGNUM_BUILD_DEPRECATED
{
CORRADE_IGNORE_DEPRECATED_PUSH

16
src/Magnum/MeshTools/Combine.h

@ -114,17 +114,27 @@ indexed, it's assumed to have the data unique; if it's not indexed, it's first
made unique using @ref 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 @ref 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 @ref Trade::MeshData first. See its
documentation for a usage example.
@see @ref isInterleaved(), @ref isMeshIndexTypeImplementationSpecific(),
@ref isVertexFormatImplementationSpecific()
*/
MAGNUM_MESHTOOLS_EXPORT Trade::MeshData combineFaceAttributes(const Trade::MeshData& mesh, const Trade::MeshData& faceAttributes);
/**
@overload
@brief Combine per-face attributes into an existing mesh
@m_since{2020,06}
Same as above with @p faceAttributes wrapped in a @ref Trade::MeshData with
@ref MeshPrimitive::Faces and no index buffer. Same as in the above case,
Wraps @p faceAttributes in a @ref Trade::MeshData with @ref MeshPrimitive::Faces
and no index buffer and calls @ref combineFaceAttributes(const Trade::MeshData&, const Trade::MeshData&).
Example usage --- adding a per-face color to an existing mesh:
@snippet MeshTools.cpp combineFaceAttributes
Same as with @ref combineFaceAttributes(const Trade::MeshData&, const Trade::MeshData&),
@p faceAttributes is expected to be interleaved. Note that offset-only
@ref Trade::MeshAttributeData instances are not supported in the
@p faceAttributes array.

3
src/Magnum/MeshTools/Compile.h

@ -321,7 +321,8 @@ Useful to get subsequently fed to
@ref Shaders::FlatGL::Configuration::setJointCount() or to
@ref Shaders::FlatGL::setPerVertexJointCount() if
@ref Shaders::FlatGL::Flag::DynamicPerVertexJointCount is enabled, and
similarly with other builtin shaders.
similarly with other builtin shaders. See @ref shaders-usage-skinning for a
high-level introduction.
@note This function is available only if Magnum is compiled with
@ref MAGNUM_TARGET_GL enabled (done by default). See @ref building-features

11
src/Magnum/MeshTools/CompressIndices.h

@ -80,7 +80,7 @@ A negative @p offset value will do an operation inverse to the above. See also
operation directly on a @ref Trade::MeshData instance.
The @p atLeast parameter is expected to not be an implementation-specific type.
@see @ref isMeshIndexTypeImplementationSpecific()
@see @ref isMeshIndexTypeImplementationSpecific(), @ref Math::castInto()
*/
MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0);
@ -152,9 +152,12 @@ MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<char>, MeshIndexType>
Does the same as @ref compressIndices(const Containers::StridedArrayView2D<const char>&, MeshIndexType, Long),
but together with adjusting vertex attribute offsets in the passed
@ref Trade::MeshData instance. This function will unconditionally make a copy
of all vertex data, use @ref compressIndices(Trade::MeshData&&, MeshIndexType)
to avoid that copy.
@ref Trade::MeshData instance. By default the function will make a copy of all
vertex data, pass a r-value in order to pick the
@ref compressIndices(Trade::MeshData&&, MeshIndexType) overload and avoid the
copy. The function is by default using at least a 16-bit index type because
while @ref 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 @p atLeast
parameter is expected to not be implementation-specific type.

31
src/Magnum/MeshTools/Concatenate.h

@ -51,16 +51,27 @@ namespace Implementation {
@param flags Flags to pass to @ref interleavedLayout()
@m_since{2020,06}
The returned mesh contains vertices from all meshes concatenated together. If
any mesh is indexed (expected to not have an implementation-specific index
type), the resulting mesh is indexed as well, with indices adjusted for vertex
offsets of particular meshes. The behavior is undefined if any mesh has indices
out of range for its particular vertex count. Meshes with
@ref MeshPrimitive::LineStrip, @ref MeshPrimitive::LineLoop,
@ref MeshPrimitive::TriangleStrip and @ref MeshPrimitive::TriangleFan can't be
concatenated --- use @ref generateIndices() to turn them into
@ref MeshPrimitive::Lines or @ref MeshPrimitive::Triangles first. The @p meshes
array is expected to have at least one item.
Returns a mesh that contains index and vertex data from all input meshes
concatenated together. Usage example:
@snippet MeshTools.cpp concatenate
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.
@snippet MeshTools.cpp concatenate-offsets
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 @ref MeshPrimitive::LineStrip,
@ref MeshPrimitive::LineLoop, @ref MeshPrimitive::TriangleStrip and
@ref MeshPrimitive::TriangleFan can't be concatenated --- use
@ref generateIndices() to turn them into @ref MeshPrimitive::Lines or
@ref MeshPrimitive::Triangles first. The @p 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

12
src/Magnum/MeshTools/Filter.h

@ -66,9 +66,9 @@ present, is left untouched. Attributes from the list that are not present in
@p 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 the
@ref filterOnlyAttributes(const Trade::MeshData&, Containers::ArrayView<const UnsignedInt>)
overload and pick attributes by their IDs instead.
are kept --- if you want a different behavior, use
@ref 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
@ -94,9 +94,9 @@ present, is left untouched. Attributes from the list that are not present in
@p 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 the
@ref filterOnlyAttributes(const Trade::MeshData&, Containers::ArrayView<const UnsignedInt>)
overload and pick attributes by their IDs instead.
are removed --- if you want a different behavior, use
@ref 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

4
src/Magnum/MeshTools/GenerateIndices.h

@ -506,7 +506,7 @@ MAGNUM_MESHTOOLS_EXPORT void generateQuadIndicesInto(const Containers::StridedAr
MAGNUM_MESHTOOLS_EXPORT void generateQuadIndicesInto(const Containers::StridedArrayView1D<const Vector3>& positions, const Containers::StridedArrayView1D<const UnsignedByte>& quads, const Containers::StridedArrayView1D<UnsignedByte>& output);
/**
@brief Convert a mesh to plain indexed lines or triangles
@brief Convert a mesh to a plain indexed one
@m_since{2020,06}
If @p mesh is one of @ref MeshPrimitive::LineStrip,
@ -535,7 +535,7 @@ avoid that copy.
MAGNUM_MESHTOOLS_EXPORT Trade::MeshData generateIndices(const Trade::MeshData& mesh);
/**
@brief Convert a mesh to plain indexed lines or triangles
@brief Convert a mesh to a plain indexed one
@m_since{2020,06}
Compared to @ref generateIndices(const Trade::MeshData&) this function can

58
src/Magnum/MeshTools/RemoveDuplicates.h

@ -55,20 +55,21 @@ namespace Magnum { namespace MeshTools {
@m_since{2020,06}
Removes duplicate data from given array by comparing the second dimension of
each item, the second dimension is expected to be contiguous. A plain bit-exact
each item. Usage example:
@snippet MeshTools.cpp removeDuplicates
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
@ref removeDuplicatesFuzzyInPlace() instead. If you want to remove duplicate
data from an already indexed array, use
@ref removeDuplicatesIndexedInPlace(const Containers::StridedArrayView1D<UnsignedInt>&, const Containers::StridedArrayView2D<char>&)
instead. Usage example:
@snippet MeshTools.cpp removeDuplicates
See @ref removeDuplicates(const Containers::StridedArrayView2D<const char>&)
instead. See @ref 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.
@see @ref Corrade::Containers::StridedArrayView::isContiguous(),
@ref removeDuplicatesInPlaceInto()
an index array pointing to original data locations. Use
@ref removeDuplicatesInPlaceInto() to place the indices into existing memory
instead of allocating a new array.
@see @relativeref{Corrade,Containers::StridedArrayView::isContiguous()}
*/
MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicatesInPlace(const Containers::StridedArrayView2D<char>& data);
@ -80,8 +81,9 @@ MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<UnsignedInt>, std::si
@return Size of unique prefix in the cleaned up @p data array
@m_since{2020,06}
Same as above, except that the index array is not allocated but put into
@p indices instead. Expects that @p indices has the same size as @p data.
Like @ref removeDuplicatesInPlace(), except that the index array is not
allocated but put into @p indices instead. Expects that @p indices has the same
size as @p data.
@see @ref removeDuplicatesInto()
*/
MAGNUM_MESHTOOLS_EXPORT std::size_t removeDuplicatesInPlaceInto(const Containers::StridedArrayView2D<char>& data, const Containers::StridedArrayView1D<UnsignedInt>& indices);
@ -95,7 +97,9 @@ MAGNUM_MESHTOOLS_EXPORT std::size_t removeDuplicatesInPlaceInto(const Containers
Compared to @ref 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.
returns an index array pointing to original data locations. Use
@ref removeDuplicatesInto() to place the indices into existing memory instead
of allocating a new array.
*/
MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicates(const Containers::StridedArrayView2D<const char>& data);
@ -162,14 +166,17 @@ MAGNUM_MESHTOOLS_EXPORT std::size_t removeDuplicatesIndexedInPlace(const Contain
Removes duplicate data from the array by collapsing them into buckets of size
@p epsilon. First vector in given bucket is used, other ones are thrown away,
no interpolation is done. Note that this function is meant to be used for
floating-point data (or generally with non-zero @p epsilon), for data where
bit-exact matching is sufficient use @ref removeDuplicatesInPlace(const Containers::StridedArrayView2D<char>&)
instead.
no interpolation is done. Usage example:
If you want to remove duplicate data from an already indexed array, use
@ref removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedInt>&, const Containers::StridedArrayView2D<Float>&, Float)
and friends instead.
@snippet MeshTools.cpp removeDuplicatesFuzzy
Note that this function is meant to be used for floating-point data (or
generally with non-zero @p epsilon), for data where bit-exact matching is
sufficient use @ref removeDuplicatesInPlace(const Containers::StridedArrayView2D<char>&)
instead. If you want to remove duplicate data from an already indexed array,
use @ref removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedInt>&, const Containers::StridedArrayView2D<Float>&, Float)
and friends instead. Use @ref 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
@ -193,8 +200,9 @@ MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<UnsignedInt>, std::si
@return Size of unique prefix in the cleaned up @p data array
@m_since{2020,06}
Same as above, except that the index array is not allocated but put into
@p indices instead. Expects that @p indices has the same size as @p data.
Like @ref removeDuplicatesFuzzyInPlace(), except that the index array is not
allocated but put into @p indices instead. Expects that @p indices has the same
size as @p data.
*/
MAGNUM_MESHTOOLS_EXPORT std::size_t removeDuplicatesFuzzyInPlaceInto(const Containers::StridedArrayView2D<Float>& data, const Containers::StridedArrayView1D<UnsignedInt>& indices, Float epsilon = Math::TypeTraits<Float>::epsilon());
@ -277,10 +285,10 @@ MAGNUM_MESHTOOLS_EXPORT std::size_t removeDuplicatesFuzzyIndexedInPlace(const Co
@brief Remove duplicates from indexed data using fuzzy comparison in-place on a type-erased index array
@m_since{2020,06}
Expects that the second dimension of @p indices is contiguous and represents
the actual 1/2/4-byte index type. Based on its size then calls
@ref removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedInt>&, const Containers::StridedArrayView2D<Float>&, Float)
or the other overloads.
Calls @ref removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView1D<UnsignedInt>&, const Containers::StridedArrayView2D<Float>&, Float)
or the other overloads based on size of the second dimension of @p indices.
Expects that the second dimension is contiguous and represents the actual
1/2/4-byte index type.
*/
MAGNUM_MESHTOOLS_EXPORT std::size_t removeDuplicatesFuzzyIndexedInPlace(const Containers::StridedArrayView2D<char>& indices, const Containers::StridedArrayView2D<Float>& data, Float epsilon = Math::TypeTraits<Float>::epsilon());

1
src/Magnum/MeshTools/Tipsify.h

@ -56,6 +56,7 @@ array for beter usage of post-transform vertex cache. Algorithm used:
for Vertex Locality and Reduced Overdraw, SIGGRAPH 2007,
https://gfx.cs.princeton.edu/pubs/Sander_2007_%3eTR/tipsy.pdf*.
@todo Ability to compute vertex count automatically
@see @relativeref{Trade,MeshOptimizerSceneConverter}
*/
MAGNUM_MESHTOOLS_EXPORT void tipsifyInPlace(const Containers::StridedArrayView1D<UnsignedInt>& indices, UnsignedInt vertexCount, std::size_t cacheSize);

17
src/Magnum/MeshTools/Transform.h

@ -152,12 +152,12 @@ template<class T, class U> U transformPoints(const T& transformation, U vectors)
Expects that the mesh contains a two-dimensional
@ref Trade::MeshAttribute::Position with index @p id (and in morph target
@p morphTargetId if not @cpp -1 @ce) and that the attribute does not have an
implementation-specific format. To avoid data loss with packed types, the positions are converted to @ref VertexFormat::Vector2 if not
already. In that case the data layouting is done by @ref interleavedLayout()
with the @p flags parameter propagated to it, see its documentation for
detailed behavior description. Other attributes, position attributes other than
@p id or with different @p morphTargetId, and indices (if any) are passed
through untouched.
implementation-specific format. To avoid data loss with packed types, the
positions are converted to @ref VertexFormat::Vector2 if not already. In that
case the data layouting is done by @ref interleavedLayout() with the @p flags
parameter propagated to it, see its documentation for detailed behavior
description. Other attributes, position attributes other than @p id or with
different @p morphTargetId, and indices (if any) are passed through untouched.
See also @ref transform2D(Trade::MeshData&&, const Matrix3&, UnsignedInt, Int, InterleaveFlags)
for a potentially more efficient operation instead of always performing a full
@ -237,6 +237,11 @@ behavior description. Other attributes, additional position/TBN attributes
other than @p id or with different @p 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 @ref flipFaceWindingInPlace().
@todoc reference the MeshData flipFaceWindingInPlace variant once it exists
See also @ref 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 @ref transform3DInPlace().

Loading…
Cancel
Save