diff --git a/python/GafferSceneTest/IECoreScenePreviewTest/PrimitiveAlgoTest.py b/python/GafferSceneTest/IECoreScenePreviewTest/PrimitiveAlgoTest.py index 539cff0c85..ef84021a33 100644 --- a/python/GafferSceneTest/IECoreScenePreviewTest/PrimitiveAlgoTest.py +++ b/python/GafferSceneTest/IECoreScenePreviewTest/PrimitiveAlgoTest.py @@ -215,7 +215,22 @@ def testMergePrimitivesSimpleMeshes( self ) : IECore.V3fData( imath.V3f( 0.1, 0.2, 0.3 ), IECore.GeometricData.Interpretation.Point ) ) + with IECore.CapturingMessageHandler() as mh: + mergedWithMissingN = PrimitiveAlgo.mergePrimitives( [( mesh1, imath.M44f() ), ( mesh2, imath.M44f() ) ] ) + self.assertEqual( len( mh.messages ), 1 ) + self.assertEqual( mh.messages[0].context, "mergePrimitives" ) + self.assertEqual( mh.messages[0].message, 'Primitive variable N missing on some input primitives, defaulting to zero length normals.' ) + + # The effect of not specifying a normal is the same as a Constant, zero normal + mesh2["N"] = IECoreScene.PrimitiveVariable( Interpolation.Constant, + IECore.V3fData( imath.V3f( 0 ), IECore.GeometricData.Interpretation.Normal ) + ) + merged = PrimitiveAlgo.mergePrimitives( [( mesh1, imath.M44f() ), ( mesh2, imath.M44f() ) ] ) + print( merged["N"], "\n\n", mergedWithMissingN["N"] ) + self.assertEqual( merged["N"], mergedWithMissingN["N"] ) + self.assertEqual( merged, mergedWithMissingN ) + self.assertTrue( merged.arePrimitiveVariablesValid() ) self.assertEqual( merged.interpolation, "linear" ) self.assertEqual( merged.verticesPerFace, IECore.IntVectorData( [ 4, 3 ] ) ) @@ -436,8 +451,6 @@ def randomC(): self.assertEqual( len( mh.messages ), numDiscarded ) for k in allInterpsRef.keys(): - #if k == "P": - #continue kInterp = allInterps[k].interpolation @@ -621,7 +634,13 @@ def testMergeMeshes( self ) : self.resamplePrimVars( referencePlane, [ "altUv", "unindexedFaceVarying" ], Interpolation.FaceVarying ) # Merge 3 meshes - complex mesh, shifted complex mesh, and a plane - merged = PrimitiveAlgo.mergePrimitives( [( source, imath.M44f() ), ( sourcePlane, imath.M44f() ), ( sourceShifted, imath.M44f() )] ) + + with IECore.CapturingMessageHandler() as mh: + merged = PrimitiveAlgo.mergePrimitives( + [( source, imath.M44f() ), ( sourcePlane, imath.M44f() ), ( sourceShifted, imath.M44f() )] + ) + self.assertEqual( len( mh.messages ), 1 ) + self.assertEqual( mh.messages[0].message, 'Primitive variable N missing on some input primitives, defaulting to zero length normals.' ) referenceSource["N"] = IECoreScene.PrimitiveVariable( Interpolation.Vertex, IECore.V3fVectorData( [imath.V3f( 0 ) ] * referenceSource.variableSize( Interpolation.Vertex ) ) ) referenceShifted["N"] = IECoreScene.PrimitiveVariable( Interpolation.Vertex, IECore.V3fVectorData( [imath.V3f( 0 ) ] * referenceSource.variableSize( Interpolation.Vertex ) ) ) diff --git a/src/GafferScene/IECoreScenePreview/PrimitiveAlgo.cpp b/src/GafferScene/IECoreScenePreview/PrimitiveAlgo.cpp index 405c8406f0..8fe4f67355 100644 --- a/src/GafferScene/IECoreScenePreview/PrimitiveAlgo.cpp +++ b/src/GafferScene/IECoreScenePreview/PrimitiveAlgo.cpp @@ -1029,6 +1029,8 @@ IECoreScene::PrimitivePtr mergePrimitivesInternal( // We also need to count the amount of data for this primvar contributed by each primitive. + + bool incomplete = false; for( unsigned int i = 0; i < primitives.size(); i++ ) { @@ -1046,6 +1048,7 @@ IECoreScene::PrimitivePtr mergePrimitivesInternal( // the indexed case. varInfo.numData[i] = 1; varInfo.indexed = true; + incomplete = true; continue; } @@ -1058,6 +1061,18 @@ IECoreScene::PrimitivePtr mergePrimitivesInternal( varInfo.indexed = true; } } + + if( incomplete ) + { + if( name == "N" ) + { + // Using default initialized normals is particularly likely to produce confusion, so we have a special + // warning for this case. + msg( Msg::Warning, "mergePrimitives", + "Primitive variable N missing on some input primitives, defaulting to zero length normals." + ); + } + } } //