You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

132 lines
6.4 KiB

#ifndef Magnum_MaterialTools_RemoveDuplicates_h
#define Magnum_MaterialTools_RemoveDuplicates_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023 Vladimír Vondruš <mosra@centrum.cz>
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::MaterialTools::removeDuplicatesInPlace(), @ref Magnum::MaterialTools::removeDuplicatesInPlaceInto(), @ref Magnum::MaterialTools::removeDuplicates(), @ref Magnum::MaterialTools::removeDuplicatesInto()
* @m_since_latest
*/
#include <Corrade/Containers/Containers.h>
#include "Magnum/MaterialTools/visibility.h"
#include "Magnum/Trade/Trade.h"
namespace Magnum { namespace MaterialTools {
/**
@brief Remove duplicate materials from a list in-place
@param[in,out] materials List of materials
@return Index array to map the original material indices to the output indices
and size of the unique prefix in the cleaned up @p materials array
@m_since_latest
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 @p materials list and maps from the original indices to prefix of the
output. See @ref 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 @f$ \mathcal{O}(n^2 m) @f$ complexity with
@f$ n @f$ being the material list size and @f$ m @f$ the per-material attribute
count --- every material in the list is compared to all unique materials
collected so far. As attributes are sorted in @ref 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 @ref SceneTools::mapIndexField() to
update a @ref Trade::SceneField::MeshMaterial field to reference only the
unique materials. For example:
@snippet MagnumMaterialTools.cpp removeDuplicatesInPlace
@see @ref removeDuplicatesInPlaceInto()
*/
MAGNUM_MATERIALTOOLS_EXPORT Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicatesInPlace(const Containers::Iterable<Trade::MaterialData>& materials);
/**
@brief Remove duplicate materials from a list in-place and put mapping into given output array
@param[in,out] materials List of materials
@param[out] mapping Where to put the resulting mapping array
@return Size of the unique prefix in the cleaned up @p materials array
@m_since_latest
Like @ref removeDuplicatesInPlace() but puts the mapping indices into
@p mapping instead of allocating a new array. Expects that @p mapping has the
same size as @p materials.
@see @ref removeDuplicatesInto()
*/
MAGNUM_MATERIALTOOLS_EXPORT std::size_t removeDuplicatesInPlaceInto(const Containers::Iterable<Trade::MaterialData>& materials, const Containers::StridedArrayView1D<UnsignedInt>& mapping);
/**
@brief Remove duplicate materials from a list
@param[in] materials List of materials
@return Array to map the original material indices to unique materials and size
of the unique prefix in the cleaned up @p materials array
@m_since_latest
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 @p materials list and maps from the original indices to
only unique materials in the input array. See @ref 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 @f$ \mathcal{O}(n^2 m) @f$ complexity with
@f$ n @f$ being the material list size and @f$ m @f$ 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 @ref Trade::MaterialData, material comparison is just
a linear operation. The function doesn't allocate any temporary memory.
@see @ref removeDuplicatesInto()
*/
MAGNUM_MATERIALTOOLS_EXPORT Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicates(const Containers::Iterable<const Trade::MaterialData>& materials);
/**
@brief Remove duplicate materials from a list in-place and put mapping into given output array
@param[in,out] materials List of materials
@param[out] mapping Where to put the resulting mapping array
@return Size of the unique prefix in the cleaned up @p materials array
@m_since_latest
Like @ref removeDuplicates() but puts the mapping indices into @p mapping
instead of allocating a new array. Expects that @p mapping has the same size as
@p materials.
@see @ref removeDuplicatesInPlaceInto()
*/
MAGNUM_MATERIALTOOLS_EXPORT std::size_t removeDuplicatesInto(const Containers::Iterable<const Trade::MaterialData>& materials, const Containers::StridedArrayView1D<UnsignedInt>& mapping);
}}
#endif