Browse Source

MeshTools: port away from std::pair in remaining APIs.

Same here, PairStl.h added for backwards compatibility. Finally allows
me to remove silly std::tie() and <tuple> includes from most example
code.
pull/617/head
Vladimír Vondruš 3 years ago
parent
commit
9bbbee6f56
  1. 3
      doc/changelog.dox
  2. 11
      doc/snippets/MagnumGL.cpp
  3. 12
      doc/snippets/MagnumMeshTools-gl.cpp
  4. 12
      doc/snippets/MagnumMeshTools.cpp
  5. 33
      src/Magnum/MeshTools/CompressIndices.cpp
  6. 20
      src/Magnum/MeshTools/CompressIndices.h
  7. 17
      src/Magnum/MeshTools/RemoveDuplicates.cpp
  8. 13
      src/Magnum/MeshTools/RemoveDuplicates.h
  9. 57
      src/Magnum/MeshTools/Test/CompressIndicesTest.cpp
  10. 28
      src/Magnum/MeshTools/Test/RemoveDuplicatesTest.cpp

3
doc/changelog.dox

@ -1304,6 +1304,9 @@ See also:
@ref GL::Buffer::setLabel() "setLabel()" APIs now work with a
@relativeref{Corrade,Containers::StringView} /
@relativeref{Corrade,Containers::String} instead of a @ref std::string
- @ref MeshTools::compressIndices(), @ref MeshTools::removeDuplicates()
and related APIs now return a @relativeref{Corrade,Containers::Pair}
instead of a @ref std::pair
- @ref Vk::DescriptorPoolCreateInfo and @ref Vk::AttachmentDescription
APIs now take a @relativeref{Corrade,Containers::Pair} instead of a
@ref std::pair

11
doc/snippets/MagnumGL.cpp

@ -23,9 +23,9 @@
DEALINGS IN THE SOFTWARE.
*/
#include <tuple> /* for std::tie() :( */
#include <Corrade/Containers/ArrayViewStl.h>
#include <Corrade/Containers/Iterable.h>
#include <Corrade/Containers/Pair.h>
#include <Corrade/Containers/Reference.h>
#include <Corrade/Containers/StringIterable.h>
#include <Corrade/Containers/StringView.h>
@ -1146,13 +1146,12 @@ mesh.addVertexBuffer(vertices, 0,
GL::Mesh mesh;
const UnsignedInt indexData[1]{};
/* [Mesh-indices-tool] */
Containers::Array<char> compressed;
MeshIndexType type;
std::tie(compressed, type) = MeshTools::compressIndices(indexData);
GL::Buffer indices{compressed};
Containers::Pair<Containers::Array<char>, MeshIndexType> compressed =
MeshTools::compressIndices(indexData);
GL::Buffer indices{compressed.first()};
DOXYGEN_ELLIPSIS()
mesh.setIndexBuffer(indices, 0, type);
mesh.setIndexBuffer(indices, 0, compressed.second());
/* [Mesh-indices-tool] */
}

12
doc/snippets/MagnumMeshTools-gl.cpp

@ -23,7 +23,7 @@
DEALINGS IN THE SOFTWARE.
*/
#include <tuple> /* for std::tie() :( */
#include <Corrade/Containers/Pair.h>
#include <Corrade/Containers/StridedArrayView.h>
#include "Magnum/GL/AbstractShaderProgram.h"
@ -36,6 +36,7 @@
#include "Magnum/Trade/MeshData.h"
#ifdef MAGNUM_BUILD_DEPRECATED
#include <tuple>
#include <vector>
#endif
@ -83,16 +84,15 @@ mesh.addVertexBuffer(std::move(vertices),
/* [compressIndices] */
Containers::Array<UnsignedInt> indices;
Containers::Array<char> indexData;
MeshIndexType indexType;
std::tie(indexData, indexType) = MeshTools::compressIndices(indices);
Containers::Pair<Containers::Array<char>, MeshIndexType> compressed =
MeshTools::compressIndices(indices);
GL::Buffer indexBuffer;
indexBuffer.setData(indexData);
indexBuffer.setData(compressed.first());
GL::Mesh mesh;
mesh.setCount(indices.size())
.setIndexBuffer(indexBuffer, 0, indexType);
.setIndexBuffer(indexBuffer, 0, compressed.second());
/* [compressIndices] */
}

12
doc/snippets/MagnumMeshTools.cpp

@ -23,8 +23,8 @@
DEALINGS IN THE SOFTWARE.
*/
#include <tuple>
#include <vector>
#include <Corrade/Containers/Pair.h>
#include "Magnum/Math/Color.h"
#include "Magnum/Math/FunctionsBatch.h"
@ -73,7 +73,7 @@ CORRADE_IGNORE_DEPRECATED_POP
/* [compressIndices-offset] */
Containers::ArrayView<const UnsignedInt> indices;
UnsignedInt offset = Math::min(indices);
std::pair<Containers::Array<char>, MeshIndexType> result =
Containers::Pair<Containers::Array<char>, MeshIndexType> compressed =
MeshTools::compressIndices(indices, offset);
// use `offset` to adjust vertex attribute offset …
@ -153,11 +153,9 @@ Trade::MeshData indexed{data.primitive(),
/* [removeDuplicates] */
Containers::ArrayView<Vector3i> data;
std::size_t size;
Containers::Array<UnsignedInt> indices;
std::tie(indices, size) = MeshTools::removeDuplicatesInPlace(
Containers::arrayCast<2, char>(data));
data = data.prefix(size);
Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> unique =
MeshTools::removeDuplicatesInPlace(Containers::arrayCast<2, char>(data));
data = data.prefix(unique.second());
/* [removeDuplicates] */
}

33
src/Magnum/MeshTools/CompressIndices.cpp

@ -27,6 +27,7 @@
#include <cstring>
#include <Corrade/Containers/Array.h>
#include <Corrade/Containers/Pair.h>
#include <Corrade/Utility/Algorithms.h>
#include "Magnum/Math/FunctionsBatch.h"
@ -54,10 +55,10 @@ template<class T, class U> inline Containers::Array<char> compress(const Contain
return buffer;
}
template<class T> std::pair<Containers::Array<char>, MeshIndexType> compressIndicesImplementation(const Containers::StridedArrayView1D<const T>& indices, const MeshIndexType atLeast, const Long offset) {
template<class T> Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndicesImplementation(const Containers::StridedArrayView1D<const T>& indices, const MeshIndexType atLeast, const Long offset) {
CORRADE_ASSERT(!isMeshIndexTypeImplementationSpecific(atLeast),
"MeshTools::compressIndices(): can't compress to an implementation-specific index type" << reinterpret_cast<void*>(meshIndexTypeUnwrap(atLeast)),
(std::pair<Containers::Array<char>, MeshIndexType>{nullptr, MeshIndexType::UnsignedInt}));
(Containers::Pair<Containers::Array<char>, MeshIndexType>{nullptr, MeshIndexType::UnsignedInt}));
const UnsignedInt max = Math::max(indices) - offset;
Containers::Array<char> out;
@ -86,31 +87,31 @@ template<class T> std::pair<Containers::Array<char>, MeshIndexType> compressIndi
}
std::pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const MeshIndexType atLeast, const Long offset) {
Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const MeshIndexType atLeast, const Long offset) {
return compressIndicesImplementation(indices, atLeast, offset);
}
std::pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const MeshIndexType atLeast, const Long offset) {
Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const MeshIndexType atLeast, const Long offset) {
return compressIndicesImplementation(indices, atLeast, offset);
}
std::pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const MeshIndexType atLeast, const Long offset) {
Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const MeshIndexType atLeast, const Long offset) {
return compressIndicesImplementation(indices, atLeast, offset);
}
std::pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Long offset) {
Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Long offset) {
return compressIndicesImplementation(indices, MeshIndexType::UnsignedShort, offset);
}
std::pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Long offset) {
Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, const Long offset) {
return compressIndicesImplementation(indices, MeshIndexType::UnsignedShort, offset);
}
std::pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Long offset) {
Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, const Long offset) {
return compressIndicesImplementation(indices, MeshIndexType::UnsignedShort, offset);
}
std::pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView2D<const char>& indices, const MeshIndexType atLeast, const Long offset) {
Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView2D<const char>& indices, const MeshIndexType atLeast, const Long offset) {
CORRADE_ASSERT(indices.isContiguous<1>(), "MeshTools::compressIndices(): second view dimension is not contiguous", {});
if(indices.size()[1] == 4)
return compressIndicesImplementation(Containers::arrayCast<1, const UnsignedInt>(indices), atLeast, offset);
@ -122,7 +123,7 @@ std::pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containe
}
}
std::pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView2D<const char>& indices, const Long offset) {
Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView2D<const char>& indices, const Long offset) {
return compressIndices(indices, MeshIndexType::UnsignedShort, offset);
}
@ -142,7 +143,7 @@ Trade::MeshData compressIndices(Trade::MeshData&& data, MeshIndexType atLeast) {
/* Compress the indices */
UnsignedInt offset;
std::pair<Containers::Array<char>, MeshIndexType> result;
Containers::Pair<Containers::Array<char>, MeshIndexType> result;
if(data.indexType() == MeshIndexType::UnsignedInt) {
auto indices = data.indices<UnsignedInt>();
offset = Math::min(indices);
@ -172,8 +173,8 @@ Trade::MeshData compressIndices(Trade::MeshData&& data, MeshIndexType atLeast) {
data.attributeArraySize(i)};
}
Trade::MeshIndexData indices{result.second, result.first};
return Trade::MeshData{data.primitive(), std::move(result.first), indices,
Trade::MeshIndexData indices{result.second(), result.first()};
return Trade::MeshData{data.primitive(), std::move(result.first()), indices,
std::move(vertexData), std::move(attributeData), newVertexCount};
}
@ -186,10 +187,8 @@ Trade::MeshData compressIndices(const Trade::MeshData& data, MeshIndexType atLea
#ifdef MAGNUM_BUILD_DEPRECATED
std::tuple<Containers::Array<char>, MeshIndexType, UnsignedInt, UnsignedInt> compressIndices(const std::vector<UnsignedInt>& indices) {
const auto minmax = Math::minmax(indices);
Containers::Array<char> data;
MeshIndexType type;
std::tie(data, type) = compressIndices(indices, MeshIndexType::UnsignedByte);
return std::make_tuple(std::move(data), type, minmax.first, minmax.second);
Containers::Pair<Containers::Array<char>, MeshIndexType> dataType = compressIndices(indices, MeshIndexType::UnsignedByte);
return std::make_tuple(std::move(dataType.first()), dataType.second(), minmax.first, minmax.second);
}
template<class T> Containers::Array<T> compressIndicesAs(const std::vector<UnsignedInt>& indices) {

20
src/Magnum/MeshTools/CompressIndices.h

@ -29,7 +29,6 @@
* @brief Function @ref Magnum::MeshTools::compressIndices()
*/
#include <utility>
#include <Corrade/Containers/Containers.h>
#include "Magnum/Mesh.h"
@ -40,6 +39,9 @@
#include <Corrade/Utility/Macros.h>
#include <Corrade/Utility/StlForwardVector.h>
#include <Corrade/Utility/StlForwardTuple.h>
/* The APIs used to return std::pair before */
#include <Corrade/Containers/PairStl.h>
#endif
namespace Magnum { namespace MeshTools {
@ -79,19 +81,19 @@ operation directly on a @ref Trade::MeshData instance.
The @p atLeast parameter is expected to not be an implementation-specific type.
@see @ref isMeshIndexTypeImplementationSpecific()
*/
MAGNUM_MESHTOOLS_EXPORT std::pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0);
MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0);
/**
@overload
@m_since{2020,06}
*/
MAGNUM_MESHTOOLS_EXPORT std::pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0);
MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0);
/**
@overload
@m_since{2020,06}
*/
MAGNUM_MESHTOOLS_EXPORT std::pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0);
MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0);
/**
@overload
@ -100,7 +102,7 @@ MAGNUM_MESHTOOLS_EXPORT std::pair<Containers::Array<char>, MeshIndexType> compre
Same as @ref compressIndices(const Containers::StridedArrayView1D<const UnsignedInt>&, MeshIndexType, Long)
with @p atLeast set to @ref MeshIndexType::UnsignedShort.
*/
MAGNUM_MESHTOOLS_EXPORT std::pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, Long offset);
MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedInt>& indices, Long offset);
/**
@overload
@ -109,7 +111,7 @@ MAGNUM_MESHTOOLS_EXPORT std::pair<Containers::Array<char>, MeshIndexType> compre
Same as @ref compressIndices(const Containers::StridedArrayView1D<const UnsignedShort>&, MeshIndexType, Long)
with @p atLeast set to @ref MeshIndexType::UnsignedShort.
*/
MAGNUM_MESHTOOLS_EXPORT std::pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, Long offset);
MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedShort>& indices, Long offset);
/**
@overload
@ -118,7 +120,7 @@ MAGNUM_MESHTOOLS_EXPORT std::pair<Containers::Array<char>, MeshIndexType> compre
Same as @ref compressIndices(const Containers::StridedArrayView1D<const UnsignedByte>&, MeshIndexType, Long)
with @p atLeast set to @ref MeshIndexType::UnsignedShort.
*/
MAGNUM_MESHTOOLS_EXPORT std::pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, Long offset);
MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView1D<const UnsignedByte>& indices, Long offset);
/**
@brief Compress a type-erased index array
@ -132,7 +134,7 @@ etc. overloads.
The @p atLeast parameter is expected to not be an implementation-specific type.
@see @ref isMeshIndexTypeImplementationSpecific()
*/
MAGNUM_MESHTOOLS_EXPORT std::pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView2D<const char>& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0);
MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView2D<const char>& indices, MeshIndexType atLeast = MeshIndexType::UnsignedShort, Long offset = 0);
/**
@overload
@ -141,7 +143,7 @@ MAGNUM_MESHTOOLS_EXPORT std::pair<Containers::Array<char>, MeshIndexType> compre
Same as @ref compressIndices(const Containers::StridedArrayView2D<const char>&, MeshIndexType, Long)
with @p atLeast set to @ref MeshIndexType::UnsignedShort.
*/
MAGNUM_MESHTOOLS_EXPORT std::pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView2D<const char>& indices, Long offset);
MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<char>, MeshIndexType> compressIndices(const Containers::StridedArrayView2D<const char>& indices, Long offset);
/**
@brief Compress mesh data indices

17
src/Magnum/MeshTools/RemoveDuplicates.cpp

@ -30,6 +30,7 @@
#include <numeric>
#include <unordered_map>
#include <Corrade/Containers/Array.h>
#include <Corrade/Containers/Pair.h>
#include <Corrade/Containers/StridedArrayView.h>
#include <Corrade/Utility/Algorithms.h>
#include <Corrade/Utility/MurmurHash2.h>
@ -97,7 +98,7 @@ std::size_t removeDuplicatesInto(const Containers::StridedArrayView2D<const char
return table.size();
}
std::pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicates(const Containers::StridedArrayView2D<const char>& data) {
Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicates(const Containers::StridedArrayView2D<const char>& data) {
Containers::Array<UnsignedInt> indices{NoInit, data.size()[0]};
const std::size_t size = removeDuplicatesInto(data, indices);
return {std::move(indices), size};
@ -155,7 +156,7 @@ std::size_t removeDuplicatesInPlaceInto(const Containers::StridedArrayView2D<cha
return table.size();
}
std::pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicatesInPlace(const Containers::StridedArrayView2D<char>& data) {
Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicatesInPlace(const Containers::StridedArrayView2D<char>& data) {
Containers::Array<UnsignedInt> indices{NoInit, data.size()[0]};
const std::size_t size = removeDuplicatesInPlaceInto(data, indices);
return {std::move(indices), size};
@ -174,9 +175,9 @@ template<class IndexType> std::size_t removeDuplicatesIndexedInPlaceImplementati
original order, which is an useful property. The float version has this
inverted (having the *Indexed() variant as the main implementation)
because the remapping there has to be done once for every dimension. */
std::pair<Containers::Array<UnsignedInt>, std::size_t> result = removeDuplicatesInPlace(data);
for(auto& i: indices) i = result.first[i];
return result.second;
const Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> result = removeDuplicatesInPlace(data);
for(auto& i: indices) i = result.first()[i];
return result.second();
}
}
@ -348,7 +349,7 @@ template<class T> std::size_t removeDuplicatesFuzzyInPlaceIntoImplementation(con
return size;
}
template<class T> std::pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicatesFuzzyInPlaceImplementation(const Containers::StridedArrayView2D<T>& data, const T epsilon) {
template<class T> Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicatesFuzzyInPlaceImplementation(const Containers::StridedArrayView2D<T>& data, const T epsilon) {
Containers::Array<UnsignedInt> indices{NoInit, data.size()[0]};
const std::size_t size = removeDuplicatesFuzzyInPlaceIntoImplementation(data, indices, epsilon);
return {std::move(indices), size};
@ -356,11 +357,11 @@ template<class T> std::pair<Containers::Array<UnsignedInt>, std::size_t> removeD
}
std::pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicatesFuzzyInPlace(const Containers::StridedArrayView2D<Float>& data, const Float epsilon) {
Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicatesFuzzyInPlace(const Containers::StridedArrayView2D<Float>& data, const Float epsilon) {
return removeDuplicatesFuzzyInPlaceImplementation(data, epsilon);
}
std::pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicatesFuzzyInPlace(const Containers::StridedArrayView2D<Double>& data, const Double epsilon) {
Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicatesFuzzyInPlace(const Containers::StridedArrayView2D<Double>& data, const Double epsilon) {
return removeDuplicatesFuzzyInPlaceImplementation(data, epsilon);
}

13
src/Magnum/MeshTools/RemoveDuplicates.h

@ -29,8 +29,6 @@
* @brief Function @ref Magnum::MeshTools::removeDuplicatesInPlace(), @ref Magnum::MeshTools::removeDuplicatesIndexedInPlace()
*/
#include <utility>
#include "Magnum/Magnum.h"
#include "Magnum/Math/TypeTraits.h"
#include "Magnum/MeshTools/visibility.h"
@ -40,6 +38,9 @@
#include <vector>
#include <Corrade/Containers/ArrayViewStl.h>
#include <Corrade/Containers/StridedArrayView.h>
/* The function used to return a std::pair */
#include <Corrade/Containers/PairStl.h>
#endif
namespace Magnum { namespace MeshTools {
@ -68,7 +69,7 @@ an index array pointing to original data locations.
@see @ref Corrade::Containers::StridedArrayView::isContiguous(),
@ref removeDuplicatesInPlaceInto()
*/
MAGNUM_MESHTOOLS_EXPORT std::pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicatesInPlace(const Containers::StridedArrayView2D<char>& data);
MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicatesInPlace(const Containers::StridedArrayView2D<char>& data);
/**
@brief Remove duplicate data from given array in-place into given output index array
@ -95,7 +96,7 @@ Compared to @ref removeDuplicatesInPlace(const Containers::StridedArrayView2D<ch
this function doesn't modify the input data array in any way but instead
returns an index array pointing to original data locations.
*/
MAGNUM_MESHTOOLS_EXPORT std::pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicates(const Containers::StridedArrayView2D<const char>& data);
MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicates(const Containers::StridedArrayView2D<const char>& data);
/**
@brief Remove duplicate data from given array into given output index array
@ -173,13 +174,13 @@ If you want to remove duplicates in multiple incidental arrays, first remove
duplicates in each array separately and then combine the resulting index arrays
back into a single one using @ref combineIndexedAttributes().
*/
MAGNUM_MESHTOOLS_EXPORT std::pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicatesFuzzyInPlace(const Containers::StridedArrayView2D<Float>& data, Float epsilon = Math::TypeTraits<Float>::epsilon());
MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicatesFuzzyInPlace(const Containers::StridedArrayView2D<Float>& data, Float epsilon = Math::TypeTraits<Float>::epsilon());
/**
* @overload
* @m_since{2020,06}
*/
MAGNUM_MESHTOOLS_EXPORT std::pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicatesFuzzyInPlace(const Containers::StridedArrayView2D<Double>& data, Double epsilon = Math::TypeTraits<Double>::epsilon());
MAGNUM_MESHTOOLS_EXPORT Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> removeDuplicatesFuzzyInPlace(const Containers::StridedArrayView2D<Double>& data, Double epsilon = Math::TypeTraits<Double>::epsilon());
/**
@brief Remove duplicate data from given array using fuzzy comparison in-place into given output index array

57
src/Magnum/MeshTools/Test/CompressIndicesTest.cpp

@ -25,6 +25,7 @@
#include <sstream>
#include <Corrade/Containers/Array.h>
#include <Corrade/Containers/Pair.h>
#include <Corrade/Containers/StridedArrayView.h>
#include <Corrade/TestSuite/Tester.h>
#include <Corrade/TestSuite/Compare/Container.h>
@ -105,19 +106,19 @@ template<class T> void CompressIndicesTest::compressUnsignedByte() {
const T indices[]{1, 2, 3, 0, 4};
/* By default it has 16-byte type as minimum, override */
std::pair<Containers::Array<char>, MeshIndexType> out =
Containers::Pair<Containers::Array<char>, MeshIndexType> out =
compressIndices(indices, MeshIndexType::UnsignedByte);
CORRADE_COMPARE(out.second, MeshIndexType::UnsignedByte);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedByte>(out.first),
CORRADE_COMPARE(out.second(), MeshIndexType::UnsignedByte);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedByte>(out.first()),
Containers::arrayView<UnsignedByte>({1, 2, 3, 0, 4}),
TestSuite::Compare::Container);
/* Test the type-erased variant as well */
out = compressIndices(Containers::arrayCast<2, const char>(Containers::stridedArrayView(indices)), MeshIndexType::UnsignedByte);
CORRADE_COMPARE(out.second, MeshIndexType::UnsignedByte);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedByte>(out.first),
CORRADE_COMPARE(out.second(), MeshIndexType::UnsignedByte);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedByte>(out.first()),
Containers::arrayView<UnsignedByte>({1, 2, 3, 0, 4}),
TestSuite::Compare::Container);
}
@ -126,18 +127,18 @@ template<class T> void CompressIndicesTest::compressUnsignedShort() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
const T indices[]{1, 256, 0, 5};
std::pair<Containers::Array<char>, MeshIndexType> out = compressIndices(indices);
Containers::Pair<Containers::Array<char>, MeshIndexType> out = compressIndices(indices);
CORRADE_COMPARE(out.second, MeshIndexType::UnsignedShort);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedShort>(out.first),
CORRADE_COMPARE(out.second(), MeshIndexType::UnsignedShort);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedShort>(out.first()),
Containers::arrayView<UnsignedShort>({1, 256, 0, 5}),
TestSuite::Compare::Container);
/* Test the type-erased variant as well */
out = compressIndices(Containers::arrayCast<2, const char>(Containers::stridedArrayView(indices)));
CORRADE_COMPARE(out.second, MeshIndexType::UnsignedShort);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedShort>(out.first),
CORRADE_COMPARE(out.second(), MeshIndexType::UnsignedShort);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedShort>(out.first()),
Containers::arrayView<UnsignedShort>({1, 256, 0, 5}),
TestSuite::Compare::Container);
}
@ -146,18 +147,18 @@ template<class T> void CompressIndicesTest::compressUnsignedInt() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
const T indices[]{65536, 3, 2};
std::pair<Containers::Array<char>, MeshIndexType> out = compressIndices(indices);
Containers::Pair<Containers::Array<char>, MeshIndexType> out = compressIndices(indices);
CORRADE_COMPARE(out.second, MeshIndexType::UnsignedInt);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedInt>(out.first),
CORRADE_COMPARE(out.second(), MeshIndexType::UnsignedInt);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedInt>(out.first()),
Containers::arrayView<UnsignedInt>({65536, 3, 2}),
TestSuite::Compare::Container);
/* Test the type-erased variant as well */
out = compressIndices(Containers::arrayCast<2, const char>(Containers::stridedArrayView(indices)));
CORRADE_COMPARE(out.second, MeshIndexType::UnsignedInt);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedInt>(out.first),
CORRADE_COMPARE(out.second(), MeshIndexType::UnsignedInt);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedInt>(out.first()),
Containers::arrayView<UnsignedInt>({65536, 3, 2}),
TestSuite::Compare::Container);
}
@ -165,28 +166,28 @@ template<class T> void CompressIndicesTest::compressUnsignedInt() {
void CompressIndicesTest::compressUnsignedByteInflateToShort() {
const UnsignedByte indices[]{1, 2, 3, 0, 4};
/* That's the default */
std::pair<Containers::Array<char>, MeshIndexType> out = compressIndices(indices);
Containers::Pair<Containers::Array<char>, MeshIndexType> out = compressIndices(indices);
CORRADE_COMPARE(out.second, MeshIndexType::UnsignedShort);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedShort>(out.first),
CORRADE_COMPARE(out.second(), MeshIndexType::UnsignedShort);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedShort>(out.first()),
Containers::arrayView<UnsignedShort>({1, 2, 3, 0, 4}),
TestSuite::Compare::Container);
}
void CompressIndicesTest::compressOffset() {
const UnsignedInt indices[]{75000 + 1, 75000 + 256, 75000 + 0, 75000 + 5};
std::pair<Containers::Array<char>, MeshIndexType> out = compressIndices(indices, 75000);
Containers::Pair<Containers::Array<char>, MeshIndexType> out = compressIndices(indices, 75000);
CORRADE_COMPARE(out.second, MeshIndexType::UnsignedShort);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedShort>(out.first),
CORRADE_COMPARE(out.second(), MeshIndexType::UnsignedShort);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedShort>(out.first()),
Containers::arrayView<UnsignedShort>({1, 256, 0, 5}),
TestSuite::Compare::Container);
/* Test the type-erased variant as well */
out = compressIndices(Containers::arrayCast<2, const char>(Containers::stridedArrayView(indices)), 75000);
CORRADE_COMPARE(out.second, MeshIndexType::UnsignedShort);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedShort>(out.first),
CORRADE_COMPARE(out.second(), MeshIndexType::UnsignedShort);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedShort>(out.first()),
Containers::arrayView<UnsignedShort>({1, 256, 0, 5}),
TestSuite::Compare::Container);
}
@ -195,18 +196,18 @@ template<class T> void CompressIndicesTest::compressOffsetNegative() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
const T indices[]{1, 255, 0, 5};
std::pair<Containers::Array<char>, MeshIndexType> out = compressIndices(indices, -75000);
Containers::Pair<Containers::Array<char>, MeshIndexType> out = compressIndices(indices, -75000);
CORRADE_COMPARE(out.second, MeshIndexType::UnsignedInt);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedInt>(out.first),
CORRADE_COMPARE(out.second(), MeshIndexType::UnsignedInt);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedInt>(out.first()),
Containers::arrayView<UnsignedInt>({75000 + 1, 75000 + 255, 75000 + 0, 75000 + 5}),
TestSuite::Compare::Container);
/* Test the type-erased variant as well */
out = compressIndices(Containers::arrayCast<2, const char>(Containers::stridedArrayView(indices)), -75000);
CORRADE_COMPARE(out.second, MeshIndexType::UnsignedInt);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedInt>(out.first),
CORRADE_COMPARE(out.second(), MeshIndexType::UnsignedInt);
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedInt>(out.first()),
Containers::arrayView<UnsignedInt>({75000 + 1, 75000 + 255, 75000 + 0, 75000 + 5}),
TestSuite::Compare::Container);
}

28
src/Magnum/MeshTools/Test/RemoveDuplicatesTest.cpp

@ -27,6 +27,7 @@
#include <random> /* random device for std::shuffle() */
#include <sstream>
#include <Corrade/Containers/GrowableArray.h>
#include <Corrade/Containers/Pair.h>
#include <Corrade/TestSuite/Tester.h>
#include <Corrade/TestSuite/Compare/Container.h>
#include <Corrade/Utility/DebugStl.h>
@ -266,18 +267,19 @@ RemoveDuplicatesTest::RemoveDuplicatesTest() {
void RemoveDuplicatesTest::removeDuplicates() {
Int data[]{-15, 32, 24, -15, 15, 7541, 24, 32};
std::pair<Containers::Array<UnsignedInt>, std::size_t> result =
Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> result =
MeshTools::removeDuplicates(Containers::arrayCast<2, char>(Containers::arrayView(data)));
CORRADE_COMPARE_AS(Containers::arrayView(result.first),
CORRADE_COMPARE_AS(Containers::arrayView(result.first()),
Containers::arrayView<UnsignedInt>({0, 1, 2, 0, 4, 5, 2, 1}),
TestSuite::Compare::Container);
CORRADE_COMPARE(result.second(), 5);
std::pair<Containers::Array<UnsignedInt>, std::size_t> resultInPlace =
Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> resultInPlace =
MeshTools::removeDuplicatesInPlace(Containers::arrayCast<2, char>(Containers::arrayView(data)));
CORRADE_COMPARE_AS(Containers::arrayView(resultInPlace.first),
CORRADE_COMPARE_AS(Containers::arrayView(resultInPlace.first()),
Containers::arrayView<UnsignedInt>({0, 1, 2, 0, 3, 4, 2, 1}),
TestSuite::Compare::Container);
CORRADE_COMPARE_AS(Containers::arrayView(data).prefix(resultInPlace.second),
CORRADE_COMPARE_AS(Containers::arrayView(data).prefix(resultInPlace.second()),
Containers::arrayView<Int>({-15, 32, 24, 15, 7541}),
TestSuite::Compare::Container);
}
@ -421,14 +423,14 @@ template<class T> void RemoveDuplicatesTest::removeDuplicatesFuzzyInPlaceOneDime
T(3.4) /* bucket 3 in 1st iteration, bucket 3 in 2nd */
};
std::pair<Containers::Array<UnsignedInt>, std::size_t> result =
Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> result =
MeshTools::removeDuplicatesFuzzyInPlace(
Containers::arrayCast<2, T>(Containers::stridedArrayView(data)),
T(1.00001));
CORRADE_COMPARE_AS(Containers::arrayView(result.first),
CORRADE_COMPARE_AS(Containers::arrayView(result.first()),
Containers::arrayView<UnsignedInt>({0, 1, 0, 1}),
TestSuite::Compare::Container);
CORRADE_COMPARE_AS(Containers::arrayView(data).prefix(result.second),
CORRADE_COMPARE_AS(Containers::arrayView(data).prefix(result.second()),
(Containers::arrayView<T>({T(1.0), T(2.9)})),
TestSuite::Compare::Container);
}
@ -446,14 +448,14 @@ template<class T> void RemoveDuplicatesTest::removeDuplicatesFuzzyInPlaceMoreDim
{T(1.0), T(5.0)}
};
std::pair<Containers::Array<UnsignedInt>, std::size_t> result =
Containers::Pair<Containers::Array<UnsignedInt>, std::size_t> result =
MeshTools::removeDuplicatesFuzzyInPlace(
Containers::arrayCast<2, T>(Containers::stridedArrayView(data)),
T(2.0));
CORRADE_COMPARE_AS(Containers::arrayView(result.first),
CORRADE_COMPARE_AS(Containers::arrayView(result.first()),
Containers::arrayView<UnsignedInt>({0, 0, 1, 1}),
TestSuite::Compare::Container);
CORRADE_COMPARE_AS(Containers::arrayView(data).prefix(result.second),
CORRADE_COMPARE_AS(Containers::arrayView(data).prefix(result.second()),
Containers::arrayView<Math::Vector2<T>>({{T(1.0), T(0.0)}, {T(0.0), T(4.0)}}),
TestSuite::Compare::Container);
}
@ -1215,7 +1217,7 @@ void RemoveDuplicatesTest::soakTest() {
CORRADE_COMPARE(MeshTools::removeDuplicatesInPlace(
Containers::StridedArrayView2D<char>{
Containers::arrayCast<char>(Containers::arrayView(data)), {1000, 4}}
).second, 100);
).second(), 100);
}
void RemoveDuplicatesTest::soakTestFuzzy() {
@ -1226,7 +1228,7 @@ void RemoveDuplicatesTest::soakTestFuzzy() {
std::shuffle(std::begin(data), std::end(data), std::minstd_rand{std::random_device{}()});
CORRADE_COMPARE(MeshTools::removeDuplicatesFuzzyInPlace(
Containers::arrayCast<2, Float>(Containers::arrayView(data))).second,
Containers::arrayCast<2, Float>(Containers::arrayView(data))).second(),
100);
}

Loading…
Cancel
Save