diff --git a/src/MeshTools/CMakeLists.txt b/src/MeshTools/CMakeLists.txt index 785cd9253..4ccd61cd4 100644 --- a/src/MeshTools/CMakeLists.txt +++ b/src/MeshTools/CMakeLists.txt @@ -1,4 +1,5 @@ set(MagnumMeshTools_SRCS + FlipNormals.cpp GenerateFlatNormals.cpp Tipsify.cpp ) diff --git a/src/MeshTools/FlipNormals.cpp b/src/MeshTools/FlipNormals.cpp new file mode 100644 index 000000000..5d3e055b3 --- /dev/null +++ b/src/MeshTools/FlipNormals.cpp @@ -0,0 +1,38 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "FlipNormals.h" + +using namespace std; +using namespace Corrade::Utility; + +namespace Magnum { namespace MeshTools { + +void flipFaceWinding(vector& indices) { + if(indices.size()%3 != 0) { + Error() << "MeshTools::flipNormals(): index count is not divisible by 3!"; + return; + } + + for(size_t i = 0; i != indices.size(); i += 3) + swap(indices[i+1], indices[i+2]); +} + +void flipNormals(vector& normals) { + for(Vector3& normal: normals) + normal = -normal; +} + +}} diff --git a/src/MeshTools/FlipNormals.h b/src/MeshTools/FlipNormals.h new file mode 100644 index 000000000..e0585c0ee --- /dev/null +++ b/src/MeshTools/FlipNormals.h @@ -0,0 +1,61 @@ +#ifndef Magnum_MeshTools_FlipNormals_h +#define Magnum_MeshTools_FlipNormals_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +/** @file + * @brief Function Magnum::MeshTools::flipNormals() + */ + +#include "Magnum.h" + +namespace Magnum { namespace MeshTools { + +/** +@brief Flip face winding + +The same as flipNormals(std::vector&, std::vector&), +but flips only face winding. +*/ +void flipFaceWinding(std::vector& indices); + +/** +@brief Flip mesh normals + +The same as flipNormals(std::vector&, std::vector&), +but flips only normals, not face winding. +*/ +void flipNormals(std::vector& normals); + +/** +@brief Flip mesh normals and face winding +@param indices Index array to operate on +@param normals Normal array to operate on + +Flips normal vectors and face winding in index array for face culling to work +properly too. See also flipNormals(std::vector&) and +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& indices, std::vector& normals) { + flipFaceWinding(indices); + flipNormals(normals); +} + +}} + +#endif \ No newline at end of file diff --git a/src/MeshTools/Test/CMakeLists.txt b/src/MeshTools/Test/CMakeLists.txt index e01d10259..b8cc409af 100644 --- a/src/MeshTools/Test/CMakeLists.txt +++ b/src/MeshTools/Test/CMakeLists.txt @@ -1,6 +1,7 @@ corrade_add_test(CleanTest CleanTest.h CleanTest.cpp ${CORRADE_UTILITY_LIBRARY}) corrade_add_test(CombineIndexedArraysTest CombineIndexedArraysTest.h CombineIndexedArraysTest.cpp ${CORRADE_UTILITY_LIBRARY}) corrade_add_test(CompressIndicesTest CompressIndicesTest.h CompressIndicesTest.cpp ${CORRADE_UTILITY_LIBRARY} ${MAGNUM_LIBRARY}) +corrade_add_test(FlipNormalsTest FlipNormalsTest.h FlipNormalsTest.cpp ${MAGNUM_MESHTOOLS_LIBRARY}) corrade_add_test(GenerateFlatNormalsTest GenerateFlatNormalsTest.h GenerateFlatNormalsTest.cpp ${MAGNUM_MESHTOOLS_LIBRARY}) corrade_add_test(InterleaveTest InterleaveTest.h InterleaveTest.cpp ${CORRADE_UTILITY_LIBRARY}) corrade_add_test(SubdivideTest SubdivideTest.h SubdivideTest.cpp ${CORRADE_UTILITY_LIBRARY}) diff --git a/src/MeshTools/Test/FlipNormalsTest.cpp b/src/MeshTools/Test/FlipNormalsTest.cpp new file mode 100644 index 000000000..1e3e4290b --- /dev/null +++ b/src/MeshTools/Test/FlipNormalsTest.cpp @@ -0,0 +1,59 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "FlipNormalsTest.h" + +#include +#include +#include "MeshTools/FlipNormals.h" + +QTEST_APPLESS_MAIN(Magnum::MeshTools::Test::FlipNormalsTest) + +using namespace std; +using namespace Corrade::Utility; + +namespace Magnum { namespace MeshTools { namespace Test { + +void FlipNormalsTest::wrongIndexCount() { + stringstream ss; + Error::setOutput(&ss); + + vector indices{0, 1}; + MeshTools::flipFaceWinding(indices); + + QVERIFY(ss.str() == "MeshTools::flipNormals(): index count is not divisible by 3!\n"); +} + +void FlipNormalsTest::flipFaceWinding() { + vector indices{0, 1, 2, + 3, 4, 5}; + MeshTools::flipFaceWinding(indices); + + QVERIFY((indices == vector{0, 2, 1, + 3, 5, 4})); +} + +void FlipNormalsTest::flipNormals() { + vector normals{Vector3::xAxis(), + Vector3::yAxis(), + Vector3::zAxis()}; + MeshTools::flipNormals(normals); + + QVERIFY((normals == vector{-Vector3::xAxis(), + -Vector3::yAxis(), + -Vector3::zAxis()})); +} + +}}} diff --git a/src/MeshTools/Test/FlipNormalsTest.h b/src/MeshTools/Test/FlipNormalsTest.h new file mode 100644 index 000000000..382c89f74 --- /dev/null +++ b/src/MeshTools/Test/FlipNormalsTest.h @@ -0,0 +1,33 @@ +#ifndef Magnum_MeshTools_Test_FlipNormalsTest_h +#define Magnum_MeshTools_Test_FlipNormalsTest_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include + +namespace Magnum { namespace MeshTools { namespace Test { + +class FlipNormalsTest: public QObject { + Q_OBJECT + + private slots: + void wrongIndexCount(); + void flipFaceWinding(); + void flipNormals(); +}; + +}}} + +#endif