Browse Source

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.
pull/601/head
Vladimír Vondruš 3 years ago
parent
commit
177c59289e
  1. 16
      src/Magnum/MaterialTools/Filter.cpp
  2. 12
      src/Magnum/MaterialTools/Filter.h
  3. 20
      src/Magnum/MaterialTools/Test/FilterTest.cpp

16
src/Magnum/MaterialTools/Filter.cpp

@ -41,7 +41,7 @@ namespace {
- if neither is nullptr then inputAttributesToKeep is patched to have zero - if neither is nullptr then inputAttributesToKeep is patched to have zero
bits for all attributes in filtered-out layers, bits for all attributes in filtered-out layers,
- both can't be nullptr */ - 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()); const std::size_t totalAttributeCount = material.attributeDataOffset(material.layerCount());
/* Generate the input attribute bit array or make a mutable copy. Using an /* 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()); 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(), CORRADE_ASSERT(attributesToKeep.size() == material.attributeData().size(),
"MaterialTools::filterAttributes(): expected" << material.attributeData().size() << "bits but got" << attributesToKeep.size(), (Trade::MaterialData{{}, {}})); "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(), CORRADE_ASSERT(layersToKeep.size() == material.layerCount(),
"MaterialTools::filterLayers(): expected" << material.layerCount() << "bits but got" << layersToKeep.size(), (Trade::MaterialData{{}, {}})); "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(), CORRADE_ASSERT(attributesToKeep.size() == material.attributeData().size(),
"MaterialTools::filterAttributesLayers(): expected" << material.attributeData().size() << "attribute bits but got" << attributesToKeep.size(), (Trade::MaterialData{{}, {}})); "MaterialTools::filterAttributesLayers(): expected" << material.attributeData().size() << "attribute bits but got" << attributesToKeep.size(), (Trade::MaterialData{{}, {}}));
CORRADE_ASSERT(layersToKeep.size() == material.layerCount(), CORRADE_ASSERT(layersToKeep.size() == material.layerCount(),
"MaterialTools::filterAttributesLayers(): expected" << material.layerCount() << "layer bits but got" << layersToKeep.size(), (Trade::MaterialData{{}, {}})); "MaterialTools::filterAttributesLayers(): expected" << material.layerCount() << "layer bits but got" << layersToKeep.size(), (Trade::MaterialData{{}, {}}));
return filterAttributesLayersImplementation(material, attributesToKeep, layersToKeep); return filterAttributesLayersImplementation(material, attributesToKeep, layersToKeep, typesToKeep);
} }
}} }}

12
src/Magnum/MaterialTools/Filter.h

@ -30,6 +30,8 @@
* @m_since_latest * @m_since_latest
*/ */
#include <Corrade/Containers/EnumSet.h>
#include "Magnum/MaterialTools/visibility.h" #include "Magnum/MaterialTools/visibility.h"
#include "Magnum/Trade/Trade.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 bit ranges corresponding to @ref Trade::MaterialData::attributeDataOffset() for
a particular layer. The output layer ranges are then recalculated based on how a particular layer. The output layer ranges are then recalculated based on how
many attributes are left in those. Empty layers are kept, 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 The size of @p attributesToKeep is expected to be equal to the number of
attributes in all layers (i.e., size of the attributes in all layers (i.e., size of the
@ref Trade::MaterialData::attributeData() array). @ref Trade::MaterialData::attributeData() array).
@see @ref filterLayers(), @ref filterAttributesLayers() @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 @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 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 @p layersToKeep was set. The only exception is the base layer, which is left
empty if removed. Attributes in other layers are kept untouched, 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 The size of @p layerCount is expected to be equal to
@ref Trade::MaterialData::layerCount(). @ref Trade::MaterialData::layerCount().
@see @ref filterAttributes(), @ref filterAttributesLayers() @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 @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 single step. Bits in @p attributesToKeep that correspond to layers that are
removed are ignored. 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{});
}} }}

20
src/Magnum/MaterialTools/Test/FilterTest.cpp

@ -82,7 +82,7 @@ void FilterTest::attributes() {
{Trade::MaterialAttribute::TextureCoordinates, 11u}, /* 3 */ {Trade::MaterialAttribute::TextureCoordinates, 11u}, /* 3 */
{Trade::MaterialAttribute::TextureLayer, 0u}, /* 4 */ {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}; Containers::BitArray attributesToKeep{DirectInit, 5, true};
attributesToKeep.reset(1); 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 /* 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 for some higher-level utility that understands their relations to
present attributes */ 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::AlphaBlend, true},
{Trade::MaterialAttribute::BaseColorTexture, 7u}, {Trade::MaterialAttribute::BaseColorTexture, 7u},
}}), DebugTools::CompareMaterial); }}), DebugTools::CompareMaterial);
/* Removing all shouldn't do anything unexpected */ /* 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); }}), DebugTools::CompareMaterial);
} }
@ -170,14 +170,14 @@ void FilterTest::layers() {
{"againSomething", false}, /* 6 #9 */ {"againSomething", false}, /* 6 #9 */
}; };
const UnsignedInt layers[]{3, 3, 6, 8, 8, 9, 10}; 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}; Containers::BitArray layersToKeep{DirectInit, 7, true};
layersToKeep.reset(1); layersToKeep.reset(1);
layersToKeep.reset(2); layersToKeep.reset(2);
layersToKeep.reset(5); 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::AlphaBlend, true},
{Trade::MaterialAttribute::BaseColor, 0xffcc66ff_rgbaf}, {Trade::MaterialAttribute::BaseColor, 0xffcc66ff_rgbaf},
{Trade::MaterialAttribute::BaseColorTexture, 7u}, {Trade::MaterialAttribute::BaseColorTexture, 7u},
@ -188,7 +188,7 @@ void FilterTest::layers() {
}, {3, 5, 5, 6}}), DebugTools::CompareMaterial); }, {3, 5, 5, 6}}), DebugTools::CompareMaterial);
/* Removing all shouldn't do anything unexpected */ /* 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); }}), DebugTools::CompareMaterial);
} }
@ -247,7 +247,7 @@ void FilterTest::attributesLayers() {
{"againSomething", false}, /* 6 #9 */ {"againSomething", false}, /* 6 #9 */
}; };
const UnsignedInt layers[]{3, 3, 6, 8, 8, 9, 10}; 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}; Containers::BitArray attributesToKeep{DirectInit, 10, true};
attributesToKeep.reset(1); attributesToKeep.reset(1);
@ -259,7 +259,7 @@ void FilterTest::attributesLayers() {
layersToKeep.reset(1); layersToKeep.reset(1);
layersToKeep.reset(2); 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::AlphaBlend, true},
{Trade::MaterialAttribute::BaseColorTexture, 7u}, {Trade::MaterialAttribute::BaseColorTexture, 7u},
{"texturePointer", nullptr}, {"texturePointer", nullptr},
@ -269,11 +269,11 @@ void FilterTest::attributesLayers() {
}, {2, 3, 3, 3, 4}}), DebugTools::CompareMaterial); }, {2, 3, 3, 3, 4}}), DebugTools::CompareMaterial);
/* Removing all attributes should keep all layers but make them empty */ /* 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); }, {0, 0, 0, 0, 0, 0, 0}}), DebugTools::CompareMaterial);
/* Removing all layers should make the material completely empty */ /* 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); }}), DebugTools::CompareMaterial);
} }

Loading…
Cancel
Save