Magnum::MaterialTools namespace new in Git master

Material tools.

Tools for converting, optimizing, filtering and merging materials.

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

find_package(Magnum REQUIRED MaterialTools)

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

See Downloading and building and Usage with CMake for more information.

Enums

enum MergeConflicts: UnsignedInt { Fail, KeepFirstIfSameType, KeepFirstIgnoreType } new in Git master
Material merge conflict resolution.
enum class PhongToPbrMetallicRoughnessFlag { KeepOriginalAttributes = 1 << 0, DropUnconvertibleAttributes = 1 << 1, DropUnconvertableAttributes = DropUnconvertibleAttributes deprecated in Git master, FailOnUnconvertibleAttributes = (1 << 2)|DropUnconvertibleAttributes, FailOnUnconvertableAttributes = FailOnUnconvertibleAttributes deprecated in Git master } new in Git master
Phong to PBR metallic/roughness conversion flag.

Typedefs

using PhongToPbrMetallicRoughnessFlags = Containers::EnumSet<PhongToPbrMetallicRoughnessFlag> new in Git master
Phong to PBR conversion flags.

Functions

auto copy(const Trade::MaterialData& material) -> Trade::MaterialData new in Git master
Make an owned copy of the material.
auto copy(Trade::MaterialData&& material) -> Trade::MaterialData new in Git master
Make a material with owned data.
auto filterAttributes(const Trade::MaterialData& material, Containers::BitArrayView attributesToKeep, Trade::MaterialTypes typesToKeep = ~Trade::MaterialTypes{}) -> Trade::MaterialData new in Git master
Filter material attributes.
auto filterLayers(const Trade::MaterialData& material, Containers::BitArrayView layersToKeep, Trade::MaterialTypes typesToKeep = ~Trade::MaterialTypes{}) -> Trade::MaterialData new in Git master
Filter material layers.
auto filterAttributesLayers(const Trade::MaterialData& material, Containers::BitArrayView attributesToKeep, Containers::BitArrayView layersToKeep, Trade::MaterialTypes typesToKeep = ~Trade::MaterialTypes{}) -> Trade::MaterialData new in Git master
Filter material attributes and layers.
auto merge(const Trade::MaterialData& first, const Trade::MaterialData& second, MergeConflicts conflicts = MergeConflicts::Fail) -> Containers::Optional<Trade::MaterialData> new in Git master
Merge two materials.
auto phongToPbrMetallicRoughness(const Trade::MaterialData& material, PhongToPbrMetallicRoughnessFlags flags = {}) -> Containers::Optional<Trade::MaterialData> new in Git master
Convert a Phong material to PBR metallic/roughness.
auto removeDuplicatesInPlace(const Containers::Iterable<Trade::MaterialData>& materials) -> Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> new in Git master
Remove duplicate materials from a list in-place.
auto removeDuplicatesInPlaceInto(const Containers::Iterable<Trade::MaterialData>& materials, const Containers::StridedArrayView1D<UnsignedInt>& mapping) -> std::size_t new in Git master
Remove duplicate materials from a list in-place and put mapping into given output array.
auto removeDuplicates(const Containers::Iterable<const Trade::MaterialData>& materials) -> Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> new in Git master
Remove duplicate materials from a list.
auto removeDuplicatesInto(const Containers::Iterable<const Trade::MaterialData>& materials, const Containers::StridedArrayView1D<UnsignedInt>& mapping) -> std::size_t new in Git master
Remove duplicate materials from a list in-place and put mapping into given output array.

Enum documentation

enum Magnum::MaterialTools::MergeConflicts: UnsignedInt new in Git master

Material merge conflict resolution.

Enumerators
Fail

Print a message to Error and return Containers::NullOpt in case both materials contain an attribute of the same name in the same layer index. Neither its type nor its value is checked, so this fails also in case the values are the same.

KeepFirstIfSameType

Keep the value from the first material in case both materials contain an attribute of the same name in the same layer index and both attributes have the same type. Print a message to Error and return Containers::NullOpt if they have a different type, for example in case of custom attributes.

If you want to keep the value from the second material instead, call merge() with this option and the materials swapped.

KeepFirstIgnoreType

Keep the value from the first material in case both materials contain an attribute of the same name in the same layer index, regardless of their type. With this option the operation always succeeds.

If you want to keep the value from the second material instead, call merge() with this option and the materials swapped.

enum class Magnum::MaterialTools::PhongToPbrMetallicRoughnessFlag new in Git master

Phong to PBR metallic/roughness conversion flag.

Enumerators
KeepOriginalAttributes

Keep original attributes instead of removing all that were converted.

DropUnconvertibleAttributes

Drop attributes that can't be converted instead of keeping them in the output. If FailOnUnconvertibleAttributes is specified as well, it has a priority.

DropUnconvertableAttributes

Drop attributes that can't be converted instead of keeping them in the output. If FailOnUnconvertibleAttributes is specified as well, it has a priority.

FailOnUnconvertibleAttributes

Fail if any attributes can't be converted instead of keeping them in the output. Has a priority over DropUnconvertibleAttributes.

FailOnUnconvertableAttributes

Drop attributes that can't be converted instead of keeping them in the output. If FailOnUnconvertibleAttributes is specified as well, it has a priority.

Typedef documentation

Function documentation

Trade::MaterialData Magnum::MaterialTools::copy(const Trade::MaterialData& material) new in Git master

Make an owned copy of the material.

Allocates a copy of Trade::MaterialData::attributeData() and layerData() and returns a new material with those. All other properties such as material types or importer state are passed through unchanged. The resulting Trade::MaterialData::attributeDataFlags() and layerDataFlags() are always Trade::DataFlag::Owned and Trade::DataFlag::Mutable.

Trade::MaterialData Magnum::MaterialTools::copy(Trade::MaterialData&& material) new in Git master

Make a material with owned data.

If either Trade::MaterialData::attributeDataFlags() or layerDataFlags() are not Trade::DataFlag::Owned and Trade::DataFlag::Mutable, allocates a copy of Trade::MaterialData::attributeData() or layerData(), otherwise transfers their ownership. The resulting data are always owned and mutable.

Trade::MaterialData Magnum::MaterialTools::filterAttributes(const Trade::MaterialData& material, Containers::BitArrayView attributesToKeep, Trade::MaterialTypes typesToKeep = ~Trade::MaterialTypes{}) new in Git master

Filter material attributes.

Returns a material with only the attributes for which the corresponding bit in attributesToKeep was set. Attributes in additional layers are referenced by bit ranges corresponding to Trade::MaterialData::attributeDataOffset() for a particular layer. The output layer ranges are then recalculated based on how many attributes are left in those. Empty layers are kept, Trade::MaterialData::types() are ANDed with typesToKeep.

The size of attributesToKeep is expected to be equal to the number of attributes in all layers (i.e., size of the Trade::MaterialData::attributeData() array).

Trade::MaterialData Magnum::MaterialTools::filterLayers(const Trade::MaterialData& material, Containers::BitArrayView layersToKeep, Trade::MaterialTypes typesToKeep = ~Trade::MaterialTypes{}) new in Git master

Filter material layers.

Returns a material with only the layers for which the corresponding bit in layersToKeep was set. The only exception is the base layer, which is left empty if removed. Attributes in other layers are kept untouched, Trade::MaterialData::types() are ANDed with typesToKeep.

The size of layerCount is expected to be equal to Trade::MaterialData::layerCount().

Trade::MaterialData Magnum::MaterialTools::filterAttributesLayers(const Trade::MaterialData& material, Containers::BitArrayView attributesToKeep, Containers::BitArrayView layersToKeep, Trade::MaterialTypes typesToKeep = ~Trade::MaterialTypes{}) new in Git master

Filter material attributes and layers.

Performs what filterAttributes() and filterLayers() do, but in a single step. Bits in attributesToKeep that correspond to layers that are removed are ignored.

Containers::Optional<Trade::MaterialData> Magnum::MaterialTools::merge(const Trade::MaterialData& first, const Trade::MaterialData& second, MergeConflicts conflicts = MergeConflicts::Fail) new in Git master

Merge two materials.

Takes attributes from second and inserts them to layers of the same index in first. If second has more layers than first, the additional layers are added at the end of first. Trade::MaterialTypes from first and second are merged together. If both materials contain an attribute of the same name in the same layer index, conflict resolution is performed according to the conflicts option.

As the input materials have the attributes sorted already, the operation is done in an $ \mathcal{O}(m + n) $ execution time and memory complexity, with $ m $ and $ n $ being count of all attributes and layers in first and second, respectively.

Containers::Optional<Trade::MaterialData> Magnum::MaterialTools::phongToPbrMetallicRoughness(const Trade::MaterialData& material, PhongToPbrMetallicRoughnessFlags flags = {}) new in Git master

Convert a Phong material to PBR metallic/roughness.

Performs conversion of the following attributes. If the target attribute is already present, it's passed through unchanged. The original attribute is removed, unless PhongToPbrMetallicRoughnessFlag::KeepOriginalAttributes is set.

The following attributes currently aren't converted. If they are present in the input material, a message is printed to Warning. The attributes are passed through unchanged unless PhongToPbrMetallicRoughnessFlag::DropUnconvertibleAttributes is set; if FailOnUnconvertibleAttributes is set instead, a message is printed to Error and the function returns Containers::NullOpt.

All other attributes (including ones common for Phong and PBR such as Trade::MaterialAttribute::NormalTexture) are passed through unchanged. The resulting material has Trade::MaterialType::PbrMetallicRoughness set and Trade::MaterialType::Phong removed.

Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> Magnum::MaterialTools::removeDuplicatesInPlace(const Containers::Iterable<Trade::MaterialData>& materials) new in Git master

Remove duplicate materials from a list in-place.

Parameters
materials in/out List of materials
Returns Index array to map the original material indices to the output indices and size of the unique prefix in the cleaned up materials array

Removes duplicate materials from the input by comparing material types, attribute names, types and values and layer offsets. Floating-point attribute values are compared using fuzzy comparison. Importer state and data flags aren't considered when comparing the materials. Unique materials are shifted to the front with order preserved, the returned mapping array has the same size as the materials list and maps from the original indices to prefix of the output. See removeDuplicates() for a variant that doesn't modify the input list in any way but instead returns a mapping array pointing to original data locations.

The operation is done in an $ \mathcal{O}(n^2 m) $ complexity with $ n $ being the material list size and $ m $ the per-material attribute count — every material in the list is compared to all unique materials collected so far. As attributes are sorted in Trade::MaterialData, material comparison is just a linear operation. The function doesn't allocate any temporary memory.

The output index array can be passed to SceneTools::mapIndexField() to update a Trade::SceneField::MeshMaterial field to reference only the unique materials. For example:

Containers::Pointer<Trade::AbstractImporter> importer = ;

/* Import all materials */
Containers::Array<Trade::MaterialData> materials;
for(UnsignedInt i = 0; i != importer->materialCount(); ++i)
    arrayAppend(materials, *importer->material(i));

/* Remove duplicates, putting the unique materials to the prefix and removing
   the rest */
Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> mapping =
    MaterialTools::removeDuplicatesInPlace(materials);
arrayRemoveSuffix(materials, materials.size() - mapping.second());

/* Apply the mapping to unique materials to the scene */
Trade::SceneData scene = ;
SceneTools::mapIndexFieldInPlace(scene,
    Trade::SceneField::MeshMaterial, mapping.first());

std::size_t Magnum::MaterialTools::removeDuplicatesInPlaceInto(const Containers::Iterable<Trade::MaterialData>& materials, const Containers::StridedArrayView1D<UnsignedInt>& mapping) new in Git master

Remove duplicate materials from a list in-place and put mapping into given output array.

Parameters
materials in/out List of materials
mapping out Where to put the resulting mapping array
Returns Size of the unique prefix in the cleaned up materials array

Like removeDuplicatesInPlace() but puts the mapping indices into mapping instead of allocating a new array. Expects that mapping has the same size as materials.

Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> Magnum::MaterialTools::removeDuplicates(const Containers::Iterable<const Trade::MaterialData>& materials) new in Git master

Remove duplicate materials from a list.

Parameters
materials in List of materials
Returns Array to map the original material indices to unique materials and size of the unique prefix in the cleaned up materials array

Removes duplicate materials from the input by comparing material types, attribute names, types and values and layer offsets. Floating-point attribute values are compared using fuzzy comparison. Importer state and data flags aren't considered when comparing the materials. The returned mapping array has the same size as the materials list and maps from the original indices to only unique materials in the input array. See removeDuplicatesInPlace() for a variant that also shifts the unique materials to the front of the list and for a practical usage example.

The operation is done in an $ \mathcal{O}(n^2 m) $ complexity with $ n $ being the material list size and $ m $ the per-material attribute count — every material in the list is compared to all unique materials collected so far, by iterating the filled prefix of the output index list and considering only index for which the index value is the same as the index. As attributes are sorted in Trade::MaterialData, material comparison is just a linear operation. The function doesn't allocate any temporary memory.

std::size_t Magnum::MaterialTools::removeDuplicatesInto(const Containers::Iterable<const Trade::MaterialData>& materials, const Containers::StridedArrayView1D<UnsignedInt>& mapping) new in Git master

Remove duplicate materials from a list in-place and put mapping into given output array.

Parameters
materials in/out List of materials
mapping out Where to put the resulting mapping array
Returns Size of the unique prefix in the cleaned up materials array

Like removeDuplicates() but puts the mapping indices into mapping instead of allocating a new array. Expects that mapping has the same size as materials.