From 177c59289e6b0f5879db5620771215a638c745ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 15 Feb 2023 19:44:21 +0100 Subject: [PATCH] MaterialTools: add a possibility to filter also the types enum. I thought it wasn't needed and people could do it manually after only to realize it'd be actually very convenient if present. --- src/Magnum/MaterialTools/Filter.cpp | 16 ++++++++-------- src/Magnum/MaterialTools/Filter.h | 12 +++++++----- src/Magnum/MaterialTools/Test/FilterTest.cpp | 20 ++++++++++---------- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/Magnum/MaterialTools/Filter.cpp b/src/Magnum/MaterialTools/Filter.cpp index 2ff9faaeb..25c75dc35 100644 --- a/src/Magnum/MaterialTools/Filter.cpp +++ b/src/Magnum/MaterialTools/Filter.cpp @@ -41,7 +41,7 @@ namespace { - if neither is nullptr then inputAttributesToKeep is patched to have zero bits for all attributes in filtered-out layers, - both can't be nullptr */ -Trade::MaterialData filterAttributesLayersImplementation(const Trade::MaterialData& material, const Containers::BitArrayView inputAttributesToKeep, const Containers::BitArrayView inputLayersToKeep) { +Trade::MaterialData filterAttributesLayersImplementation(const Trade::MaterialData& material, const Containers::BitArrayView inputAttributesToKeep, const Containers::BitArrayView inputLayersToKeep, const Trade::MaterialTypes typesToKeep) { const std::size_t totalAttributeCount = material.attributeDataOffset(material.layerCount()); /* Generate the input attribute bit array or make a mutable copy. Using an @@ -106,32 +106,32 @@ Trade::MaterialData filterAttributesLayersImplementation(const Trade::MaterialDa } CORRADE_INTERNAL_ASSERT(attributeOffset == attributes.size()); - return Trade::MaterialData{material.types(), std::move(attributes), std::move(layers)}; + return Trade::MaterialData{material.types() & typesToKeep, std::move(attributes), std::move(layers)}; } } -Trade::MaterialData filterAttributes(const Trade::MaterialData& material, const Containers::BitArrayView attributesToKeep) { +Trade::MaterialData filterAttributes(const Trade::MaterialData& material, const Containers::BitArrayView attributesToKeep, const Trade::MaterialTypes typesToKeep) { CORRADE_ASSERT(attributesToKeep.size() == material.attributeData().size(), "MaterialTools::filterAttributes(): expected" << material.attributeData().size() << "bits but got" << attributesToKeep.size(), (Trade::MaterialData{{}, {}})); - return filterAttributesLayersImplementation(material, attributesToKeep, nullptr); + return filterAttributesLayersImplementation(material, attributesToKeep, nullptr, typesToKeep); } -Trade::MaterialData filterLayers(const Trade::MaterialData& material, const Containers::BitArrayView layersToKeep) { +Trade::MaterialData filterLayers(const Trade::MaterialData& material, const Containers::BitArrayView layersToKeep, const Trade::MaterialTypes typesToKeep) { CORRADE_ASSERT(layersToKeep.size() == material.layerCount(), "MaterialTools::filterLayers(): expected" << material.layerCount() << "bits but got" << layersToKeep.size(), (Trade::MaterialData{{}, {}})); - return filterAttributesLayersImplementation(material, nullptr, layersToKeep); + return filterAttributesLayersImplementation(material, nullptr, layersToKeep, typesToKeep); } -Trade::MaterialData filterAttributesLayers(const Trade::MaterialData& material, const Containers::BitArrayView attributesToKeep, const Containers::BitArrayView layersToKeep) { +Trade::MaterialData filterAttributesLayers(const Trade::MaterialData& material, const Containers::BitArrayView attributesToKeep, const Containers::BitArrayView layersToKeep, const Trade::MaterialTypes typesToKeep) { CORRADE_ASSERT(attributesToKeep.size() == material.attributeData().size(), "MaterialTools::filterAttributesLayers(): expected" << material.attributeData().size() << "attribute bits but got" << attributesToKeep.size(), (Trade::MaterialData{{}, {}})); CORRADE_ASSERT(layersToKeep.size() == material.layerCount(), "MaterialTools::filterAttributesLayers(): expected" << material.layerCount() << "layer bits but got" << layersToKeep.size(), (Trade::MaterialData{{}, {}})); - return filterAttributesLayersImplementation(material, attributesToKeep, layersToKeep); + return filterAttributesLayersImplementation(material, attributesToKeep, layersToKeep, typesToKeep); } }} diff --git a/src/Magnum/MaterialTools/Filter.h b/src/Magnum/MaterialTools/Filter.h index 669eb50b6..982adb986 100644 --- a/src/Magnum/MaterialTools/Filter.h +++ b/src/Magnum/MaterialTools/Filter.h @@ -30,6 +30,8 @@ * @m_since_latest */ +#include + #include "Magnum/MaterialTools/visibility.h" #include "Magnum/Trade/Trade.h" @@ -44,14 +46,14 @@ Returns a material with only the attributes for which the corresponding bit in bit ranges corresponding to @ref 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, -@ref Trade::MaterialData::types() are transferred unchanged. +@ref Trade::MaterialData::types() are ANDed with @p typesToKeep. The size of @p attributesToKeep is expected to be equal to the number of attributes in all layers (i.e., size of the @ref Trade::MaterialData::attributeData() array). @see @ref filterLayers(), @ref filterAttributesLayers() */ -MAGNUM_MATERIALTOOLS_EXPORT Trade::MaterialData filterAttributes(const Trade::MaterialData& material, Containers::BitArrayView attributesToKeep); +MAGNUM_MATERIALTOOLS_EXPORT Trade::MaterialData filterAttributes(const Trade::MaterialData& material, Containers::BitArrayView attributesToKeep, Trade::MaterialTypes typesToKeep = ~Trade::MaterialTypes{}); /** @brief Filter material layers @@ -60,13 +62,13 @@ MAGNUM_MATERIALTOOLS_EXPORT Trade::MaterialData filterAttributes(const Trade::Ma Returns a material with only the layers for which the corresponding bit in @p layersToKeep was set. The only exception is the base layer, which is left empty if removed. Attributes in other layers are kept untouched, -@ref Trade::MaterialData::types() are transferred unchanged. +@ref Trade::MaterialData::types() are ANDed with @p typesToKeep. The size of @p layerCount is expected to be equal to @ref Trade::MaterialData::layerCount(). @see @ref filterAttributes(), @ref filterAttributesLayers() */ -MAGNUM_MATERIALTOOLS_EXPORT Trade::MaterialData filterLayers(const Trade::MaterialData& material, Containers::BitArrayView layersToKeep); +MAGNUM_MATERIALTOOLS_EXPORT Trade::MaterialData filterLayers(const Trade::MaterialData& material, Containers::BitArrayView layersToKeep, Trade::MaterialTypes typesToKeep = ~Trade::MaterialTypes{}); /** @brief Filter material attributes and layers @@ -76,7 +78,7 @@ Performs what @ref filterAttributes() and @ref filterLayers() do, but in a single step. Bits in @p attributesToKeep that correspond to layers that are removed are ignored. */ -MAGNUM_MATERIALTOOLS_EXPORT Trade::MaterialData filterAttributesLayers(const Trade::MaterialData& material, Containers::BitArrayView attributesToKeep, Containers::BitArrayView layersToKeep); +MAGNUM_MATERIALTOOLS_EXPORT Trade::MaterialData filterAttributesLayers(const Trade::MaterialData& material, Containers::BitArrayView attributesToKeep, Containers::BitArrayView layersToKeep, Trade::MaterialTypes typesToKeep = ~Trade::MaterialTypes{}); }} diff --git a/src/Magnum/MaterialTools/Test/FilterTest.cpp b/src/Magnum/MaterialTools/Test/FilterTest.cpp index 89d98330a..5f8d12d42 100644 --- a/src/Magnum/MaterialTools/Test/FilterTest.cpp +++ b/src/Magnum/MaterialTools/Test/FilterTest.cpp @@ -82,7 +82,7 @@ void FilterTest::attributes() { {Trade::MaterialAttribute::TextureCoordinates, 11u}, /* 3 */ {Trade::MaterialAttribute::TextureLayer, 0u}, /* 4 */ }; - Trade::MaterialData material{Trade::MaterialType::PbrClearCoat|Trade::MaterialType::Flat, Trade::DataFlags{}, attributes}; + Trade::MaterialData material{Trade::MaterialType::PbrClearCoat|Trade::MaterialType::Flat|Trade::MaterialType::Phong, Trade::DataFlags{}, attributes}; Containers::BitArray attributesToKeep{DirectInit, 5, true}; attributesToKeep.reset(1); @@ -92,13 +92,13 @@ void FilterTest::attributes() { /* The types are kept intact even if they don't make sense, that's a job for some higher-level utility that understands their relations to present attributes */ - CORRADE_COMPARE_AS(filterAttributes(material, attributesToKeep), (Trade::MaterialData{Trade::MaterialType::PbrClearCoat|Trade::MaterialType::Flat, { + CORRADE_COMPARE_AS(filterAttributes(material, attributesToKeep, Trade::MaterialType::PbrClearCoat|Trade::MaterialType::PbrMetallicRoughness), (Trade::MaterialData{Trade::MaterialType::PbrClearCoat, { {Trade::MaterialAttribute::AlphaBlend, true}, {Trade::MaterialAttribute::BaseColorTexture, 7u}, }}), DebugTools::CompareMaterial); /* Removing all shouldn't do anything unexpected */ - CORRADE_COMPARE_AS(filterAttributes(material, Containers::BitArray{ValueInit, 5}), (Trade::MaterialData{Trade::MaterialType::PbrClearCoat|Trade::MaterialType::Flat, { + CORRADE_COMPARE_AS(filterAttributes(material, Containers::BitArray{ValueInit, 5}, {}), (Trade::MaterialData{{}, { }}), DebugTools::CompareMaterial); } @@ -170,14 +170,14 @@ void FilterTest::layers() { {"againSomething", false}, /* 6 #9 */ }; const UnsignedInt layers[]{3, 3, 6, 8, 8, 9, 10}; - Trade::MaterialData material{Trade::MaterialType::PbrClearCoat, Trade::DataFlags{}, attributes, Trade::DataFlags{}, layers}; + Trade::MaterialData material{Trade::MaterialType::PbrClearCoat|Trade::MaterialType::PbrMetallicRoughness, Trade::DataFlags{}, attributes, Trade::DataFlags{}, layers}; Containers::BitArray layersToKeep{DirectInit, 7, true}; layersToKeep.reset(1); layersToKeep.reset(2); layersToKeep.reset(5); - CORRADE_COMPARE_AS(filterLayers(material, layersToKeep), (Trade::MaterialData{Trade::MaterialType::PbrClearCoat, { + CORRADE_COMPARE_AS(filterLayers(material, layersToKeep, Trade::MaterialType::PbrMetallicRoughness|Trade::MaterialType::PbrSpecularGlossiness), (Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, { {Trade::MaterialAttribute::AlphaBlend, true}, {Trade::MaterialAttribute::BaseColor, 0xffcc66ff_rgbaf}, {Trade::MaterialAttribute::BaseColorTexture, 7u}, @@ -188,7 +188,7 @@ void FilterTest::layers() { }, {3, 5, 5, 6}}), DebugTools::CompareMaterial); /* Removing all shouldn't do anything unexpected */ - CORRADE_COMPARE_AS(filterLayers(material, Containers::BitArray{ValueInit, 7}), (Trade::MaterialData{Trade::MaterialType::PbrClearCoat, { + CORRADE_COMPARE_AS(filterLayers(material, Containers::BitArray{ValueInit, 7}, {}), (Trade::MaterialData{{}, { }}), DebugTools::CompareMaterial); } @@ -247,7 +247,7 @@ void FilterTest::attributesLayers() { {"againSomething", false}, /* 6 #9 */ }; const UnsignedInt layers[]{3, 3, 6, 8, 8, 9, 10}; - Trade::MaterialData material{Trade::MaterialType::PbrClearCoat, Trade::DataFlags{}, attributes, Trade::DataFlags{}, layers}; + Trade::MaterialData material{Trade::MaterialType::PbrClearCoat|Trade::MaterialType::PbrMetallicRoughness, Trade::DataFlags{}, attributes, Trade::DataFlags{}, layers}; Containers::BitArray attributesToKeep{DirectInit, 10, true}; attributesToKeep.reset(1); @@ -259,7 +259,7 @@ void FilterTest::attributesLayers() { layersToKeep.reset(1); layersToKeep.reset(2); - CORRADE_COMPARE_AS(filterAttributesLayers(material, attributesToKeep, layersToKeep), (Trade::MaterialData{Trade::MaterialType::PbrClearCoat, { + CORRADE_COMPARE_AS(filterAttributesLayers(material, attributesToKeep, layersToKeep, Trade::MaterialType::PbrMetallicRoughness|Trade::MaterialType::PbrSpecularGlossiness), (Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, { {Trade::MaterialAttribute::AlphaBlend, true}, {Trade::MaterialAttribute::BaseColorTexture, 7u}, {"texturePointer", nullptr}, @@ -269,11 +269,11 @@ void FilterTest::attributesLayers() { }, {2, 3, 3, 3, 4}}), DebugTools::CompareMaterial); /* Removing all attributes should keep all layers but make them empty */ - CORRADE_COMPARE_AS(filterAttributesLayers(material, Containers::BitArray{ValueInit, 10}, Containers::BitArray{DirectInit, 7, true}), (Trade::MaterialData{Trade::MaterialType::PbrClearCoat, { + CORRADE_COMPARE_AS(filterAttributesLayers(material, Containers::BitArray{ValueInit, 10}, Containers::BitArray{DirectInit, 7, true}, {}), (Trade::MaterialData{{}, { }, {0, 0, 0, 0, 0, 0, 0}}), DebugTools::CompareMaterial); /* Removing all layers should make the material completely empty */ - CORRADE_COMPARE_AS(filterLayers(material, Containers::BitArray{ValueInit, 7}), (Trade::MaterialData{Trade::MaterialType::PbrClearCoat, { + CORRADE_COMPARE_AS(filterAttributesLayers(material, Containers::BitArray{ValueInit, 10}, Containers::BitArray{ValueInit, 7}, {}), (Trade::MaterialData{{}, { }}), DebugTools::CompareMaterial); }