diff --git a/doc/changelog.dox b/doc/changelog.dox index 173b8b645..2a8a6b185 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -227,7 +227,8 @@ See also: @ref MeshTools::boundingRange() for AABBs (see [mosra/magnum#557](https://github.com/mosra/magnum/pull/557)) - Added @ref MeshTools::generateQuadIndices() for quad triangulation including non-convex and non-planar quads -- New @ref MeshTools::filterOnlyAttributes() and +- New @ref MeshTools::filterAttributes(), + @ref MeshTools::filterOnlyAttributes() and @ref MeshTools::filterExceptAttributes() utilities for filtering mesh data attribute lists - New family of @ref MeshTools::transform2D(), @ref MeshTools::transform3D() diff --git a/src/Magnum/MeshTools/CMakeLists.txt b/src/Magnum/MeshTools/CMakeLists.txt index 108df9fa8..adc80bc72 100644 --- a/src/Magnum/MeshTools/CMakeLists.txt +++ b/src/Magnum/MeshTools/CMakeLists.txt @@ -38,7 +38,7 @@ set(MagnumMeshTools_GracefulAssert_SRCS CompressIndices.cpp Concatenate.cpp Duplicate.cpp - FilterAttributes.cpp + Filter.cpp FlipNormals.cpp GenerateIndices.cpp GenerateLines.cpp @@ -54,7 +54,7 @@ set(MagnumMeshTools_HEADERS CompressIndices.h Concatenate.h Duplicate.h - FilterAttributes.h + Filter.h FlipNormals.h GenerateIndices.h GenerateLines.h @@ -77,6 +77,7 @@ if(MAGNUM_BUILD_DEPRECATED) CombineIndexedArrays.cpp) list(APPEND MagnumMeshTools_HEADERS CombineIndexedArrays.h + FilterAttributes.h GenerateFlatNormals.h) endif() diff --git a/src/Magnum/MeshTools/Filter.cpp b/src/Magnum/MeshTools/Filter.cpp new file mode 100644 index 000000000..433abf2b0 --- /dev/null +++ b/src/Magnum/MeshTools/Filter.cpp @@ -0,0 +1,148 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "Filter.h" + +#include +#include + +#include "Magnum/Trade/MeshData.h" + +#ifdef MAGNUM_BUILD_DEPRECATED +#define _MAGNUM_NO_DEPRECATED_MESHTOOLS_FILTERATTRIBUTES /* so it doesn't warn */ +#include "Magnum/MeshTools/FilterAttributes.h" +#endif + +namespace Magnum { namespace MeshTools { + +Trade::MeshData filterAttributes(const Trade::MeshData& mesh, const Containers::BitArrayView attributesToKeep) { + CORRADE_ASSERT(attributesToKeep.size() == mesh.attributeCount(), + "MeshTools::filterAttributes(): expected" << mesh.attributeCount() << "bits but got" << attributesToKeep.size(), (Trade::MeshData{MeshPrimitive::Triangles, 0})); + + /* Copy attributes that aren't filtered away. Not using NoInit in order to + use the default deleter and have this usable from plugins. */ + Containers::Array filtered{attributesToKeep.count()}; + /** @todo some copyMasked() utility */ + UnsignedInt attributeOffset = 0; + for(UnsignedInt i = 0; i != attributesToKeep.size(); ++i) { + if(!attributesToKeep[i]) continue; + filtered[attributeOffset++] = mesh.attributeData()[i]; + } + CORRADE_INTERNAL_ASSERT(attributeOffset == filtered.size()); + + /* Can't do just Trade::MeshIndexData{data.indices()} as that would discard + implementation-specific types. And can't do + Trade::meshIndexData{data.indexType(), view} + because asking for index type would assert on non-indexed meshes. */ + Trade::MeshIndexData indices; + if(mesh.isIndexed()) indices = Trade::MeshIndexData{ + mesh.indexType(), + Containers::StridedArrayView1D{ + mesh.indexData(), + mesh.indexData().data() + mesh.indexOffset(), + mesh.indexCount(), + mesh.indexStride()}}; + + return Trade::MeshData{mesh.primitive(), + {}, mesh.indexData(), indices, + {}, mesh.vertexData(), std::move(filtered), + mesh.vertexCount()}; +} + +Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, const Containers::ArrayView attributes) { + Containers::BitArray attributesToKeep{DirectInit, mesh.attributeCount(), false}; + for(const Trade::MeshAttribute attribute: attributes) { + /* Can't use findAttributeId() because all instances of the attribute + should be kept, not just the first one */ + for(UnsignedInt i = 0; i != attributesToKeep.size(); ++i) { + if(mesh.attributeName(i) == attribute) + attributesToKeep.set(i); + } + } + return filterAttributes(mesh, attributesToKeep); +} + +Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, std::initializer_list attributes) { + return filterOnlyAttributes(mesh, Containers::arrayView(attributes)); +} + +#ifdef MAGNUM_BUILD_DEPRECATED +Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, const Containers::ArrayView attributes) { + Containers::BitArray attributesToKeep{DirectInit, mesh.attributeCount(), false}; + for(const UnsignedInt i: attributes) { + CORRADE_ASSERT(i < mesh.attributeCount(), + "MeshTools::filterOnlyAttributes(): index" << i << "out of range for" << mesh.attributeCount() << "attributes", + (Trade::MeshData{MeshPrimitive{}, 0})); + attributesToKeep.set(i); + } + + return filterAttributes(mesh, attributesToKeep); +} + +Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, std::initializer_list attributes) { + CORRADE_IGNORE_DEPRECATED_PUSH + return filterOnlyAttributes(mesh, Containers::arrayView(attributes)); + CORRADE_IGNORE_DEPRECATED_POP +} +#endif + +Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, const Containers::ArrayView attributes) { + Containers::BitArray attributesToKeep{DirectInit, mesh.attributeCount(), true}; + for(const Trade::MeshAttribute attribute: attributes) { + /* Can't use findAttributeId() because all instances of the attribute + should be removed, not just the first one */ + for(UnsignedInt i = 0; i != attributesToKeep.size(); ++i) { + if(mesh.attributeName(i) == attribute) + attributesToKeep.reset(i); + } + } + return filterAttributes(mesh, attributesToKeep); +} + +Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, std::initializer_list attributes) { + return filterExceptAttributes(mesh, Containers::arrayView(attributes)); +} + +#ifdef MAGNUM_BUILD_DEPRECATED +Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, const Containers::ArrayView attributes) { + Containers::BitArray attributesToKeep{DirectInit, mesh.attributeCount(), true}; + for(const UnsignedInt i: attributes) { + CORRADE_ASSERT(i < mesh.attributeCount(), + "MeshTools::filterExceptAttributes(): index" << i << "out of range for" << mesh.attributeCount() << "attributes", + (Trade::MeshData{MeshPrimitive{}, 0})); + attributesToKeep.reset(i); + } + + return filterAttributes(mesh, attributesToKeep); +} + +Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, std::initializer_list attributes) { + CORRADE_IGNORE_DEPRECATED_PUSH + return filterExceptAttributes(mesh, Containers::arrayView(attributes)); + CORRADE_IGNORE_DEPRECATED_POP +} +#endif + +}} diff --git a/src/Magnum/MeshTools/Filter.h b/src/Magnum/MeshTools/Filter.h new file mode 100644 index 000000000..0685060db --- /dev/null +++ b/src/Magnum/MeshTools/Filter.h @@ -0,0 +1,110 @@ +#ifndef Magnum_MeshTools_Filter_h +#define Magnum_MeshTools_Filter_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Function @ref Magnum::MeshTools::filterAttributes(), @ref Magnum::MeshTools::filterOnlyAttributes(), @ref Magnum::MeshTools::filterExceptAttributes() + * @m_since_latest + */ + +#include + +#include "Magnum/MeshTools/visibility.h" +#include "Magnum/Trade/Trade.h" + +namespace Magnum { namespace MeshTools { + +/** +@brief Filter a mesh to contain only the selected subset of attributes +@m_since_latest + +Returns a non-owning reference to the vertex and index buffer from @p mesh with +only the attributes for which the corresponding bit in @p attributesToKeep was +set. The index buffer, if present, is left untouched. The size of +@p attributesToKeep is expected to be equal to +@ref 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 @ref interleave(const Trade::MeshData&, Containers::ArrayView, InterleaveFlags) "interleave()" +without @ref InterleaveFlag::PreserveInterleavedAttributes set. +@see @ref reference() +*/ +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterAttributes(const Trade::MeshData& mesh, Containers::BitArrayView attributesToKeep); + +/** +@brief Filter a mesh to contain only the selected subset of named attributes +@m_since_latest + +Returns a non-owning reference to the vertex and index buffer from @p mesh with +only the attributes that are listed in @p attributes. The index buffer, if +present, is left untouched. Attributes from the list that are not present in +@p mesh are skipped. All duplicates of a listed attribute are kept --- if you +want a different behavior, use the @ref filterOnlyAttributes(const Trade::MeshData&, Containers::ArrayView) +overload 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 @ref interleave(const Trade::MeshData&, Containers::ArrayView, InterleaveFlags) "interleave()" +without @ref InterleaveFlag::PreserveInterleavedAttributes set. +@see @ref reference() +*/ +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, Containers::ArrayView attributes); + +/** + * @overload + * @m_since_latest + */ +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, std::initializer_list attributes); + +/** +@brief Filter a mesh to contain everything except the selected subset of named attributes +@m_since_latest + +Returns a non-owning reference to the vertex and index buffer from @p mesh with +only the attributes that are not listed in @p attributes. The index buffer, if +present, is left untouched. Attributes from the list that are not present in +@p mesh are skipped. All duplicates of a listed attribute are removed --- if +you want a different behavior, use the @ref filterExceptAttributes(const Trade::MeshData&, Containers::ArrayView) +overload and pick attributes by their IDs instead. If @p attributes is empty, +the behavior is equivalent to @ref reference(). + +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 @ref interleave(const Trade::MeshData&, Containers::ArrayView, InterleaveFlags) "interleave()" +without @ref InterleaveFlag::PreserveInterleavedAttributes set. +*/ +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, Containers::ArrayView attributes); + +/** + * @overload + * @m_since_latest + */ +MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, std::initializer_list attributes); + +}} + +#endif diff --git a/src/Magnum/MeshTools/FilterAttributes.cpp b/src/Magnum/MeshTools/FilterAttributes.cpp deleted file mode 100644 index c803b9263..000000000 --- a/src/Magnum/MeshTools/FilterAttributes.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - This file is part of Magnum. - - Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, - 2020, 2021, 2022 Vladimír Vondruš - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "FilterAttributes.h" - -#include -#include - -#include "Magnum/Trade/MeshData.h" - -namespace Magnum { namespace MeshTools { - -namespace { - -bool hasAttribute(const Containers::ArrayView attributes, const Trade::MeshAttribute attribute) { - for(const Trade::MeshAttribute i: attributes) - if(i == attribute) return true; - return false; -} - -/** @todo drop this insanity in favor of a BitArray */ -bool hasAttribute(const Containers::ArrayView attributes, const UnsignedInt attribute) { - for(const UnsignedInt i: attributes) - if(i == attribute) return true; - return false; -} - -} - -Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, const Containers::ArrayView attributes) { - /* Not asserting here for existence of attributes since that'd be another - O(n^2) operation */ - /** @todo but that's not consistent with the ID-based variant, or maybe do - this via a BitArray in the second loop and check that all attributes - got referenced afterwards? */ - - /* Pick just attributes from the list */ - Containers::Array filtered; - arrayReserve(filtered, mesh.attributeCount()); - for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) { - if(hasAttribute(attributes, mesh.attributeName(i))) - arrayAppend(filtered, mesh.attributeData(i)); - } - - /* Convert back to a default deleter to make this usable in plugins */ - arrayShrink(filtered, DefaultInit); - - /* Can't do just Trade::MeshIndexData{data.indices()} as that would discard - implementation-specific types. And can't do - Trade::meshIndexData{data.indexType(), view} - because asking for index type would assert on non-indexed meshes. */ - Trade::MeshIndexData indices; - if(mesh.isIndexed()) indices = Trade::MeshIndexData{ - mesh.indexType(), - Containers::StridedArrayView1D{ - mesh.indexData(), - mesh.indexData().data() + mesh.indexOffset(), - mesh.indexCount(), - mesh.indexStride()}}; - - return Trade::MeshData{mesh.primitive(), - {}, mesh.indexData(), indices, - {}, mesh.vertexData(), std::move(filtered), - mesh.vertexCount()}; -} - -Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, std::initializer_list attributes) { - return filterOnlyAttributes(mesh, Containers::arrayView(attributes)); -} - -Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, const Containers::ArrayView attributes) { - #ifndef CORRADE_NO_ASSERT - for(const UnsignedInt i: attributes) CORRADE_ASSERT(i < mesh.attributeCount(), - "MeshTools::filterOnlyAttributes(): index" << i << "out of range for" << mesh.attributeCount() << "attributes", - (Trade::MeshData{MeshPrimitive{}, 0})); - #endif - - /* Pick just attributes from the list */ - Containers::Array filtered; - arrayReserve(filtered, mesh.attributeCount()); - for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) { - if(hasAttribute(attributes, i)) - arrayAppend(filtered, mesh.attributeData(i)); - } - - /* Convert back to a default deleter to make this usable in plugins */ - arrayShrink(filtered, DefaultInit); - - /* Can't do just Trade::MeshIndexData{data.indices()} as that would discard - implementation-specific types. And can't do - Trade::meshIndexData{data.indexType(), view} - because asking for index type would assert on non-indexed meshes. */ - Trade::MeshIndexData indices; - if(mesh.isIndexed()) indices = Trade::MeshIndexData{ - mesh.indexType(), - Containers::StridedArrayView1D{ - mesh.indexData(), - mesh.indexData().data() + mesh.indexOffset(), - mesh.indexCount(), - mesh.indexStride()}}; - - return Trade::MeshData{mesh.primitive(), - {}, mesh.indexData(), indices, - {}, mesh.vertexData(), std::move(filtered), - mesh.vertexCount()}; -} - -Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, std::initializer_list attributes) { - return filterOnlyAttributes(mesh, Containers::arrayView(attributes)); -} - -Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, const Containers::ArrayView attributes) { - /* Not asserting here for existence of attributes since that'd be another - O(n^2) operation */ - /** @todo but that's not consistent with the ID-based variant, or maybe do - this via a BitArray in the second loop and check that all attributes - got referenced afterwards? */ - - /* Pick just attributes from the list */ - Containers::Array filtered; - arrayReserve(filtered, mesh.attributeCount()); - for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) { - if(!hasAttribute(attributes, mesh.attributeName(i))) - arrayAppend(filtered, mesh.attributeData(i)); - } - - /* Convert back to a default deleter to make this usable in plugins */ - arrayShrink(filtered, DefaultInit); - - /* Can't do just Trade::MeshIndexData{data.indices()} as that would discard - implementation-specific types. And can't do - Trade::meshIndexData{data.indexType(), view} - because asking for index type would assert on non-indexed meshes. */ - Trade::MeshIndexData indices; - if(mesh.isIndexed()) indices = Trade::MeshIndexData{ - mesh.indexType(), - Containers::StridedArrayView1D{ - mesh.indexData(), - mesh.indexData().data() + mesh.indexOffset(), - mesh.indexCount(), - mesh.indexStride()}}; - - return Trade::MeshData{mesh.primitive(), - {}, mesh.indexData(), indices, - {}, mesh.vertexData(), std::move(filtered), - mesh.vertexCount()}; -} - -Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, std::initializer_list attributes) { - return filterExceptAttributes(mesh, Containers::arrayView(attributes)); -} - -Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, const Containers::ArrayView attributes) { - #ifndef CORRADE_NO_ASSERT - for(const UnsignedInt i: attributes) CORRADE_ASSERT(i < mesh.attributeCount(), - "MeshTools::filterExceptAttributes(): index" << i << "out of range for" << mesh.attributeCount() << "attributes", - (Trade::MeshData{MeshPrimitive{}, 0})); - #endif - - /* Pick just attributes from the list */ - Containers::Array filtered; - arrayReserve(filtered, mesh.attributeCount()); - for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) { - if(!hasAttribute(attributes, i)) - arrayAppend(filtered, mesh.attributeData(i)); - } - - /* Convert back to a default deleter to make this usable in plugins */ - arrayShrink(filtered, DefaultInit); - - /* Can't do just Trade::MeshIndexData{data.indices()} as that would discard - implementation-specific types. And can't do - Trade::meshIndexData{data.indexType(), view} - because asking for index type would assert on non-indexed meshes. */ - Trade::MeshIndexData indices; - if(mesh.isIndexed()) indices = Trade::MeshIndexData{ - mesh.indexType(), - Containers::StridedArrayView1D{ - mesh.indexData(), - mesh.indexData().data() + mesh.indexOffset(), - mesh.indexCount(), - mesh.indexStride()}}; - - return Trade::MeshData{mesh.primitive(), - {}, mesh.indexData(), indices, - {}, mesh.vertexData(), std::move(filtered), - mesh.vertexCount()}; -} - -Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, std::initializer_list attributes) { - return filterExceptAttributes(mesh, Containers::arrayView(attributes)); -} - -}} diff --git a/src/Magnum/MeshTools/FilterAttributes.h b/src/Magnum/MeshTools/FilterAttributes.h index e43664254..1af5b5f9f 100644 --- a/src/Magnum/MeshTools/FilterAttributes.h +++ b/src/Magnum/MeshTools/FilterAttributes.h @@ -25,46 +25,30 @@ DEALINGS IN THE SOFTWARE. */ +#ifdef MAGNUM_BUILD_DEPRECATED /** @file * @brief Function @ref Magnum::MeshTools::filterOnlyAttributes(), @ref Magnum::MeshTools::filterExceptAttributes() - * @m_since_latest + * @m_deprecated_since_latest Use @ref Magnum/MeshTools/Filter.h instead. */ +#endif -#include +#include "Magnum/configure.h" -#include "Magnum/MeshTools/visibility.h" -#include "Magnum/Trade/Trade.h" +#ifdef MAGNUM_BUILD_DEPRECATED +#include -namespace Magnum { namespace MeshTools { +#include "Magnum/MeshTools/Filter.h" -/** -@brief Filter a mesh to contain only the selected subset of named attributes -@m_since_latest - -Returns a non-owning reference to the vertex and index buffer from @p mesh with -only the attributes that are listed in @p attributes. The index buffer, if -present, is left untouched. Attributes from the list that are not present in -@p mesh are skipped. All duplicates of a listed attribute are kept --- if you -want a different behavior, use the @ref filterOnlyAttributes(const Trade::MeshData&, Containers::ArrayView) -overload 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 @ref interleave(const Trade::MeshData&, Containers::ArrayView, InterleaveFlags) "interleave()" -without @ref InterleaveFlag::PreserveInterleavedAttributes set. -@see @ref reference() -*/ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, Containers::ArrayView attributes); +#ifndef _MAGNUM_NO_DEPRECATED_MESHTOOLS_FILTERATTRIBUTES +CORRADE_DEPRECATED_FILE("use Magnum/MeshTools/Filter.h instead") +#endif -/** - * @overload - * @m_since_latest - */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, std::initializer_list attributes); +namespace Magnum { namespace MeshTools { /** @brief Filter a mesh to contain only the selected subset of attributes -@m_since_latest +@m_deprecated_since_latest Use @ref filterAttributes(const Trade::MeshData&, Containers::BitArrayView) + instead. Returns a non-owning reference to the vertex and index buffer from @p mesh with only the attribute IDs listed in @p attributes. IDs specified more than once @@ -78,42 +62,19 @@ the output to @ref interleave(const Trade::MeshData&, Containers::ArrayView attributes); +CORRADE_DEPRECATED("use filterAttributes() instead") MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, Containers::ArrayView attributes); /** - * @overload - * @m_since_latest - */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, std::initializer_list attributes); - -/** -@brief Filter a mesh to contain everything except the selected subset of named attributes -@m_since_latest - -Returns a non-owning reference to the vertex and index buffer from @p mesh with -only the attributes that are not listed in @p attributes. The index buffer, if -present, is left untouched. Attributes from the list that are not present in -@p mesh are skipped. All duplicates of a listed attribute are removed --- if -you want a different behavior, use the @ref filterExceptAttributes(const Trade::MeshData&, Containers::ArrayView) -overload and pick attributes by their IDs instead. If @p attributes is empty, -the behavior is equivalent to @ref reference(). - -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 @ref interleave(const Trade::MeshData&, Containers::ArrayView, InterleaveFlags) "interleave()" -without @ref InterleaveFlag::PreserveInterleavedAttributes set. +@brief Filter a mesh to contain only the selected subset of attributes +@m_deprecated_since_latest Use @ref filterAttributes(const Trade::MeshData&, Containers::BitArrayView) + instead. */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, Containers::ArrayView attributes); - -/** - * @overload - * @m_since_latest - */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, std::initializer_list attributes); +CORRADE_DEPRECATED("use filterAttributes() instead") MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterOnlyAttributes(const Trade::MeshData& mesh, std::initializer_list attributes); /** @brief Filter a mesh to contain everything except the selected subset of attributes -@m_since_latest +@m_deprecated_since_latest Use @ref filterAttributes(const Trade::MeshData&, Containers::BitArrayView) + instead. Returns a non-owning reference to the vertex and index buffer from @p mesh with only the attribute IDs that are not listed in @p attributes. IDs specified @@ -127,14 +88,18 @@ the vertex data repacked to contain just the remaining attributes as well, pass the output to @ref interleave(const Trade::MeshData&, Containers::ArrayView, InterleaveFlags) "interleave()" without @ref InterleaveFlag::PreserveInterleavedAttributes set. */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, Containers::ArrayView attributes); +CORRADE_DEPRECATED("use filterAttributes() instead") MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, Containers::ArrayView attributes); /** - * @overload - * @m_since_latest - */ -MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, std::initializer_list attributes); +@brief Filter a mesh to contain everything except the selected subset of attributes +@m_deprecated_since_latest Use @ref filterAttributes(const Trade::MeshData&, Containers::BitArrayView) + instead. +*/ +CORRADE_DEPRECATED("use filterAttributes() instead") MAGNUM_MESHTOOLS_EXPORT Trade::MeshData filterExceptAttributes(const Trade::MeshData& mesh, std::initializer_list attributes); }} +#else +#error use Magnum/MeshTools/Filter.h instead +#endif #endif diff --git a/src/Magnum/MeshTools/Test/CMakeLists.txt b/src/Magnum/MeshTools/Test/CMakeLists.txt index 2cc712d04..28a3aded0 100644 --- a/src/Magnum/MeshTools/Test/CMakeLists.txt +++ b/src/Magnum/MeshTools/Test/CMakeLists.txt @@ -32,7 +32,7 @@ corrade_add_test(MeshToolsCombineTest CombineTest.cpp LIBRARIES MagnumMeshToolsT corrade_add_test(MeshToolsCompressIndicesTest CompressIndicesTest.cpp LIBRARIES MagnumMeshToolsTestLib) corrade_add_test(MeshToolsConcatenateTest ConcatenateTest.cpp LIBRARIES MagnumMeshToolsTestLib) corrade_add_test(MeshToolsDuplicateTest DuplicateTest.cpp LIBRARIES MagnumMeshToolsTestLib) -corrade_add_test(MeshToolsFilterAttributesTest FilterAttributesTest.cpp LIBRARIES MagnumMeshToolsTestLib) +corrade_add_test(MeshToolsFilterTest FilterTest.cpp LIBRARIES MagnumMeshToolsTestLib) corrade_add_test(MeshToolsFlipNormalsTest FlipNormalsTest.cpp LIBRARIES MagnumMeshToolsTestLib) corrade_add_test(MeshToolsGenerateIndicesTest GenerateIndicesTest.cpp LIBRARIES MagnumMeshToolsTestLib) corrade_add_test(MeshToolsGenerateLinesTest GenerateLinesTest.cpp diff --git a/src/Magnum/MeshTools/Test/FilterAttributesTest.cpp b/src/Magnum/MeshTools/Test/FilterTest.cpp similarity index 74% rename from src/Magnum/MeshTools/Test/FilterAttributesTest.cpp rename to src/Magnum/MeshTools/Test/FilterTest.cpp index 7d8d2c60c..c7be8c2a0 100644 --- a/src/Magnum/MeshTools/Test/FilterAttributesTest.cpp +++ b/src/Magnum/MeshTools/Test/FilterTest.cpp @@ -24,35 +24,50 @@ */ #include +#include +#include #include #include #include "Magnum/Math/Vector4.h" -#include "Magnum/MeshTools/FilterAttributes.h" +#include "Magnum/MeshTools/Filter.h" #include "Magnum/Trade/MeshData.h" -namespace Magnum { namespace MeshTools { namespace Test { namespace { - -struct FilterAttributesTest: TestSuite::Tester { - explicit FilterAttributesTest(); - - void filterOnlyAttributeNames(); - void filterOnlyAttributeNamesNoIndexData(); - void filterOnlyAttributeNamesNoAttributeData(); - - void filterOnlyAttributeIds(); - void filterOnlyAttributeIdsOutOfBounds(); - void filterOnlyAttributeIdsNoIndexData(); - void filterOnlyAttributeIdsNoAttributeData(); +#ifdef MAGNUM_BUILD_DEPRECATED +#define _MAGNUM_NO_DEPRECATED_MESHTOOLS_FILTERATTRIBUTES /* so it doesn't warn */ +#include "Magnum/MeshTools/FilterAttributes.h" +#endif - void filterExceptAttributeNames(); - void filterExceptAttributeNamesNoIndexData(); - void filterExceptAttributeNamesNoAttributeData(); +namespace Magnum { namespace MeshTools { namespace Test { namespace { - void filterExceptAttributeIds(); - void filterExceptAttributeIdsOutOfBounds(); - void filterExceptAttributeIdsNoIndexData(); - void filterExceptAttributeIdsNoAttributeData(); +struct FilterTest: TestSuite::Tester { + explicit FilterTest(); + + void attributes(); + void attributesNoIndexData(); + void attributesWrongBitCount(); + + void onlyAttributes(); + void onlyAttributesNoIndexData(); + void onlyAttributesNoAttributeData(); + + #ifdef MAGNUM_BUILD_DEPRECATED + void onlyAttributeIds(); + void onlyAttributeIdsOutOfBounds(); + void onlyAttributeIdsNoIndexData(); + void onlyAttributeIdsNoAttributeData(); + #endif + + void exceptAttributes(); + void exceptAttributesNoIndexData(); + void exceptAttributesNoAttributeData(); + + #ifdef MAGNUM_BUILD_DEPRECATED + void exceptAttributeIds(); + void exceptAttributeIdsOutOfBounds(); + void exceptAttributeIdsNoIndexData(); + void exceptAttributeIdsNoAttributeData(); + #endif }; const struct { @@ -63,32 +78,42 @@ const struct { {"implementation-specific index type", meshIndexTypeWrap(0xcaca)} }; -FilterAttributesTest::FilterAttributesTest() { - addInstancedTests({&FilterAttributesTest::filterOnlyAttributeNames}, +FilterTest::FilterTest() { + addInstancedTests({&FilterTest::attributes}, + Containers::arraySize(ImplementationSpecificIndexTypeData)); + + addTests({&FilterTest::attributesNoIndexData, + &FilterTest::attributesWrongBitCount}); + + addInstancedTests({&FilterTest::onlyAttributes}, Containers::arraySize(ImplementationSpecificIndexTypeData)); - addTests({&FilterAttributesTest::filterOnlyAttributeNamesNoIndexData, - &FilterAttributesTest::filterOnlyAttributeNamesNoAttributeData}); + addTests({&FilterTest::onlyAttributesNoIndexData, + &FilterTest::onlyAttributesNoAttributeData}); - addInstancedTests({&FilterAttributesTest::filterOnlyAttributeIds}, + #ifdef MAGNUM_BUILD_DEPRECATED + addInstancedTests({&FilterTest::onlyAttributeIds}, Containers::arraySize(ImplementationSpecificIndexTypeData)); - addTests({&FilterAttributesTest::filterOnlyAttributeIdsOutOfBounds, - &FilterAttributesTest::filterOnlyAttributeIdsNoIndexData, - &FilterAttributesTest::filterOnlyAttributeIdsNoAttributeData}); + addTests({&FilterTest::onlyAttributeIdsOutOfBounds, + &FilterTest::onlyAttributeIdsNoIndexData, + &FilterTest::onlyAttributeIdsNoAttributeData}); + #endif - addInstancedTests({&FilterAttributesTest::filterExceptAttributeNames}, + addInstancedTests({&FilterTest::exceptAttributes}, Containers::arraySize(ImplementationSpecificIndexTypeData)); - addTests({&FilterAttributesTest::filterExceptAttributeNamesNoIndexData, - &FilterAttributesTest::filterExceptAttributeNamesNoAttributeData}); + addTests({&FilterTest::exceptAttributesNoIndexData, + &FilterTest::exceptAttributesNoAttributeData}); - addInstancedTests({&FilterAttributesTest::filterExceptAttributeIds}, + #ifdef MAGNUM_BUILD_DEPRECATED + addInstancedTests({&FilterTest::exceptAttributeIds}, Containers::arraySize(ImplementationSpecificIndexTypeData)); - addTests({&FilterAttributesTest::filterExceptAttributeIdsOutOfBounds, - &FilterAttributesTest::filterExceptAttributeIdsNoIndexData, - &FilterAttributesTest::filterExceptAttributeIdsNoAttributeData}); + addTests({&FilterTest::exceptAttributeIdsOutOfBounds, + &FilterTest::exceptAttributeIdsNoIndexData, + &FilterTest::exceptAttributeIdsNoAttributeData}); + #endif } struct Vertex { @@ -97,7 +122,104 @@ struct Vertex { Vector2 textureCoordinates1, textureCoordinates2; }; -void FilterAttributesTest::filterOnlyAttributeNames() { +void FilterTest::attributes() { + auto&& data = ImplementationSpecificIndexTypeData[testCaseInstanceId()]; + setTestCaseDescription(data.name); + + Containers::Array indexData{5*sizeof(UnsignedShort)}; + Containers::StridedArrayView1D indices = Containers::arrayCast(indexData); + Containers::Array vertexData{3*sizeof(Vertex)}; + Containers::StridedArrayView1D vertices = Containers::arrayCast(vertexData); + + Trade::MeshData mesh{MeshPrimitive::TriangleStrip, + std::move(indexData), Trade::MeshIndexData{data.indexType, indices}, + std::move(vertexData), { + Trade::MeshAttributeData{Trade::MeshAttribute::Position, vertices.slice(&Vertex::position)}, + Trade::MeshAttributeData{Trade::MeshAttribute::Tangent, vertices.slice(&Vertex::tangent)}, + Trade::MeshAttributeData{Trade::MeshAttribute::TextureCoordinates, vertices.slice(&Vertex::textureCoordinates1)}, + Trade::MeshAttributeData{Trade::MeshAttribute::TextureCoordinates, vertices.slice(&Vertex::textureCoordinates2)}, + }}; + + Containers::BitArray attributesToKeep{ValueInit, mesh.attributeCount()}; + attributesToKeep.set(1); + attributesToKeep.set(3); + + Trade::MeshData filtered = filterAttributes(mesh, attributesToKeep); + CORRADE_COMPARE(filtered.primitive(), MeshPrimitive::TriangleStrip); + + CORRADE_VERIFY(filtered.isIndexed()); + CORRADE_COMPARE(filtered.indexCount(), 5); + CORRADE_COMPARE(filtered.indexType(), data.indexType); + CORRADE_COMPARE(filtered.indexData().data(), indices.data()); + CORRADE_COMPARE(filtered.indexDataFlags(), Trade::DataFlags{}); + + CORRADE_COMPARE(filtered.vertexCount(), 3); + CORRADE_COMPARE(filtered.vertexData().data(), vertices.data()); + CORRADE_COMPARE(filtered.vertexDataFlags(), Trade::DataFlags{}); + + /* Testing just the offset if it matches expectations, the + MeshAttributeData is copied directly so no metadata should get lost */ + CORRADE_COMPARE(filtered.attributeCount(), 2); + CORRADE_COMPARE(filtered.attributeName(0), Trade::MeshAttribute::Tangent); + CORRADE_COMPARE(filtered.attributeOffset(0), offsetof(Vertex, tangent)); + CORRADE_COMPARE(filtered.attributeName(1), Trade::MeshAttribute::TextureCoordinates); + CORRADE_COMPARE(filtered.attributeOffset(1), offsetof(Vertex, textureCoordinates2)); + + /* The attribute data should not be a growable array to make this usable in + plugins */ + Containers::Array attributeData = filtered.releaseAttributeData(); + CORRADE_VERIFY(!attributeData.deleter()); +} + +void FilterTest::attributesNoIndexData() { + /* A trivial subset of filterAttributes() testing it doesn't blow up if the + mesh is not indexed */ + + Containers::Array vertexData{3*sizeof(Vertex)}; + Containers::StridedArrayView1D vertices = Containers::arrayCast(vertexData); + + Trade::MeshData mesh{MeshPrimitive::TriangleFan, + std::move(vertexData), { + Trade::MeshAttributeData{Trade::MeshAttribute::TextureCoordinates, vertices.slice(&Vertex::textureCoordinates1)} + }}; + + Trade::MeshData filtered = filterAttributes(mesh, Containers::BitArray{DirectInit, 1, true}); + CORRADE_COMPARE(filtered.primitive(), MeshPrimitive::TriangleFan); + + CORRADE_VERIFY(!filtered.isIndexed()); + /* Consistent with behavior in reference() for index-less meshes */ + CORRADE_COMPARE(filtered.indexDataFlags(), Trade::DataFlags{}); + + CORRADE_COMPARE(filtered.vertexCount(), 3); + CORRADE_COMPARE(filtered.vertexData().data(), vertices.data()); + CORRADE_COMPARE(filtered.vertexDataFlags(), Trade::DataFlags{}); + + /* Testing just the offset if it matches expectations, the + MeshAttributeData is copied directly so no metadata should get lost */ + CORRADE_COMPARE(filtered.attributeCount(), 1); + CORRADE_COMPARE(filtered.attributeName(0), Trade::MeshAttribute::TextureCoordinates); + CORRADE_COMPARE(filtered.attributeOffset(0), offsetof(Vertex, textureCoordinates1)); +} + +void FilterTest::attributesWrongBitCount() { + CORRADE_SKIP_IF_NO_ASSERT(); + + /* GCC 4.8 dies if I try to initialize this with a {}. I won't, then. */ + Vertex vertices[3]; + + Trade::MeshData mesh{MeshPrimitive::TriangleFan, + {}, vertices, { + Trade::MeshAttributeData{Trade::MeshAttribute::Position, Containers::stridedArrayView(vertices).slice(&Vertex::position)}, + Trade::MeshAttributeData{Trade::MeshAttribute::TextureCoordinates, Containers::stridedArrayView(vertices).slice(&Vertex::textureCoordinates1)} + }}; + + std::ostringstream out; + Error redirectError{&out}; + filterAttributes(mesh, Containers::BitArray{ValueInit, 3}); + CORRADE_COMPARE(out.str(), "MeshTools::filterAttributes(): expected 2 bits but got 3\n"); +} + +void FilterTest::onlyAttributes() { auto&& data = ImplementationSpecificIndexTypeData[testCaseInstanceId()]; setTestCaseDescription(data.name); @@ -148,7 +270,7 @@ void FilterAttributesTest::filterOnlyAttributeNames() { CORRADE_VERIFY(!attributeData.deleter()); } -void FilterAttributesTest::filterOnlyAttributeNamesNoIndexData() { +void FilterTest::onlyAttributesNoIndexData() { /* A trivial subset of filterOnlyAttributeNames() testing it doesn't blow up if the mesh is not indexed */ @@ -180,7 +302,7 @@ void FilterAttributesTest::filterOnlyAttributeNamesNoIndexData() { CORRADE_COMPARE(filtered.attributeOffset(0), offsetof(Vertex, textureCoordinates1)); } -void FilterAttributesTest::filterOnlyAttributeNamesNoAttributeData() { +void FilterTest::onlyAttributesNoAttributeData() { Containers::Array indexData{5*sizeof(UnsignedShort)}; Containers::StridedArrayView1D indices = Containers::arrayCast(indexData); @@ -206,7 +328,8 @@ void FilterAttributesTest::filterOnlyAttributeNamesNoAttributeData() { CORRADE_COMPARE(filtered.attributeCount(), 0); } -void FilterAttributesTest::filterOnlyAttributeIds() { +#ifdef MAGNUM_BUILD_DEPRECATED +void FilterTest::onlyAttributeIds() { auto&& data = ImplementationSpecificIndexTypeData[testCaseInstanceId()]; setTestCaseDescription(data.name); @@ -224,11 +347,13 @@ void FilterAttributesTest::filterOnlyAttributeIds() { Trade::MeshAttributeData{Trade::MeshAttribute::TextureCoordinates, vertices.slice(&Vertex::textureCoordinates2)}, }}; + CORRADE_IGNORE_DEPRECATED_PUSH Trade::MeshData filtered = filterOnlyAttributes(mesh, { /* The attribute 1 is specified twice, but that won't result in the same attribute being added twice */ 1, 1, 3 }); + CORRADE_IGNORE_DEPRECATED_POP CORRADE_COMPARE(filtered.primitive(), MeshPrimitive::TriangleStrip); CORRADE_VERIFY(filtered.isIndexed()); @@ -255,7 +380,7 @@ void FilterAttributesTest::filterOnlyAttributeIds() { CORRADE_VERIFY(!attributeData.deleter()); } -void FilterAttributesTest::filterOnlyAttributeIdsOutOfBounds() { +void FilterTest::onlyAttributeIdsOutOfBounds() { CORRADE_SKIP_IF_NO_ASSERT(); /* GCC 4.8 dies if I try to initialize this with a {}. I won't, then. */ @@ -269,11 +394,13 @@ void FilterAttributesTest::filterOnlyAttributeIdsOutOfBounds() { std::ostringstream out; Error redirectError{&out}; + CORRADE_IGNORE_DEPRECATED_PUSH filterOnlyAttributes(mesh, {0, 0, 2}); + CORRADE_IGNORE_DEPRECATED_POP CORRADE_COMPARE(out.str(), "MeshTools::filterOnlyAttributes(): index 2 out of range for 2 attributes\n"); } -void FilterAttributesTest::filterOnlyAttributeIdsNoIndexData() { +void FilterTest::onlyAttributeIdsNoIndexData() { /* A trivial subset of filterOnlyAttributeIds() testing it doesn't blow up if the mesh is not indexed */ @@ -285,9 +412,11 @@ void FilterAttributesTest::filterOnlyAttributeIdsNoIndexData() { Trade::MeshAttributeData{Trade::MeshAttribute::TextureCoordinates, vertices.slice(&Vertex::textureCoordinates1)} }}; + CORRADE_IGNORE_DEPRECATED_PUSH Trade::MeshData filtered = filterOnlyAttributes(mesh, { 0 }); + CORRADE_IGNORE_DEPRECATED_POP CORRADE_COMPARE(filtered.primitive(), MeshPrimitive::TriangleFan); CORRADE_VERIFY(!filtered.isIndexed()); @@ -305,14 +434,16 @@ void FilterAttributesTest::filterOnlyAttributeIdsNoIndexData() { CORRADE_COMPARE(filtered.attributeOffset(0), offsetof(Vertex, textureCoordinates1)); } -void FilterAttributesTest::filterOnlyAttributeIdsNoAttributeData() { +void FilterTest::onlyAttributeIdsNoAttributeData() { Containers::Array indexData{5*sizeof(UnsignedShort)}; Containers::StridedArrayView1D indices = Containers::arrayCast(indexData); Trade::MeshData mesh{MeshPrimitive::Points, std::move(indexData), Trade::MeshIndexData{indices}, 15}; + CORRADE_IGNORE_DEPRECATED_PUSH Trade::MeshData filtered = filterOnlyAttributes(mesh, std::initializer_list{}); + CORRADE_IGNORE_DEPRECATED_POP CORRADE_COMPARE(filtered.primitive(), MeshPrimitive::Points); CORRADE_VERIFY(filtered.isIndexed()); @@ -328,8 +459,9 @@ void FilterAttributesTest::filterOnlyAttributeIdsNoAttributeData() { CORRADE_COMPARE(filtered.attributeCount(), 0); } +#endif -void FilterAttributesTest::filterExceptAttributeNames() { +void FilterTest::exceptAttributes() { auto&& data = ImplementationSpecificIndexTypeData[testCaseInstanceId()]; setTestCaseDescription(data.name); @@ -380,7 +512,7 @@ void FilterAttributesTest::filterExceptAttributeNames() { CORRADE_VERIFY(!attributeData.deleter()); } -void FilterAttributesTest::filterExceptAttributeNamesNoIndexData() { +void FilterTest::exceptAttributesNoIndexData() { /* A trivial subset of filterExceptAttributeNames() testing it doesn't blow up if the mesh is not indexed */ @@ -413,7 +545,7 @@ void FilterAttributesTest::filterExceptAttributeNamesNoIndexData() { CORRADE_COMPARE(filtered.attributeOffset(0), offsetof(Vertex, textureCoordinates1)); } -void FilterAttributesTest::filterExceptAttributeNamesNoAttributeData() { +void FilterTest::exceptAttributesNoAttributeData() { Containers::Array indexData{5*sizeof(UnsignedShort)}; Containers::StridedArrayView1D indices = Containers::arrayCast(indexData); @@ -439,7 +571,8 @@ void FilterAttributesTest::filterExceptAttributeNamesNoAttributeData() { CORRADE_COMPARE(filtered.attributeCount(), 0); } -void FilterAttributesTest::filterExceptAttributeIds() { +#ifdef MAGNUM_BUILD_DEPRECATED +void FilterTest::exceptAttributeIds() { auto&& data = ImplementationSpecificIndexTypeData[testCaseInstanceId()]; setTestCaseDescription(data.name); @@ -457,11 +590,13 @@ void FilterAttributesTest::filterExceptAttributeIds() { Trade::MeshAttributeData{Trade::MeshAttribute::TextureCoordinates, vertices.slice(&Vertex::textureCoordinates2)}, }}; + CORRADE_IGNORE_DEPRECATED_PUSH Trade::MeshData filtered = filterExceptAttributes(mesh, { /* The attribute 1 is specified twice, but that won't result in attribute 1 being removed and then again */ 1, 1, 3 }); + CORRADE_IGNORE_DEPRECATED_POP CORRADE_COMPARE(filtered.primitive(), MeshPrimitive::TriangleStrip); CORRADE_VERIFY(filtered.isIndexed()); @@ -488,7 +623,7 @@ void FilterAttributesTest::filterExceptAttributeIds() { CORRADE_VERIFY(!attributeData.deleter()); } -void FilterAttributesTest::filterExceptAttributeIdsOutOfBounds() { +void FilterTest::exceptAttributeIdsOutOfBounds() { CORRADE_SKIP_IF_NO_ASSERT(); /* GCC 4.8 dies if I try to initialize this with a {}. I won't, then. */ @@ -502,11 +637,13 @@ void FilterAttributesTest::filterExceptAttributeIdsOutOfBounds() { std::ostringstream out; Error redirectError{&out}; + CORRADE_IGNORE_DEPRECATED_PUSH filterExceptAttributes(mesh, {0, 0, 2}); + CORRADE_IGNORE_DEPRECATED_POP CORRADE_COMPARE(out.str(), "MeshTools::filterExceptAttributes(): index 2 out of range for 2 attributes\n"); } -void FilterAttributesTest::filterExceptAttributeIdsNoIndexData() { +void FilterTest::exceptAttributeIdsNoIndexData() { /* A trivial subset of filterExceptAttributeIds() testing it doesn't blow up if the mesh is not indexed */ @@ -519,9 +656,11 @@ void FilterAttributesTest::filterExceptAttributeIdsNoIndexData() { Trade::MeshAttributeData{Trade::MeshAttribute::TextureCoordinates, vertices.slice(&Vertex::textureCoordinates1)} }}; + CORRADE_IGNORE_DEPRECATED_PUSH Trade::MeshData filtered = filterExceptAttributes(mesh, { 0 }); + CORRADE_IGNORE_DEPRECATED_POP CORRADE_COMPARE(filtered.primitive(), MeshPrimitive::TriangleFan); CORRADE_VERIFY(!filtered.isIndexed()); @@ -539,14 +678,16 @@ void FilterAttributesTest::filterExceptAttributeIdsNoIndexData() { CORRADE_COMPARE(filtered.attributeOffset(0), offsetof(Vertex, textureCoordinates1)); } -void FilterAttributesTest::filterExceptAttributeIdsNoAttributeData() { +void FilterTest::exceptAttributeIdsNoAttributeData() { Containers::Array indexData{5*sizeof(UnsignedShort)}; Containers::StridedArrayView1D indices = Containers::arrayCast(indexData); Trade::MeshData mesh{MeshPrimitive::Points, std::move(indexData), Trade::MeshIndexData{indices}, 15}; + CORRADE_IGNORE_DEPRECATED_PUSH Trade::MeshData filtered = filterExceptAttributes(mesh, std::initializer_list{}); + CORRADE_IGNORE_DEPRECATED_POP CORRADE_COMPARE(filtered.primitive(), MeshPrimitive::Points); CORRADE_VERIFY(filtered.isIndexed()); @@ -562,7 +703,8 @@ void FilterAttributesTest::filterExceptAttributeIdsNoAttributeData() { CORRADE_COMPARE(filtered.attributeCount(), 0); } +#endif }}}} -CORRADE_TEST_MAIN(Magnum::MeshTools::Test::FilterAttributesTest) +CORRADE_TEST_MAIN(Magnum::MeshTools::Test::FilterTest)