diff --git a/src/Magnum/MeshTools/FlipNormals.cpp b/src/Magnum/MeshTools/FlipNormals.cpp index 05089b132..6adde3a47 100644 --- a/src/Magnum/MeshTools/FlipNormals.cpp +++ b/src/Magnum/MeshTools/FlipNormals.cpp @@ -56,6 +56,18 @@ void flipFaceWindingInPlace(const Containers::StridedArrayView1D& flipFaceWindingInPlaceImplementation(indices); } +void flipFaceWindingInPlace(const Containers::StridedArrayView2D& indices) { + CORRADE_ASSERT(indices.isContiguous<1>(), "MeshTools::flipFaceWindingInPlace(): second index view dimension is not contiguous", ); + if(indices.size()[1] == 4) + return flipFaceWindingInPlaceImplementation(Containers::arrayCast<1, UnsignedInt>(indices)); + else if(indices.size()[1] == 2) + return flipFaceWindingInPlaceImplementation(Containers::arrayCast<1, UnsignedShort>(indices)); + else { + CORRADE_ASSERT(indices.size()[1] == 1, "MeshTools::flipFaceWindingInPlace(): expected index type size 1, 2 or 4 but got" << indices.size()[1], ); + return flipFaceWindingInPlaceImplementation(Containers::arrayCast<1, UnsignedByte>(indices)); + } +} + void flipNormalsInPlace(const Containers::StridedArrayView1D& normals) { for(Vector3& normal: normals) normal = -normal; diff --git a/src/Magnum/MeshTools/FlipNormals.h b/src/Magnum/MeshTools/FlipNormals.h index de9e863ec..65e67084c 100644 --- a/src/Magnum/MeshTools/FlipNormals.h +++ b/src/Magnum/MeshTools/FlipNormals.h @@ -67,6 +67,17 @@ void flipNormalsInPlace(const Containers::StridedArrayView1D& ind */ void flipNormalsInPlace(const Containers::StridedArrayView1D& indices, const Containers::StridedArrayView1D& normals); +/** +@brief Flip mesh normals and face winding in-place on a type-erased index array +@m_since_latest + +Expects that the second dimension of @p indices is contiguous and represents +the actual 1/2/4-byte index type. Based on its size then calls one of the +@ref flipNormalsInPlace(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) +etc. overloads. +*/ +void flipNormalsInPlace(const Containers::StridedArrayView2D& indices, const Containers::StridedArrayView1D& normals); + #ifdef MAGNUM_BUILD_DEPRECATED /** @brief @copybrief flipNormalsInPlace(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) @@ -99,6 +110,17 @@ void MAGNUM_MESHTOOLS_EXPORT flipFaceWindingInPlace(const Containers::StridedArr */ void MAGNUM_MESHTOOLS_EXPORT flipFaceWindingInPlace(const Containers::StridedArrayView1D& indices); +/** +@brief Flip face winding in-place on a type-erased index array +@m_since_latest + +Expects that the second dimension of @p indices is contiguous and represents +the actual 1/2/4-byte index type. Based on its size then calls one of the +@ref flipFaceWindingInPlace(const Containers::StridedArrayView1D&) +etc. overloads. +*/ +void MAGNUM_MESHTOOLS_EXPORT flipFaceWindingInPlace(const Containers::StridedArrayView2D& indices); + #ifdef MAGNUM_BUILD_DEPRECATED /** @brief @copybrief flipFaceWindingInPlace(const Containers::StridedArrayView1D&) @@ -141,6 +163,11 @@ inline void flipNormalsInPlace(const Containers::StridedArrayView1D& indices, const Containers::StridedArrayView1D& normals) { + flipFaceWindingInPlace(indices); + flipNormalsInPlace(normals); +} + }} #endif diff --git a/src/Magnum/MeshTools/Test/FlipNormalsTest.cpp b/src/Magnum/MeshTools/Test/FlipNormalsTest.cpp index 9f2049fc4..626aa6040 100644 --- a/src/Magnum/MeshTools/Test/FlipNormalsTest.cpp +++ b/src/Magnum/MeshTools/Test/FlipNormalsTest.cpp @@ -39,9 +39,11 @@ struct FlipNormalsTest: TestSuite::Tester { void wrongIndexCount(); template void flipFaceWinding(); + template void flipFaceWindingErased(); void flipNormals(); template void flipNormalsFaceWinding(); + template void flipNormalsFaceWindingErased(); }; FlipNormalsTest::FlipNormalsTest() { @@ -49,11 +51,18 @@ FlipNormalsTest::FlipNormalsTest() { &FlipNormalsTest::flipFaceWinding, &FlipNormalsTest::flipFaceWinding, &FlipNormalsTest::flipFaceWinding, + &FlipNormalsTest::flipFaceWindingErased, + &FlipNormalsTest::flipFaceWindingErased, + &FlipNormalsTest::flipFaceWindingErased, &FlipNormalsTest::flipNormals, &FlipNormalsTest::flipNormalsFaceWinding, &FlipNormalsTest::flipNormalsFaceWinding, - &FlipNormalsTest::flipNormalsFaceWinding}); + &FlipNormalsTest::flipNormalsFaceWinding, + &FlipNormalsTest::flipNormalsFaceWindingErased, + &FlipNormalsTest::flipNormalsFaceWindingErased, + &FlipNormalsTest::flipNormalsFaceWindingErased, + }); } void FlipNormalsTest::wrongIndexCount() { @@ -77,6 +86,17 @@ template void FlipNormalsTest::flipFaceWinding() { TestSuite::Compare::Container); } +template void FlipNormalsTest::flipFaceWindingErased() { + setTestCaseTemplateName(Math::TypeTraits::name()); + + T indices[]{0, 1, 2, 3, 4, 5}; + MeshTools::flipFaceWindingInPlace(indices); + + CORRADE_COMPARE_AS(Containers::arrayView(indices), + Containers::arrayView({0, 2, 1, 3, 5, 4}), + TestSuite::Compare::Container); +} + void FlipNormalsTest::flipNormals() { Vector3 normals[]{Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis()}; MeshTools::flipNormalsInPlace(normals); @@ -103,6 +123,24 @@ template void FlipNormalsTest::flipNormalsFaceWinding() { }), TestSuite::Compare::Container); } +template void FlipNormalsTest::flipNormalsFaceWindingErased() { + setTestCaseTemplateName(Math::TypeTraits::name()); + + T indices[]{0, 1, 2, 3, 4, 5}; + Vector3 normals[]{Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis()}; + MeshTools::flipNormalsInPlace( + Containers::arrayCast<2, char>(Containers::stridedArrayView(indices)), + normals); + + CORRADE_COMPARE_AS(Containers::arrayView(indices), + Containers::arrayView({0, 2, 1, 3, 5, 4}), + TestSuite::Compare::Container); + CORRADE_COMPARE_AS(Containers::arrayView(normals), + Containers::arrayView({ + -Vector3::xAxis(), -Vector3::yAxis(), -Vector3::zAxis() + }), TestSuite::Compare::Container); +} + }}}} CORRADE_TEST_MAIN(Magnum::MeshTools::Test::FlipNormalsTest)