Browse Source

MeshTools: return filled size from interleaveInto().

This ancient API is still useful somewhat I guess, so let's make it less
annoying to use. And also test it properly, including the assert.
pull/659/head
Vladimír Vondruš 2 years ago
parent
commit
3f5e2e2268
  1. 1
      doc/changelog.dox
  2. 10
      src/Magnum/MeshTools/Interleave.h
  3. 51
      src/Magnum/MeshTools/Test/InterleaveTest.cpp

1
doc/changelog.dox

@ -746,6 +746,7 @@ See also:
@ref MeshTools::concatenate(const Containers::Iterable<const Trade::MeshData>&, InterleaveFlags)
optionally take a @ref MeshTools::InterleaveFlags parameter affecting the
output, in particular whether to preserve the original interleaved layout.
- @ref MeshTools::interleaveInto() now returns the actually filled size
- @ref MeshTools::concatenate() now allows concatenating an array attribute
into an array attribute with more elements. The remaining elements are
zero-filled, similarly to how missing attributes are handled. To avoid

10
src/Magnum/MeshTools/Interleave.h

@ -171,6 +171,7 @@ template<class T, class ...U
/**
@brief Interleave vertex attributes into existing buffer
@return Filled buffer size
Unlike @ref interleave() this function interleaves the data into existing
buffer and leaves gaps untouched instead of zero-initializing them. This
@ -178,16 +179,17 @@ function can thus be used for interleaving data depending on runtime
parameters. Expects that all arrays have the same size and the passed buffer is
large enough to contain the interleaved data.
*/
template<class T, class ...U> void interleaveInto(Containers::ArrayView<char> buffer, const T& first, const U&... next) {
template<class T, class ...U> std::size_t interleaveInto(Containers::ArrayView<char> buffer, const T& first, const U&... next) {
/* Verify expected buffer size */
#ifndef CORRADE_NO_ASSERT
const std::size_t attributeCount = Implementation::AttributeCount{}(first, next...);
#endif
const std::size_t stride = Implementation::Stride{}(first, next...);
CORRADE_ASSERT(attributeCount*stride <= buffer.size(), "MeshTools::interleaveInto(): the data buffer is too small, expected" << attributeCount*stride << "but got" << buffer.size(), );
CORRADE_ASSERT(attributeCount*stride <= buffer.size(),
"MeshTools::interleaveInto(): expected a buffer of at least" << attributeCount*stride << "bytes but got" << buffer.size(), {});
/* Write data */
Implementation::writeInterleaved(stride, buffer.begin(), first, next...);
return attributeCount*stride;
}
/**

51
src/Magnum/MeshTools/Test/InterleaveTest.cpp

@ -56,6 +56,8 @@ struct InterleaveTest: Corrade::TestSuite::Tester {
void interleaveEmpty();
void interleaveInto();
void interleaveIntoLarger();
void interleaveIntoInvalid();
void interleavedData();
void interleavedDataUnordered();
@ -142,6 +144,8 @@ InterleaveTest::InterleaveTest() {
&InterleaveTest::interleaveEmpty,
&InterleaveTest::interleaveInto,
&InterleaveTest::interleaveIntoLarger,
&InterleaveTest::interleaveIntoInvalid,
&InterleaveTest::interleavedData,
&InterleaveTest::interleavedDataUnordered,
@ -293,7 +297,8 @@ void InterleaveTest::interleaveInto() {
0x11, 0x33, 0x55, 0x77, 0x11, 0x33, 0x55, 0x77, 0x11, 0x33, 0x55, 0x77,
0x11, 0x33, 0x55, 0x77, 0x11, 0x33, 0x55, 0x77, 0x11, 0x33, 0x55, 0x77}};
MeshTools::interleaveInto(data, 2, std::vector<Int>{4, 5, 6, 7}, 1, std::vector<Short>{0, 1, 2, 3}, 3);
CORRADE_COMPARE(data.size(), 48);
CORRADE_COMPARE(MeshTools::interleaveInto(data, 2, std::vector<Int>{4, 5, 6, 7}, 1, std::vector<Short>{0, 1, 2, 3}, 3), 48);
if(!Utility::Endianness::isBigEndian()) {
/* _______gap, int___________________, _gap, short_____, _____________gap */
@ -314,6 +319,50 @@ void InterleaveTest::interleaveInto() {
}
}
void InterleaveTest::interleaveIntoLarger() {
/* Same as interleaveInto(), just with the data buffer being larger */
Containers::Array<char> data{InPlaceInit, {
0x11, 0x33, 0x55, 0x77, 0x11, 0x33, 0x55, 0x77, 0x11, 0x33, 0x55, 0x77,
0x11, 0x33, 0x55, 0x77, 0x11, 0x33, 0x55, 0x77, 0x11, 0x33, 0x55, 0x77,
0x11, 0x33, 0x55, 0x77, 0x11, 0x33, 0x55, 0x77, 0x11, 0x33, 0x55, 0x77,
0x11, 0x33, 0x55, 0x77, 0x11, 0x33, 0x55, 0x77, 0x11, 0x33, 0x55, 0x77, 0x11}};
CORRADE_COMPARE(data.size(), 49);
CORRADE_COMPARE(MeshTools::interleaveInto(data, 2, std::vector<Int>{4, 5, 6, 7}, 1, std::vector<Short>{0, 1, 2, 3}, 3), 48);
if(!Utility::Endianness::isBigEndian()) {
/* _______gap, int___________________, _gap, short_____, _____________gap */
CORRADE_COMPARE(std::vector<char>(data.begin(), data.end()), (std::vector<char>{
0x11, 0x33, 0x04, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x33, 0x55, 0x77,
0x11, 0x33, 0x05, 0x00, 0x00, 0x00, 0x55, 0x01, 0x00, 0x33, 0x55, 0x77,
0x11, 0x33, 0x06, 0x00, 0x00, 0x00, 0x55, 0x02, 0x00, 0x33, 0x55, 0x77,
0x11, 0x33, 0x07, 0x00, 0x00, 0x00, 0x55, 0x03, 0x00, 0x33, 0x55, 0x77,
0x11
}));
} else {
/* _______gap, ___________________int, _gap, _____short, _____________gap */
CORRADE_COMPARE(std::vector<char>(data.begin(), data.end()), (std::vector<char>{
0x11, 0x33, 0x00, 0x00, 0x00, 0x04, 0x55, 0x00, 0x00, 0x33, 0x55, 0x77,
0x11, 0x33, 0x00, 0x00, 0x00, 0x05, 0x55, 0x00, 0x01, 0x33, 0x55, 0x77,
0x11, 0x33, 0x00, 0x00, 0x00, 0x06, 0x55, 0x00, 0x02, 0x33, 0x55, 0x77,
0x11, 0x33, 0x00, 0x00, 0x00, 0x07, 0x55, 0x00, 0x03, 0x33, 0x55, 0x77,
0x11
}));
}
}
void InterleaveTest::interleaveIntoInvalid() {
CORRADE_SKIP_IF_NO_ASSERT();
Containers::Array<char> data{NoInit, 23};
std::ostringstream out;
Error redirectError{&out};
MeshTools::interleaveInto(data, 2, Containers::arrayView({1, 2, 3, 4}));
CORRADE_COMPARE(out.str(), "MeshTools::interleaveInto(): expected a buffer of at least 24 bytes but got 23\n");
}
void InterleaveTest::interleavedData() {
Containers::Array<char> vertexData{100 + 3*20};
Containers::StridedArrayView1D<Vector2> positions{vertexData,

Loading…
Cancel
Save