Browse Source

Using fixed-size 32bit integer type for indices.

vectorfields
Vladimír Vondruš 14 years ago
parent
commit
8f5940dd56
  1. 10
      src/MeshTools/Clean.h
  2. 24
      src/MeshTools/CombineIndexedArrays.h
  3. 2
      src/MeshTools/CompressIndices.cpp
  4. 20
      src/MeshTools/CompressIndices.h
  5. 2
      src/MeshTools/FlipNormals.cpp
  6. 9
      src/MeshTools/FlipNormals.h
  7. 6
      src/MeshTools/GenerateFlatNormals.cpp
  8. 7
      src/MeshTools/GenerateFlatNormals.h
  9. 12
      src/MeshTools/Subdivide.h
  10. 4
      src/MeshTools/Test/CleanTest.cpp
  11. 34
      src/MeshTools/Test/CombineIndexedArraysTest.cpp
  12. 6
      src/MeshTools/Test/CompressIndicesTest.cpp
  13. 8
      src/MeshTools/Test/FlipNormalsTest.cpp
  14. 6
      src/MeshTools/Test/GenerateFlatNormalsTest.cpp
  15. 6
      src/MeshTools/Test/SubdivideTest.cpp
  16. 2
      src/MeshTools/Test/TipsifyTest.cpp
  17. 2
      src/MeshTools/Test/TipsifyTest.h
  18. 38
      src/MeshTools/Tipsify.cpp
  19. 12
      src/MeshTools/Tipsify.h
  20. 12
      src/Primitives/Capsule.cpp
  21. 2
      src/Primitives/Cube.cpp
  22. 2
      src/Primitives/Icosphere.cpp
  23. 4
      src/Primitives/Test/CapsuleTest.cpp
  24. 4
      src/Primitives/Test/CylinderTest.cpp
  25. 4
      src/Primitives/Test/UVSphereTest.cpp
  26. 8
      src/Trade/MeshData2D.h
  27. 8
      src/Trade/MeshData3D.h

10
src/MeshTools/Clean.h

@ -33,7 +33,7 @@ namespace Implementation {
template<class Vertex, std::size_t vertexSize = Vertex::Size> class Clean {
public:
inline Clean(std::vector<unsigned int>& indices, std::vector<Vertex>& vertices): indices(indices), vertices(vertices) {}
inline Clean(std::vector<std::uint32_t>& indices, std::vector<Vertex>& vertices): indices(indices), vertices(vertices) {}
void operator()(typename Vertex::Type epsilon = TypeTraits<typename Vertex::Type>::epsilon()) {
if(indices.empty()) return;
@ -108,12 +108,12 @@ template<class Vertex, std::size_t vertexSize = Vertex::Size> class Clean {
};
struct HashedVertex {
unsigned int oldIndex, newIndex;
std::uint32_t oldIndex, newIndex;
HashedVertex(unsigned int oldIndex, unsigned int newIndex): oldIndex(oldIndex), newIndex(newIndex) {}
HashedVertex(std::uint32_t oldIndex, std::uint32_t newIndex): oldIndex(oldIndex), newIndex(newIndex) {}
};
std::vector<unsigned int>& indices;
std::vector<std::uint32_t>& indices;
std::vector<Vertex>& vertices;
};
@ -137,7 +137,7 @@ Removes duplicate vertices from the mesh.
@todo Interpolate vertices, not collapse them to first in the cell
@todo Ability to specify other attributes for interpolation
*/
template<class Vertex, std::size_t vertexSize = Vertex::Size> inline void clean(std::vector<unsigned int>& indices, std::vector<Vertex>& vertices, typename Vertex::Type epsilon = TypeTraits<typename Vertex::Type>::epsilon()) {
template<class Vertex, std::size_t vertexSize = Vertex::Size> inline void clean(std::vector<std::uint32_t>& indices, std::vector<Vertex>& vertices, typename Vertex::Type epsilon = TypeTraits<typename Vertex::Type>::epsilon()) {
Implementation::Clean<Vertex, vertexSize>(indices, vertices)(epsilon);
}

24
src/MeshTools/CombineIndexedArrays.h

@ -33,17 +33,17 @@ namespace Implementation {
class CombineIndexedArrays {
public:
template<class ...T> std::vector<unsigned int> operator()(const std::tuple<const std::vector<unsigned int>&, std::vector<T>&>&... indexedArrays) {
template<class ...T> std::vector<std::uint32_t> operator()(const std::tuple<const std::vector<std::uint32_t>&, std::vector<T>&>&... indexedArrays) {
/* Compute index count */
std::size_t _indexCount = indexCount(std::get<0>(indexedArrays)...);
/* Resulting index array */
std::vector<unsigned int> result;
std::vector<std::uint32_t> result;
result.resize(_indexCount);
std::iota(result.begin(), result.end(), 0);
/* All index combinations */
std::vector<Math::Vector<sizeof...(indexedArrays), unsigned int> > indexCombinations(_indexCount);
std::vector<Math::Vector<sizeof...(indexedArrays), std::uint32_t> > indexCombinations(_indexCount);
writeCombinedIndices(indexCombinations, std::get<0>(indexedArrays)...);
/* Make the combinations unique */
@ -56,13 +56,13 @@ class CombineIndexedArrays {
}
private:
template<class ...T> inline static std::size_t indexCount(const std::vector<unsigned int>& first, const std::vector<T>&... next) {
template<class ...T> inline static std::size_t indexCount(const std::vector<std::uint32_t>& first, const std::vector<T>&... next) {
CORRADE_ASSERT(sizeof...(next) == 0 || indexCount(next...) == first.size(), "MeshTools::combineIndexedArrays(): index arrays don't have the same length, nothing done.", 0);
return first.size();
}
template<std::size_t size, class ...T> static void writeCombinedIndices(std::vector<Math::Vector<size, unsigned int>>& output, const std::vector<unsigned int>& first, const std::vector<T>&... next) {
template<std::size_t size, class ...T> static void writeCombinedIndices(std::vector<Math::Vector<size, std::uint32_t>>& output, const std::vector<std::uint32_t>& first, const std::vector<T>&... next) {
/* Copy the data to output */
for(std::size_t i = 0; i != output.size(); ++i)
output[i][size-sizeof...(next)-1] = first[i];
@ -70,7 +70,7 @@ class CombineIndexedArrays {
writeCombinedIndices(output, next...);
}
template<std::size_t size, class T, class ...U> static void writeCombinedArrays(const std::vector<Math::Vector<size, unsigned int>>& combinedIndices, std::vector<T>& first, std::vector<U>&... next) {
template<std::size_t size, class T, class ...U> static void writeCombinedArrays(const std::vector<Math::Vector<size, std::uint32_t>>& combinedIndices, std::vector<T>& first, std::vector<U>&... next) {
/* Rewrite output array */
std::vector<T> output;
for(std::size_t i = 0; i != combinedIndices.size(); ++i)
@ -82,8 +82,8 @@ class CombineIndexedArrays {
/* Terminator functions for recursive calls */
inline static std::size_t indexCount() { return 0; }
template<std::size_t size> inline static void writeCombinedIndices(std::vector<Math::Vector<size, unsigned int>>&) {}
template<std::size_t size> inline static void writeCombinedArrays(const std::vector<Math::Vector<size, unsigned int>>&) {}
template<std::size_t size> inline static void writeCombinedIndices(std::vector<Math::Vector<size, std::uint32_t>>&) {}
template<std::size_t size> inline static void writeCombinedArrays(const std::vector<Math::Vector<size, std::uint32_t>>&) {}
};
}
@ -105,13 +105,13 @@ avoid explicit verbose specification of tuple type, you can write it with help
of some STL functions like shown below. Also if one index array is shader by
more than one attribute array, just pass the index array more times. Example:
@code
std::vector<unsigned int> vertexIndices;
std::vector<std::uint32_t> vertexIndices;
std::vector<Point3D> positions;
std::vector<unsigned int> normalTextureIndices;
std::vector<std::uint32_t> normalTextureIndices;
std::vector<Vector3> normals;
std::vector<Vector2> textureCoordinates;
std::vector<unsigned int> indices = MeshTools::combineIndexedArrays(
std::vector<std::uint32_t> indices = MeshTools::combineIndexedArrays(
std::make_tuple(std::cref(vertexIndices), std::ref(positions)),
std::make_tuple(std::cref(normalTextureIndices), std::ref(normals)),
std::make_tuple(std::cref(normalTextureIndices), std::ref(textureCoordinates))
@ -127,7 +127,7 @@ attributes indexed with `indices`.
which parameter is index array and which is attribute array, mainly when
both are of the same type.
*/
template<class ...T> std::vector<unsigned int> combineIndexedArrays(const std::tuple<const std::vector<unsigned int>&, std::vector<T>&>&... indexedArrays) {
template<class ...T> std::vector<std::uint32_t> combineIndexedArrays(const std::tuple<const std::vector<std::uint32_t>&, std::vector<T>&>&... indexedArrays) {
return Implementation::CombineIndexedArrays()(indexedArrays...);
}

2
src/MeshTools/CompressIndices.cpp

@ -46,7 +46,7 @@ void CompressIndices::operator()(IndexedMesh* mesh, Buffer::Usage usage) const {
delete[] data;
}
template<class IndexType> std::tuple<size_t, Type, char*> CompressIndices::Compressor::run(const std::vector<unsigned int>& indices) {
template<class IndexType> std::tuple<size_t, Type, char*> CompressIndices::Compressor::run(const std::vector<uint32_t>& indices) {
/* Create smallest possible version of index buffer */
char* buffer = new char[indices.size()*sizeof(IndexType)];
for(size_t i = 0; i != indices.size(); ++i) {

20
src/MeshTools/CompressIndices.h

@ -37,7 +37,7 @@ namespace Implementation {
class MESHTOOLS_EXPORT CompressIndices {
public:
CompressIndices(const std::vector<unsigned int>& indices): indices(indices) {}
CompressIndices(const std::vector<std::uint32_t>& indices): indices(indices) {}
std::tuple<std::size_t, Type, char*> operator()() const;
@ -45,10 +45,10 @@ class MESHTOOLS_EXPORT CompressIndices {
private:
struct Compressor {
template<class IndexType> static std::tuple<std::size_t, Type, char*> run(const std::vector<unsigned int>& indices);
template<class IndexType> static std::tuple<std::size_t, Type, char*> run(const std::vector<std::uint32_t>& indices);
};
const std::vector<unsigned int>& indices;
const std::vector<std::uint32_t>& indices;
};
}
@ -62,9 +62,9 @@ class MESHTOOLS_EXPORT CompressIndices {
This function takes index array and outputs them compressed to smallest
possible size. For example when your indices have maximum number 463, it's
wasteful to store them in array of `unsigned int`s, array of `unsigned short`s
is sufficient. Size of the buffer can be computed from index count and type,
as shown below. Example usage:
wasteful to store them in array of 32bit integers, array of 16bit integers is
sufficient. Size of the buffer can be computed from index count and type, as
shown below. Example usage:
@code
std::size_t indexCount;
Type indexType;
@ -75,10 +75,10 @@ std::size_t dataSize = indexCount*TypeInfo::sizeOf(indexType);
delete[] data;
@endcode
See also compressIndices(IndexedMesh*, Buffer::Usage, const std::vector<unsigned int>&),
See also compressIndices(IndexedMesh*, Buffer::Usage, const std::vector<std::uint32_t>&),
which writes the compressed data directly into index buffer of given mesh.
*/
inline std::tuple<std::size_t, Type, char*> compressIndices(const std::vector<std::unsigned int>& indices) {
inline std::tuple<std::size_t, Type, char*> compressIndices(const std::vector<std::uint32_t>& indices) {
return Implementation::CompressIndices{indices}();
}
@ -88,14 +88,14 @@ inline std::tuple<std::size_t, Type, char*> compressIndices(const std::vector<st
@param usage Index buffer usage
@param indices Index array
The same as compressIndices(const std::vector<unsigned int>&), but this
The same as compressIndices(const std::vector<std::uint32_t>&), but this
function writes the output to mesh's index buffer and updates index count and
type in the mesh accordingly, so you don't have to call Mesh::setIndexCount()
and Mesh::setIndexType() on your own.
@see MeshTools::interleave()
*/
inline void compressIndices(IndexedMesh* mesh, Buffer::Usage usage, const std::vector<unsigned int>& indices) {
inline void compressIndices(IndexedMesh* mesh, Buffer::Usage usage, const std::vector<std::uint32_t>& indices) {
return Implementation::CompressIndices{indices}(mesh, usage);
}

2
src/MeshTools/FlipNormals.cpp

@ -21,7 +21,7 @@ using namespace std;
namespace Magnum { namespace MeshTools {
void flipFaceWinding(vector<unsigned int>& indices) {
void flipFaceWinding(vector<uint32_t>& indices) {
CORRADE_ASSERT(!(indices.size()%3), "MeshTools::flipNormals(): index count is not divisible by 3!", );
for(size_t i = 0; i != indices.size(); i += 3)

9
src/MeshTools/FlipNormals.h

@ -19,6 +19,7 @@
* @brief Function Magnum::MeshTools::flipNormals()
*/
#include <cstdint>
#include <vector>
#include "Magnum.h"
@ -30,15 +31,15 @@ namespace Magnum { namespace MeshTools {
/**
@brief Flip face winding
The same as flipNormals(std::vector<unsigned int>&, std::vector<Vector3>&),
The same as flipNormals(std::vector<std::uint32_t>&, std::vector<Vector3>&),
but flips only face winding.
*/
void MESHTOOLS_EXPORT flipFaceWinding(std::vector<unsigned int>& indices);
void MESHTOOLS_EXPORT flipFaceWinding(std::vector<std::uint32_t>& indices);
/**
@brief Flip mesh normals
The same as flipNormals(std::vector<unsigned int>&, std::vector<Vector3>&),
The same as flipNormals(std::vector<std::uint32_t>&, std::vector<Vector3>&),
but flips only normals, not face winding.
*/
void MESHTOOLS_EXPORT flipNormals(std::vector<Vector3>& normals);
@ -55,7 +56,7 @@ flipFaceWinding(), which flip normals or face winding only.
@attention The function requires the mesh to have triangle faces, thus index
count must be divisible by 3.
*/
inline void flipNormals(std::vector<unsigned int>& indices, std::vector<Vector3>& normals) {
inline void flipNormals(std::vector<std::uint32_t>& indices, std::vector<Vector3>& normals) {
flipFaceWinding(indices);
flipNormals(normals);
}

6
src/MeshTools/GenerateFlatNormals.cpp

@ -22,11 +22,11 @@ using namespace std;
namespace Magnum { namespace MeshTools {
tuple<vector<unsigned int>, vector<Vector3>> generateFlatNormals(const vector<unsigned int>& indices, const vector<Point3D>& positions) {
CORRADE_ASSERT(!(indices.size()%3), "MeshTools::generateFlatNormals(): index count is not divisible by 3!", (tuple<vector<unsigned int>, vector<Vector3>>()));
tuple<vector<uint32_t>, vector<Vector3>> generateFlatNormals(const vector<uint32_t>& indices, const vector<Point3D>& positions) {
CORRADE_ASSERT(!(indices.size()%3), "MeshTools::generateFlatNormals(): index count is not divisible by 3!", (tuple<vector<uint32_t>, vector<Vector3>>()));
/* Create normal for every triangle (assuming counterclockwise winding) */
vector<unsigned int> normalIndices;
vector<uint32_t> normalIndices;
normalIndices.reserve(indices.size());
vector<Vector3> normals;
normals.reserve(indices.size()/3);

7
src/MeshTools/GenerateFlatNormals.h

@ -19,6 +19,7 @@
* @brief Function Magnum::MeshTools::generateFlatNormals()
*/
#include <cstdint>
#include <tuple>
#include <vector>
@ -37,10 +38,10 @@ namespace Magnum { namespace MeshTools {
For each face generates one normal vector, removes duplicates before
returning. Example usage:
@code
std::vector<unsigned int> vertexIndices;
std::vector<std::uint32_t> vertexIndices;
std::vector<Point3D> positions;
std::vector<unsigned int> normalIndices;
std::vector<std::uint32_t> normalIndices;
std::vector<Vector3> normals;
std::tie(normalIndices, normals) = MeshTools::generateFlatNormals(vertexIndices, positions);
@endcode
@ -50,7 +51,7 @@ use the same indices.
@attention Index count must be divisible by 3, otherwise zero length result
is generated.
*/
std::tuple<std::vector<unsigned int>, std::vector<Vector3>> MESHTOOLS_EXPORT generateFlatNormals(const std::vector<unsigned int>& indices, const std::vector<Point3D>& positions);
std::tuple<std::vector<std::uint32_t>, std::vector<Vector3>> MESHTOOLS_EXPORT generateFlatNormals(const std::vector<std::uint32_t>& indices, const std::vector<Point3D>& positions);
}}

12
src/MeshTools/Subdivide.h

@ -29,7 +29,7 @@ namespace Implementation {
template<class Vertex, class Interpolator> class Subdivide {
public:
inline Subdivide(std::vector<unsigned int>& indices, std::vector<Vertex>& vertices): indices(indices), vertices(vertices) {}
inline Subdivide(std::vector<std::uint32_t>& indices, std::vector<Vertex>& vertices): indices(indices), vertices(vertices) {}
void operator()(Interpolator interpolator) {
CORRADE_ASSERT(!(indices.size()%3), "MeshTools::subdivide(): index count is not divisible by 3!", );
@ -40,7 +40,7 @@ template<class Vertex, class Interpolator> class Subdivide {
/* Subdivide each face to four new */
for(std::size_t i = 0; i != indexCount; i += 3) {
/* Interpolate each side */
unsigned int newVertices[3];
std::uint32_t newVertices[3];
for(int j = 0; j != 3; ++j)
newVertices[j] = addVertex(interpolator(vertices[indices[i+j]], vertices[indices[i+(j+1)%3]]));
@ -66,15 +66,15 @@ template<class Vertex, class Interpolator> class Subdivide {
}
private:
std::vector<unsigned int>& indices;
std::vector<std::uint32_t>& indices;
std::vector<Vertex>& vertices;
unsigned int addVertex(const Vertex& v) {
std::uint32_t addVertex(const Vertex& v) {
vertices.push_back(v);
return vertices.size()-1;
}
void addFace(unsigned int first, unsigned int second, unsigned int third) {
void addFace(std::uint32_t first, std::uint32_t second, std::uint32_t third) {
indices.push_back(first);
indices.push_back(second);
indices.push_back(third);
@ -96,7 +96,7 @@ template<class Vertex, class Interpolator> class Subdivide {
Goes through all triangle faces and subdivides them into four new. Cleaning
duplicate vertices in the mesh is up to user.
*/
template<class Vertex, class Interpolator> inline void subdivide(std::vector<unsigned int>& indices, std::vector<Vertex>& vertices, Interpolator interpolator) {
template<class Vertex, class Interpolator> inline void subdivide(std::vector<std::uint32_t>& indices, std::vector<Vertex>& vertices, Interpolator interpolator) {
Implementation::Subdivide<Vertex, Interpolator>(indices, vertices)(interpolator);
}

4
src/MeshTools/Test/CleanTest.cpp

@ -29,12 +29,12 @@ CleanTest::CleanTest() {
void CleanTest::cleanMesh() {
vector<Vector1> positions{1, 2, 1, 4};
vector<unsigned int> indices{0, 1, 2, 1, 2, 3};
vector<uint32_t> indices{0, 1, 2, 1, 2, 3};
MeshTools::clean(indices, positions);
/* Verify cleanup */
CORRADE_VERIFY(positions == (vector<Vector1>{1, 2, 4}));
CORRADE_COMPARE(indices, (vector<unsigned int>{0, 1, 0, 1, 0, 2}));
CORRADE_COMPARE(indices, (vector<uint32_t>{0, 1, 0, 1, 0, 2}));
}
}}}

34
src/MeshTools/Test/CombineIndexedArraysTest.cpp

@ -33,29 +33,29 @@ CombineIndexedArraysTest::CombineIndexedArraysTest() {
void CombineIndexedArraysTest::wrongIndexCount() {
stringstream ss;
Error::setOutput(&ss);
vector<unsigned int> array;
vector<unsigned int> result = MeshTools::combineIndexedArrays(
tuple<const vector<unsigned int>&, vector<unsigned int>&>(vector<unsigned int>{0, 1, 0}, array),
tuple<const vector<unsigned int>&, vector<unsigned int>&>(vector<unsigned int>{3, 4}, array));
vector<uint32_t> array;
vector<uint32_t> result = MeshTools::combineIndexedArrays(
tuple<const vector<uint32_t>&, vector<uint32_t>&>(vector<uint32_t>{0, 1, 0}, array),
tuple<const vector<uint32_t>&, vector<uint32_t>&>(vector<uint32_t>{3, 4}, array));
CORRADE_COMPARE(result.size(), 0);
CORRADE_COMPARE(ss.str(), "MeshTools::combineIndexedArrays(): index arrays don't have the same length, nothing done.\n");
}
void CombineIndexedArraysTest::combine() {
vector<unsigned int> array1{ 0, 1 };
vector<unsigned int> array2{ 0, 1, 2, 3, 4 };
vector<unsigned int> array3{ 0, 1, 2, 3, 4, 5, 6, 7 };
vector<unsigned int> result = MeshTools::combineIndexedArrays(
tuple<const vector<unsigned int>&, vector<unsigned int>&>(vector<unsigned int>{0, 1, 0}, array1),
tuple<const vector<unsigned int>&, vector<unsigned int>&>(vector<unsigned int>{3, 4, 3}, array2),
tuple<const vector<unsigned int>&, vector<unsigned int>&>(vector<unsigned int>{6, 7, 6}, array3));
CORRADE_COMPARE(result, (vector<unsigned int>{0, 1, 0}));
CORRADE_COMPARE(array1, (vector<unsigned int>{0, 1}));
CORRADE_COMPARE(array2, (vector<unsigned int>{3, 4}));
CORRADE_COMPARE(array3, (vector<unsigned int>{6, 7}));
vector<uint32_t> array1{ 0, 1 };
vector<uint32_t> array2{ 0, 1, 2, 3, 4 };
vector<uint32_t> array3{ 0, 1, 2, 3, 4, 5, 6, 7 };
vector<uint32_t> result = MeshTools::combineIndexedArrays(
tuple<const vector<uint32_t>&, vector<uint32_t>&>(vector<uint32_t>{0, 1, 0}, array1),
tuple<const vector<uint32_t>&, vector<uint32_t>&>(vector<uint32_t>{3, 4, 3}, array2),
tuple<const vector<uint32_t>&, vector<uint32_t>&>(vector<uint32_t>{6, 7, 6}, array3));
CORRADE_COMPARE(result, (vector<uint32_t>{0, 1, 0}));
CORRADE_COMPARE(array1, (vector<uint32_t>{0, 1}));
CORRADE_COMPARE(array2, (vector<uint32_t>{3, 4}));
CORRADE_COMPARE(array3, (vector<uint32_t>{6, 7}));
}
}}}

6
src/MeshTools/Test/CompressIndicesTest.cpp

@ -37,7 +37,7 @@ void CompressIndicesTest::compressChar() {
Type indexType;
char* data;
tie(indexCount, indexType, data) = MeshTools::compressIndices(
vector<unsigned int>{1, 2, 3, 0, 4});
vector<uint32_t>{1, 2, 3, 0, 4});
CORRADE_COMPARE(indexCount, 5);
CORRADE_VERIFY(indexType == Type::UnsignedByte);
@ -52,7 +52,7 @@ void CompressIndicesTest::compressShort() {
Type indexType;
char* data;
tie(indexCount, indexType, data) = MeshTools::compressIndices(
vector<unsigned int>{1, 256, 0, 5});
vector<uint32_t>{1, 256, 0, 5});
CORRADE_COMPARE(indexCount, 4);
CORRADE_VERIFY(indexType == Type::UnsignedShort);
@ -78,7 +78,7 @@ void CompressIndicesTest::compressInt() {
Type indexType;
char* data;
tie(indexCount, indexType, data) = MeshTools::compressIndices(
vector<unsigned int>{65536, 3, 2});
vector<uint32_t>{65536, 3, 2});
CORRADE_COMPARE(indexCount, 3);
CORRADE_VERIFY(indexType == Type::UnsignedInt);

8
src/MeshTools/Test/FlipNormalsTest.cpp

@ -36,19 +36,19 @@ void FlipNormalsTest::wrongIndexCount() {
stringstream ss;
Error::setOutput(&ss);
vector<unsigned int> indices{0, 1};
vector<uint32_t> indices{0, 1};
MeshTools::flipFaceWinding(indices);
CORRADE_COMPARE(ss.str(), "MeshTools::flipNormals(): index count is not divisible by 3!\n");
}
void FlipNormalsTest::flipFaceWinding() {
vector<unsigned int> indices{0, 1, 2,
vector<uint32_t> indices{0, 1, 2,
3, 4, 5};
MeshTools::flipFaceWinding(indices);
CORRADE_COMPARE(indices, (vector<unsigned int>{0, 2, 1,
3, 5, 4}));
CORRADE_COMPARE(indices, (vector<uint32_t>{0, 2, 1,
3, 5, 4}));
}
void FlipNormalsTest::flipNormals() {

6
src/MeshTools/Test/GenerateFlatNormalsTest.cpp

@ -34,7 +34,7 @@ GenerateFlatNormalsTest::GenerateFlatNormalsTest() {
void GenerateFlatNormalsTest::wrongIndexCount() {
stringstream ss;
Error::setOutput(&ss);
vector<unsigned int> indices;
vector<uint32_t> indices;
vector<Vector3> normals;
tie(indices, normals) = MeshTools::generateFlatNormals({
0, 1
@ -47,7 +47,7 @@ void GenerateFlatNormalsTest::wrongIndexCount() {
void GenerateFlatNormalsTest::generate() {
/* Two vertices connected by one edge, each winded in another direction */
vector<unsigned int> indices;
vector<uint32_t> indices;
vector<Vector3> normals;
tie(indices, normals) = MeshTools::generateFlatNormals({
0, 1, 2,
@ -59,7 +59,7 @@ void GenerateFlatNormalsTest::generate() {
{1.0f, 0.0f, 0.0f}
});
CORRADE_COMPARE(indices, (vector<unsigned int>{
CORRADE_COMPARE(indices, (vector<uint32_t>{
0, 0, 0,
1, 1, 1
}));

6
src/MeshTools/Test/SubdivideTest.cpp

@ -36,20 +36,20 @@ void SubdivideTest::wrongIndexCount() {
Error::setOutput(&ss);
vector<Vector1> positions;
vector<unsigned int> indices{0, 1};
vector<uint32_t> indices{0, 1};
MeshTools::subdivide(indices, positions, interpolator);
CORRADE_COMPARE(ss.str(), "MeshTools::subdivide(): index count is not divisible by 3!\n");
}
void SubdivideTest::subdivide() {
vector<Vector1> positions{0, 2, 6, 8};
vector<unsigned int> indices{0, 1, 2, 1, 2, 3};
vector<uint32_t> indices{0, 1, 2, 1, 2, 3};
MeshTools::subdivide(indices, positions, interpolator);
CORRADE_COMPARE(indices.size(), 24);
CORRADE_VERIFY(positions == (vector<Vector1>{0, 2, 6, 8, 1, 4, 3, 4, 7, 5}));
CORRADE_COMPARE(indices, (vector<unsigned int>{4, 5, 6, 7, 8, 9, 0, 4, 6, 4, 1, 5, 6, 5, 2, 1, 7, 9, 7, 2, 8, 9, 8, 3}));
CORRADE_COMPARE(indices, (vector<uint32_t>{4, 5, 6, 7, 8, 9, 0, 4, 6, 4, 1, 5, 6, 5, 2, 1, 7, 9, 7, 2, 8, 9, 8, 3}));
MeshTools::clean(indices, positions);

2
src/MeshTools/Test/TipsifyTest.cpp

@ -114,7 +114,7 @@ void TipsifyTest::buildAdjacency() {
void TipsifyTest::tipsify() {
MeshTools::tipsify(indices, vertexCount, 3);
CORRADE_COMPARE(indices, (vector<unsigned int>{
CORRADE_COMPARE(indices, (vector<uint32_t>{
4, 1, 0,
9, 5, 4,
1, 4, 5,

2
src/MeshTools/Test/TipsifyTest.h

@ -27,7 +27,7 @@ class TipsifyTest: public Corrade::TestSuite::Tester<TipsifyTest> {
void tipsify();
private:
std::vector<unsigned int> indices;
std::vector<std::uint32_t> indices;
std::size_t vertexCount;
};

38
src/MeshTools/Tipsify.cpp

@ -17,42 +17,44 @@
#include <stack>
using namespace std;
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Magnum { namespace MeshTools { namespace Implementation {
void Tipsify::operator()(size_t cacheSize) {
/* Neighboring triangles for each vertex, per-vertex live triangle count */
std::vector<unsigned int> liveTriangleCount, neighborPosition, neighbors;
std::vector<uint32_t> liveTriangleCount, neighborPosition, neighbors;
buildAdjacency(liveTriangleCount, neighborPosition, neighbors);
/* Global time, per-vertex caching timestamps, per-triangle emmited flag */
unsigned int time = cacheSize+1;
std::vector<unsigned int> timestamp(vertexCount);
uint32_t time = cacheSize+1;
std::vector<uint32_t> timestamp(vertexCount);
std::vector<bool> emitted(indices.size()/3);
/* Dead-end vertex stack */
std::stack<unsigned int> deadEndStack;
std::stack<uint32_t> deadEndStack;
/* Output index buffer */
std::vector<unsigned int> outputIndices;
std::vector<uint32_t> outputIndices;
outputIndices.reserve(indices.size());
/* Starting vertex for fanning, cursor */
unsigned int fanningVertex = 0;
unsigned int i = 0;
uint32_t fanningVertex = 0;
uint32_t i = 0;
while(fanningVertex != 0xFFFFFFFFu) {
/* Array with candidates for next fanning vertex (in 1-ring around
fanning vertex) */
std::vector<unsigned int> candidates;
std::vector<uint32_t> candidates;
/* For all neighbors of fanning vertex */
for(unsigned int ti = neighborPosition[fanningVertex], t = neighbors[ti]; ti != neighborPosition[fanningVertex+1]; t = neighbors[++ti]) {
for(uint32_t ti = neighborPosition[fanningVertex], t = neighbors[ti]; ti != neighborPosition[fanningVertex+1]; t = neighbors[++ti]) {
/* Continue if already emitted */
if(emitted[t]) continue;
emitted[t] = true;
/* Write all vertices of the triangle to output buffer */
for(unsigned int vi = 0, v = indices[t*3]; vi != 3; v = indices[++vi+t*3]) {
for(uint32_t vi = 0, v = indices[t*3]; vi != 3; v = indices[++vi+t*3]) {
outputIndices.push_back(v);
/* Add to dead end stack and candidates array */
@ -73,15 +75,15 @@ void Tipsify::operator()(size_t cacheSize) {
fanningVertex = 0xFFFFFFFFu;
/* Go through candidates in 1-ring around fanning vertex */
int candidatePriority = -1;
for(unsigned int v: candidates) {
int32_t candidatePriority = -1;
for(uint32_t v: candidates) {
/* Skip if it doesn't have any live triangles */
if(!liveTriangleCount[v]) continue;
/* Get most fresh candidate which will still be in cache even
after fanning. Every fanned triangle will generate at most
two cache misses, thus 2*liveTriangleCount */
int priority = 0;
int32_t priority = 0;
if(time-timestamp[v]+2*liveTriangleCount[v] <= cacheSize)
priority = time-timestamp[v];
if(priority > candidatePriority) {
@ -117,12 +119,12 @@ void Tipsify::operator()(size_t cacheSize) {
std::swap(indices, outputIndices);
}
void Tipsify::buildAdjacency(std::vector<unsigned int>& liveTriangleCount, std::vector<unsigned int>& neighborOffset, std::vector<unsigned int>& neighbors) const {
void Tipsify::buildAdjacency(std::vector<uint32_t>& liveTriangleCount, std::vector<uint32_t>& neighborOffset, std::vector<uint32_t>& neighbors) const {
/* How many times is each vertex referenced == count of neighboring
triangles for each vertex */
liveTriangleCount.clear();
liveTriangleCount.resize(vertexCount);
for(unsigned int i = 0; i != indices.size(); ++i)
for(size_t i = 0; i != indices.size(); ++i)
++liveTriangleCount[indices[i]];
/* Building offset array from counts. Neighbors for i-th vertex will at
@ -132,8 +134,8 @@ void Tipsify::buildAdjacency(std::vector<unsigned int>& liveTriangleCount, std::
neighborOffset.clear();
neighborOffset.reserve(vertexCount+1);
neighborOffset.push_back(0);
unsigned int sum = 0;
for(unsigned int i = 0; i != vertexCount; ++i) {
uint32_t sum = 0;
for(size_t i = 0; i != vertexCount; ++i) {
neighborOffset.push_back(sum);
sum += liveTriangleCount[i];
}
@ -142,7 +144,7 @@ void Tipsify::buildAdjacency(std::vector<unsigned int>& liveTriangleCount, std::
positioning */
neighbors.clear();
neighbors.resize(sum);
for(unsigned int i = 0; i != indices.size(); ++i)
for(size_t i = 0; i != indices.size(); ++i)
neighbors[neighborOffset[indices[i]+1]++] = i/3;
}

12
src/MeshTools/Tipsify.h

@ -19,7 +19,7 @@
* @brief Function Magnum::MeshTools::tipsify()
*/
#include <cstddef>
#include <cstdint>
#include <vector>
#include "magnumMeshToolsVisibility.h"
@ -31,7 +31,7 @@ namespace Implementation {
class MESHTOOLS_EXPORT Tipsify {
public:
inline Tipsify(std::vector<unsigned int>& indices, unsigned int vertexCount): indices(indices), vertexCount(vertexCount) {}
inline Tipsify(std::vector<std::uint32_t>& indices, std::uint32_t vertexCount): indices(indices), vertexCount(vertexCount) {}
void operator()(std::size_t cacheSize);
@ -41,11 +41,11 @@ class MESHTOOLS_EXPORT Tipsify {
* Computes count and indices of adjacent triangles for each vertex
* (used internally).
*/
void buildAdjacency(std::vector<unsigned int>& liveTriangleCount, std::vector<unsigned int>& neighborOffset, std::vector<unsigned int>& neighbors) const;
void buildAdjacency(std::vector<std::uint32_t>& liveTriangleCount, std::vector<std::uint32_t>& neighborOffset, std::vector<std::uint32_t>& neighbors) const;
private:
std::vector<unsigned int>& indices;
const unsigned int vertexCount;
std::vector<std::uint32_t>& indices;
const std::uint32_t vertexCount;
};
}
@ -63,7 +63,7 @@ array for beter usage of post-transform vertex cache. Algorithm used:
for Vertex Locality and Reduced Overdraw, SIGGRAPH 2007,
http://gfx.cs.princeton.edu/pubs/Sander_2007_%3ETR/index.php*.
*/
inline void tipsify(std::vector<unsigned int>& indices, unsigned int vertexCount, std::size_t cacheSize) {
inline void tipsify(std::vector<std::uint32_t>& indices, std::uint32_t vertexCount, std::size_t cacheSize) {
Implementation::Tipsify(indices, vertexCount)(cacheSize);
}

12
src/Primitives/Capsule.cpp

@ -22,7 +22,7 @@ using namespace std;
namespace Magnum { namespace Primitives {
Capsule::Capsule(unsigned int hemisphereRings, unsigned int cylinderRings, unsigned int segments, GLfloat length, TextureCoords textureCoords): MeshData3D("", Mesh::Primitive::Triangles, new vector<unsigned int>, {new vector<Point3D>()}, {new vector<Vector3>()}, textureCoords == TextureCoords::Generate ? vector<vector<Vector2>*>{new vector<Vector2>()} : vector<vector<Vector2>*>()), segments(segments), textureCoords(textureCoords) {
Capsule::Capsule(unsigned int hemisphereRings, unsigned int cylinderRings, unsigned int segments, GLfloat length, TextureCoords textureCoords): MeshData3D("", Mesh::Primitive::Triangles, new vector<uint32_t>, {new vector<Point3D>()}, {new vector<Vector3>()}, textureCoords == TextureCoords::Generate ? vector<vector<Vector2>*>{new vector<Vector2>()} : vector<vector<Vector2>*>()), segments(segments), textureCoords(textureCoords) {
CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1 && segments >= 3, "Capsule must have at least one hemisphere ring, one cylinder ring and three segments", );
GLfloat height = 2.0f+length;
@ -50,7 +50,7 @@ Capsule::Capsule(unsigned int hemisphereRings, unsigned int cylinderRings, unsig
topFaceRing();
}
Capsule::Capsule(unsigned int segments, TextureCoords textureCoords): MeshData3D("", Mesh::Primitive::Triangles, new std::vector<unsigned int>, {new std::vector<Point3D>()}, {new std::vector<Vector3>()}, textureCoords == TextureCoords::Generate ? std::vector<std::vector<Vector2>*>{new std::vector<Vector2>()} : std::vector<std::vector<Vector2>*>()), segments(segments), textureCoords(textureCoords) {}
Capsule::Capsule(unsigned int segments, TextureCoords textureCoords): MeshData3D("", Mesh::Primitive::Triangles, new std::vector<std::uint32_t>, {new std::vector<Point3D>()}, {new std::vector<Vector3>()}, textureCoords == TextureCoords::Generate ? std::vector<std::vector<Vector2>*>{new std::vector<Vector2>()} : std::vector<std::vector<Vector2>*>()), segments(segments), textureCoords(textureCoords) {}
void Capsule::capVertex(GLfloat y, GLfloat normalY, GLfloat textureCoordsV) {
positions(0)->push_back({0.0f, y, 0.0f});
@ -128,11 +128,11 @@ void Capsule::faceRings(unsigned int count, unsigned int offset) {
for(unsigned int i = 0; i != count; ++i) {
for(unsigned int j = 0; j != segments; ++j) {
unsigned int bottomLeft = i*vertexSegments+j+offset;
unsigned int bottomRight = ((j != segments-1 || textureCoords == TextureCoords::Generate) ?
uint32_t bottomLeft = i*vertexSegments+j+offset;
uint32_t bottomRight = ((j != segments-1 || textureCoords == TextureCoords::Generate) ?
i*vertexSegments+j+1+offset : i*segments+offset);
unsigned int topLeft = bottomLeft+vertexSegments;
unsigned int topRight = bottomRight+vertexSegments;
uint32_t topLeft = bottomLeft+vertexSegments;
uint32_t topRight = bottomRight+vertexSegments;
indices()->push_back(bottomLeft);
indices()->push_back(bottomRight);

2
src/Primitives/Cube.cpp

@ -21,7 +21,7 @@ using namespace std;
namespace Magnum { namespace Primitives {
Cube::Cube(): MeshData3D("", Mesh::Primitive::Triangles, new vector<unsigned int>{
Cube::Cube(): MeshData3D("", Mesh::Primitive::Triangles, new vector<std::uint32_t>{
0, 2, 1,
2, 3, 1,
1, 3, 5,

2
src/Primitives/Icosphere.cpp

@ -21,7 +21,7 @@ using namespace std;
namespace Magnum { namespace Primitives {
Icosphere<0>::Icosphere(): MeshData3D("", Mesh::Primitive::Triangles, new vector<unsigned int>{
Icosphere<0>::Icosphere(): MeshData3D("", Mesh::Primitive::Triangles, new vector<uint32_t>{
1, 2, 6,
1, 7, 2,
3, 4, 5,

4
src/Primitives/Test/CapsuleTest.cpp

@ -90,7 +90,7 @@ void CapsuleTest::withoutTextureCoords() {
{0.0f, 1.0f, 0.0f}
}), Container);
CORRADE_COMPARE_AS(*capsule.indices(), (vector<unsigned int>{
CORRADE_COMPARE_AS(*capsule.indices(), (vector<uint32_t>{
0, 2, 1, 0, 3, 2, 0, 1, 3,
1, 2, 5, 1, 5, 4, 2, 3, 6, 2, 6, 5, 3, 1, 4, 3, 4, 6,
4, 5, 8, 4, 8, 7, 5, 6, 9, 5, 9, 8, 6, 4, 7, 6, 7, 9,
@ -165,7 +165,7 @@ void CapsuleTest::withTextureCoords() {
{0.5f, 1.0f}
}), Container);
CORRADE_COMPARE_AS(*capsule.indices(), (vector<unsigned int>{
CORRADE_COMPARE_AS(*capsule.indices(), (vector<uint32_t>{
0, 2, 1, 0, 3, 2, 0, 4, 3,
1, 2, 6, 1, 6, 5, 2, 3, 7, 2, 7, 6, 3, 4, 8, 3, 8, 7,
5, 6, 10, 5, 10, 9, 6, 7, 11, 6, 11, 10, 7, 8, 12, 7, 12, 11,

4
src/Primitives/Test/CylinderTest.cpp

@ -63,7 +63,7 @@ void CylinderTest::withoutAnything() {
{-0.866025f, 0.0f, -0.5f}
}), Container);
CORRADE_COMPARE_AS(*cylinder.indices(), (vector<unsigned int>{
CORRADE_COMPARE_AS(*cylinder.indices(), (vector<uint32_t>{
0, 1, 4, 0, 4, 3, 1, 2, 5, 1, 5, 4, 2, 0, 3, 2, 3, 5,
3, 4, 7, 3, 7, 6, 4, 5, 8, 4, 8, 7, 5, 3, 6, 5, 6, 8
}), Container);
@ -165,7 +165,7 @@ void CylinderTest::withTextureCoordsAndCaps() {
{0.5f, 1.0f}
}), Container);
CORRADE_COMPARE_AS(*cylinder.indices(), (vector<unsigned int>{
CORRADE_COMPARE_AS(*cylinder.indices(), (vector<uint32_t>{
0, 2, 1, 0, 3, 2, 0, 4, 3,
1, 2, 6, 1, 6, 5, 2, 3, 7, 2, 7, 6, 3, 4, 8, 3, 8, 7,
5, 6, 10, 5, 10, 9, 6, 7, 11, 6, 11, 10, 7, 8, 12, 7,

4
src/Primitives/Test/UVSphereTest.cpp

@ -63,7 +63,7 @@ void UVSphereTest::withoutTextureCoords() {
{0.0f, 1.0f, 0.0f}
}), Container);
CORRADE_COMPARE_AS(*sphere.indices(), (vector<unsigned int>{
CORRADE_COMPARE_AS(*sphere.indices(), (vector<uint32_t>{
0, 2, 1, 0, 3, 2, 0, 1, 3,
1, 2, 5, 1, 5, 4, 2, 3, 6, 2, 6, 5, 3, 1, 4, 3, 4, 6,
4, 5, 7, 5, 6, 7, 6, 4, 7
@ -105,7 +105,7 @@ void UVSphereTest::withTextureCoords() {
{0.5f, 1.0f}
}), Container);
CORRADE_COMPARE_AS(*sphere.indices(), (vector<unsigned int>{
CORRADE_COMPARE_AS(*sphere.indices(), (vector<uint32_t>{
0, 2, 1, 0, 3, 2, 0, 4, 3,
1, 2, 6, 1, 6, 5, 2, 3, 7, 2, 7, 6, 3, 4, 8, 3, 8, 7,
5, 6, 9, 6, 7, 9, 7, 8, 9

8
src/Trade/MeshData2D.h

@ -51,7 +51,7 @@ class MAGNUM_EXPORT MeshData2D {
* @param textureCoords2D Array with two-dimensional texture
* coordinate arrays or empty array
*/
inline MeshData2D(const std::string& name, Mesh::Primitive primitive, std::vector<unsigned int>* indices, std::vector<std::vector<Point2D>*> positions, std::vector<std::vector<Vector2>*> textureCoords2D): _name(name), _primitive(primitive), _indices(indices), _positions(positions), _textureCoords2D(textureCoords2D) {}
inline MeshData2D(const std::string& name, Mesh::Primitive primitive, std::vector<std::uint32_t>* indices, std::vector<std::vector<Point2D>*> positions, std::vector<std::vector<Vector2>*> textureCoords2D): _name(name), _primitive(primitive), _indices(indices), _positions(positions), _textureCoords2D(textureCoords2D) {}
/** @brief Destructor */
~MeshData2D();
@ -66,8 +66,8 @@ class MAGNUM_EXPORT MeshData2D {
* @brief Indices
* @return Indices or nullptr if the mesh is not indexed.
*/
inline std::vector<unsigned int>* indices() { return _indices; }
inline const std::vector<unsigned int>* indices() const { return _indices; } /**< @overload */
inline std::vector<std::uint32_t>* indices() { return _indices; }
inline const std::vector<std::uint32_t>* indices() const { return _indices; } /**< @overload */
/** @brief Count of vertex position arrays */
inline unsigned int positionArrayCount() const { return _positions.size(); }
@ -96,7 +96,7 @@ class MAGNUM_EXPORT MeshData2D {
private:
std::string _name;
Mesh::Primitive _primitive;
std::vector<unsigned int>* _indices;
std::vector<std::uint32_t>* _indices;
std::vector<std::vector<Point2D>*> _positions;
std::vector<std::vector<Vector2>*> _textureCoords2D;
};

8
src/Trade/MeshData3D.h

@ -52,7 +52,7 @@ class MAGNUM_EXPORT MeshData3D {
* @param textureCoords2D Array with two-dimensional texture
* coordinate arrays or empty array
*/
inline MeshData3D(const std::string& name, Mesh::Primitive primitive, std::vector<unsigned int>* indices, std::vector<std::vector<Point3D>*> positions, std::vector<std::vector<Vector3>*> normals, std::vector<std::vector<Vector2>*> textureCoords2D): _name(name), _primitive(primitive), _indices(indices), _positions(positions), _normals(normals), _textureCoords2D(textureCoords2D) {}
inline MeshData3D(const std::string& name, Mesh::Primitive primitive, std::vector<std::uint32_t>* indices, std::vector<std::vector<Point3D>*> positions, std::vector<std::vector<Vector3>*> normals, std::vector<std::vector<Vector2>*> textureCoords2D): _name(name), _primitive(primitive), _indices(indices), _positions(positions), _normals(normals), _textureCoords2D(textureCoords2D) {}
/** @brief Destructor */
~MeshData3D();
@ -67,8 +67,8 @@ class MAGNUM_EXPORT MeshData3D {
* @brief Indices
* @return Indices or nullptr if the mesh is not indexed.
*/
inline std::vector<unsigned int>* indices() { return _indices; }
inline const std::vector<unsigned int>* indices() const { return _indices; } /**< @overload */
inline std::vector<std::uint32_t>* indices() { return _indices; }
inline const std::vector<std::uint32_t>* indices() const { return _indices; } /**< @overload */
/** @brief Count of vertex position arrays */
inline unsigned int positionArrayCount() const { return _positions.size(); }
@ -109,7 +109,7 @@ class MAGNUM_EXPORT MeshData3D {
private:
std::string _name;
Mesh::Primitive _primitive;
std::vector<unsigned int>* _indices;
std::vector<std::uint32_t>* _indices;
std::vector<std::vector<Point3D>*> _positions;
std::vector<std::vector<Vector3>*> _normals;
std::vector<std::vector<Vector2>*> _textureCoords2D;

Loading…
Cancel
Save