diff --git a/src/MeshTools/Clean.h b/src/MeshTools/Clean.h index 62bae24fa..282302cda 100644 --- a/src/MeshTools/Clean.h +++ b/src/MeshTools/Clean.h @@ -19,7 +19,10 @@ * @brief Class Magnum::MeshTools::Clean */ -#include "AbstractTool.h" +#include +#include + +#include "TypeTraits.h" namespace Magnum { namespace MeshTools { @@ -28,10 +31,14 @@ namespace Magnum { namespace MeshTools { See clean() for full documentation. */ -template class Clean: public AbstractTool { +template class Clean { public: - /** @copydoc AbstractTool::AbstractTool() */ - inline Clean(MeshBuilder& builder): AbstractTool(builder) {} + /** + * @brief Constructor + * + * See clean() for full documentation. + */ + inline Clean(std::vector& indices, std::vector& vertices): indices(indices), vertices(vertices) {} /** * @brief Functor @@ -39,7 +46,7 @@ template class Clean: public Abs * See clean() for full documentation. */ void operator()(typename Vertex::Type epsilon = TypeTraits::epsilon()) { - if(this->indices.empty()) return; + if(indices.empty()) return; /* Get mesh bounds */ Vertex min, max; @@ -47,7 +54,7 @@ template class Clean: public Abs min[i] = std::numeric_limits::max(); max[i] = std::numeric_limits::min(); } - for(auto it = this->vertices.cbegin(); it != this->vertices.cend(); ++it) + for(auto it = vertices.cbegin(); it != vertices.cend(); ++it) for(size_t i = 0; i != vertexSize; ++i) if((*it)[i] < min[i]) min[i] = (*it)[i]; @@ -67,18 +74,18 @@ template class Clean: public Abs for(size_t moving = 0; moving <= vertexSize; ++moving) { /* Under each index is pointer to face which contains given vertex - and index of vertex in the face. */ + and index of vertex in the face. */ std::unordered_map, HashedVertex, IndexHash> table; /* Reserve space for all vertices */ - table.reserve(this->vertices.size()); + table.reserve(vertices.size()); /* Go through all faces' vertices */ - for(auto it = this->indices.begin(); it != this->indices.end(); ++it) { + for(auto it = indices.begin(); it != indices.end(); ++it) { /* Index of a vertex in vertexSize-dimensional table */ size_t index[vertexSize]; for(size_t ii = 0; ii != vertexSize; ++ii) - index[ii] = (this->vertices[*it][ii]+moved[ii]-min[ii])/epsilon; + index[ii] = (vertices[*it][ii]+moved[ii]-min[ii])/epsilon; /* Try inserting the vertex into table, if it already exists, change vertex pointer of the face to already @@ -91,8 +98,8 @@ template class Clean: public Abs /* Shrink vertices array */ std::vector newVertices(table.size()); for(auto it = table.cbegin(); it != table.cend(); ++it) - newVertices[it->second.newIndex] = this->vertices[it->second.oldIndex]; - std::swap(newVertices, this->vertices); + newVertices[it->second.newIndex] = vertices[it->second.oldIndex]; + std::swap(newVertices, vertices); /* Move vertex coordinates by epsilon/2 in next direction */ if(moving != Vertex::Size) { @@ -118,38 +125,41 @@ template class Clean: public Abs HashedVertex(unsigned int oldIndex, unsigned int newIndex): oldIndex(oldIndex), newIndex(newIndex) {} }; + + std::vector& indices; + std::vector& vertices; }; /** @brief %Clean the mesh -@tparam Vertex Vertex data type (the same as in MeshBuilder) +@tparam Vertex Vertex data type @tparam vertexSize How many initial vertex fields are important (for example, when dealing with perspective in 3D space, only first three fields of otherwise 4D vertex are important) -@param builder %Mesh builder to operate on -@param epsilon Epsilon value, vertices nearer than this - distance will be melt together. +@param indices Index array to operate on +@param vertices Vertex array to operate on +@param epsilon Epsilon value, vertices nearer than this distance will be + melt together. Removes duplicate vertices from the mesh. This is convenience function supplementing direct usage of Clean class, instead of @code -MeshBuilder builder; -MeshTools::Clean{builder}(epsilon); +MeshTools::Clean(indices, vertices)(epsilon); @endcode you can just write @code -MeshTools::clean(builder, epsilon); +MeshTools::clean(indices, vertices, epsilon); @endcode However, when you want to specify @c vertexSize template parameter, you have to explicitly specify both of them: @code -MeshTools::clean(builder, epsilon); +MeshTools::clean(indices, vertices, epsilon); @endcode */ -template inline void clean(MeshBuilder& builder, typename Vertex::Type epsilon = TypeTraits::epsilon()) { - Clean{builder}(epsilon); +template inline void clean(std::vector& indices, std::vector& vertices, typename Vertex::Type epsilon = TypeTraits::epsilon()) { + Clean(indices, vertices)(epsilon); } }} diff --git a/src/MeshTools/Subdivide.h b/src/MeshTools/Subdivide.h index 712785653..146929621 100644 --- a/src/MeshTools/Subdivide.h +++ b/src/MeshTools/Subdivide.h @@ -19,7 +19,7 @@ * @brief Class Magnum::MeshTools::Subdivide */ -#include "AbstractTool.h" +#include namespace Magnum { namespace MeshTools { @@ -28,10 +28,14 @@ namespace Magnum { namespace MeshTools { See subdivide() for full documentation. */ -template class Subdivide: public AbstractTool { +template class Subdivide { public: - /** @copydoc AbstractTool::AbstractTool() */ - inline Subdivide(MeshBuilder& builder): AbstractTool(builder) {} + /** + * @brief Constructor + * + * See subdivide() for full documentation. + */ + inline Subdivide(std::vector& indices, std::vector& vertices): indices(indices), vertices(vertices) {} /** * @brief Functor @@ -39,15 +43,15 @@ template class Subdivide: public AbstractTool< * See subdivide() for full documentation. */ void operator()(Interpolator interpolator) { - size_t indexCount = this->indices.size(); - this->indices.reserve(this->indices.size()*4); + size_t indexCount = indices.size(); + indices.reserve(indices.size()*4); /* Subdivide each face to four new */ for(size_t i = 0; i != indexCount; i += 3) { /* Interpolate each side */ unsigned int newVertices[3]; for(int j = 0; j != 3; ++j) - newVertices[j] = this->builder.addVertex(interpolator(this->vertices[this->indices[i+j]], this->vertices[this->indices[i+(j+1)%3]])); + newVertices[j] = addVertex(interpolator(vertices[indices[i+j]], vertices[indices[i+(j+1)%3]])); /* * Add three new faces (0, 1, 3) and update original (2) @@ -62,20 +66,36 @@ template class Subdivide: public AbstractTool< * / \ / \ * orig 1 ----- new 1 ---- orig 2 */ - this->builder.addFace(this->indices[i], newVertices[0], newVertices[2]); - this->builder.addFace(newVertices[0], this->indices[i+1], newVertices[1]); - this->builder.addFace(newVertices[2], newVertices[1], this->indices[i+2]); + addFace(indices[i], newVertices[0], newVertices[2]); + addFace(newVertices[0], indices[i+1], newVertices[1]); + addFace(newVertices[2], newVertices[1], indices[i+2]); for(size_t j = 0; j != 3; ++j) - this->indices[i+j] = newVertices[j]; + indices[i+j] = newVertices[j]; } } + + private: + std::vector& indices; + std::vector& vertices; + + unsigned int addVertex(const Vertex& v) { + vertices.push_back(v); + return vertices.size()-1; + } + + void addFace(unsigned int first, unsigned int second, unsigned int third) { + indices.push_back(first); + indices.push_back(second); + indices.push_back(third); + } }; /** @brief %Subdivide the mesh @tparam Vertex Vertex data type (the same as in MeshBuilder) @tparam Interpolator See @c interpolator function parameter -@param builder %Mesh builder to operate on +@param indices Index array to operate on +@param vertices Vertex array to operate on @param interpolator Functor or function pointer which interpolates two adjacent vertices: Vertex interpolator(Vertex a, Vertex b) @@ -85,16 +105,15 @@ duplicate vertices in the mesh is up to user. This is convenience function supplementing direct usage of Subdivide class, instead of @code -MeshBuilder builder; -MeshTools::Subdivide{builder}(interpolator); +MeshTools::Subdivide(indices, vertices)(interpolator); @endcode you can just write @code -MeshTools::subdivide(builder, interpolator); +MeshTools::subdivide(indices, vertices, interpolator); @endcode */ -template inline void subdivide(MeshBuilder& builder, Interpolator interpolator) { - Subdivide{builder}(interpolator); +template inline void subdivide(std::vector& indices, std::vector& vertices, Interpolator interpolator) { + Subdivide(indices, vertices)(interpolator); } }} diff --git a/src/MeshTools/Test/CleanTest.cpp b/src/MeshTools/Test/CleanTest.cpp index bebdeedc2..69c086238 100644 --- a/src/MeshTools/Test/CleanTest.cpp +++ b/src/MeshTools/Test/CleanTest.cpp @@ -26,19 +26,13 @@ using namespace std; namespace Magnum { namespace MeshTools { namespace Test { void CleanTest::cleanMesh() { - MeshBuilder builder; - builder.addVertex(1); - builder.addVertex(2); - builder.addVertex(1); - builder.addVertex(4); - builder.addFace(0, 1, 2); - builder.addFace(1, 2, 3); - - MeshTools::clean(builder, 1); + vector vertices{1, 2, 1, 4}; + vector indices{0, 1, 2, 1, 2, 3}; + MeshTools::clean(indices, vertices); /* Verify cleanup */ - QVERIFY((builder.vertices() == vector{1, 2, 4})); - QVERIFY((builder.indices() == vector{0, 1, 0, 1, 0, 2})); + QVERIFY((vertices == vector{1, 2, 4})); + QVERIFY((indices == vector{0, 1, 0, 1, 0, 2})); } }}} diff --git a/src/MeshTools/Test/SubdivideTest.cpp b/src/MeshTools/Test/SubdivideTest.cpp index d94ec11a0..0e1c8005d 100644 --- a/src/MeshTools/Test/SubdivideTest.cpp +++ b/src/MeshTools/Test/SubdivideTest.cpp @@ -17,7 +17,6 @@ #include -#include "MeshBuilder.h" #include "MeshTools/Clean.h" #include "MeshTools/Subdivide.h" @@ -28,24 +27,19 @@ using namespace std; namespace Magnum { namespace MeshTools { namespace Test { void SubdivideTest::subdivide() { - MeshBuilder builder; - builder.addVertex(0); - builder.addVertex(2); - builder.addVertex(6); - builder.addVertex(8); - builder.addFace(0, 1, 2); - builder.addFace(1, 2, 3); + vector vertices{0, 2, 6, 8}; + vector indices{0, 1, 2, 1, 2, 3}; + MeshTools::subdivide(indices, vertices, interpolator); - MeshTools::subdivide(builder, interpolator); - QVERIFY(builder.indices().size() == 24); + QVERIFY(indices.size() == 24); - QVERIFY((builder.vertices() == vector{0, 2, 6, 8, 1, 4, 3, 4, 7, 5})); - QVERIFY((builder.indices() == vector{4, 5, 6, 7, 8, 9, 0, 4, 6, 4, 1, 5, 6, 5, 2, 1, 7, 9, 7, 2, 8, 9, 8, 3})); + QVERIFY((vertices == vector{0, 2, 6, 8, 1, 4, 3, 4, 7, 5})); + QVERIFY((indices == vector{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(builder, 1); + MeshTools::clean(indices, vertices); /* Vertices 0, 1, 2, 3, 4, 5, 6, 7, 8 */ - QVERIFY(builder.vertices().size() == 9); + QVERIFY(vertices.size() == 9); } }}} diff --git a/src/MeshTools/Tipsify.h b/src/MeshTools/Tipsify.h index d9acba3df..c5bda18d4 100644 --- a/src/MeshTools/Tipsify.h +++ b/src/MeshTools/Tipsify.h @@ -76,12 +76,11 @@ Triangle Reordering for Vertex Locality and Reduced Overdraw, SIGGRAPH This is convenience function supplementing direct usage of Tipsify class, instead of @code -MeshBuilder builder; -MeshTools::Tipsify{builder}(cacheSize); +MeshTools::Tipsify(indices, vertexCount)(cacheSize); @endcode you can just write @code -MeshTools::tipsify(builder, cacheSize); +MeshTools::tipsify(indices, vertexCount, cacheSize); @endcode */ inline void tipsify(std::vector& indices, unsigned int vertexCount, size_t cacheSize) {