From 0fc5f57b0126ae52b314eccd3d55f899340e3711 Mon Sep 17 00:00:00 2001 From: John Haddon Date: Mon, 21 Sep 2026 15:37:38 +0100 Subject: [PATCH] MeshAlgo : Anchor the first vertex in `MeshAlgo::reverseWinding()` --- Changes | 8 ++++++++ .../IECoreAlembic/test/IECoreAlembic/AlembicSceneTest.py | 2 +- src/IECoreScene/MeshAlgoWinding.cpp | 9 ++++++++- test/IECoreScene/MeshAlgoWindingTest.py | 6 +++--- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Changes b/Changes index 8ef2451314..3bf72f9158 100644 --- a/Changes +++ b/Changes @@ -1,7 +1,15 @@ 10.7.x.x (relative to 10.7.1.3) ======== +Improvements +------------ + +- MeshAlgo : Changed `reverseWinding()` so that the first vertex of each face remains unchanged. This matches the algorithm used in other DCCs. + +Breaking Changes +---------------- +- MeshAlgo : Changed the output of `reverseWinding()`. 10.7.1.3 (relative to 10.7.1.2) ======== diff --git a/contrib/IECoreAlembic/test/IECoreAlembic/AlembicSceneTest.py b/contrib/IECoreAlembic/test/IECoreAlembic/AlembicSceneTest.py index 3cc171db12..1e1465c111 100644 --- a/contrib/IECoreAlembic/test/IECoreAlembic/AlembicSceneTest.py +++ b/contrib/IECoreAlembic/test/IECoreAlembic/AlembicSceneTest.py @@ -294,10 +294,10 @@ def testConvertArbGeomParams( self ) : self.assertEqual( m["colorSet1"].expandedData(), IECore.Color4fVectorData( [ + imath.Color4f( 0, 1, 0, 1 ), imath.Color4f( 1, 0, 0, 1 ), imath.Color4f( 0, 0, 0, 1 ), imath.Color4f( 0, 0, 1, 1 ), - imath.Color4f( 0, 1, 0, 1 ), ] ) ) diff --git a/src/IECoreScene/MeshAlgoWinding.cpp b/src/IECoreScene/MeshAlgoWinding.cpp index ee4c1de0eb..ff02e82c31 100644 --- a/src/IECoreScene/MeshAlgoWinding.cpp +++ b/src/IECoreScene/MeshAlgoWinding.cpp @@ -56,7 +56,14 @@ void reverseWinding( MeshPrimitive *mesh, T &values, const Canceller *canceller for( PolygonIterator it = mesh->faceBegin(), eIt = mesh->faceEnd(); it != eIt; ++it ) { Canceller::check( canceller ); - std::reverse( it.faceVaryingBegin( values.begin() ), it.faceVaryingEnd( values.begin() ) ); + auto b = it.faceVaryingBegin( values.begin() ); + auto e = it.faceVaryingEnd( values.begin() ); + if( b == e ) + { + continue; + } + ++b; + std::reverse( b, e ); } } diff --git a/test/IECoreScene/MeshAlgoWindingTest.py b/test/IECoreScene/MeshAlgoWindingTest.py index e6b956bbe3..10d13292b2 100644 --- a/test/IECoreScene/MeshAlgoWindingTest.py +++ b/test/IECoreScene/MeshAlgoWindingTest.py @@ -78,8 +78,8 @@ def testSingleTriangle( self ) : # Except for vertex ids, and facevarying data - self.assertEqual( list( meshReversed.vertexIds ), list( reversed( mesh.vertexIds ) ) ) - self.assertEqual( list( meshReversed["uv"].data ), list( reversed( mesh["uv"].data ) ) ) + self.assertEqual( list( meshReversed.vertexIds ), list( mesh.vertexIds[:1] ) + list( reversed( mesh.vertexIds[1:] ) ) ) + self.assertEqual( list( meshReversed["uv"].data ), list( mesh["uv"].data[:1] ) + list( reversed( mesh["uv"].data[1:] ) ) ) def testPlane( self ) : @@ -142,7 +142,7 @@ def testUVIndices( self ) : # UV indices should change, but UV data doesn't need to self.assertEqual( meshReversed["uv"].data, mesh["uv"].data ) - self.assertEqual( list( meshReversed["uv"].indices ), list( reversed( mesh["uv"].indices ) ) ) + self.assertEqual( list( meshReversed["uv"].indices ), list( mesh["uv"].indices[:1] ) + list( reversed( mesh["uv"].indices[1:] ) ) ) def testReferencedData( self ) :