def testDeleteExisting(self): plane = GafferScene.Plane() aAttributes = GafferScene.CustomAttributes() aAttributes["in"].setInput(plane["out"]) a = Gaffer.NameValuePlug("a", IECore.IntData(1)) aAttributes["attributes"].addChild(a) bAttributes = GafferScene.CustomAttributes() bAttributes["in"].setInput(plane["out"]) b = Gaffer.NameValuePlug("b", IECore.IntData(2)) bAttributes["attributes"].addChild(b) copyAttributes = GafferScene.CopyAttributes() copyAttributes["in"].setInput(aAttributes["out"]) copyAttributes["source"].setInput(bAttributes["out"]) f = GafferScene.PathFilter() f["paths"].setValue(IECore.StringVectorData(["/plane"])) copyAttributes["filter"].setInput(f["out"]) # Delete existing off. self.assertEqual( copyAttributes["out"].attributes("/plane"), IECore.CompoundObject({ "a": aAttributes["out"].attributes("/plane")["a"], "b": bAttributes["out"].attributes("/plane")["b"], })) # Delete existing on. copyAttributes["deleteExisting"].setValue(True) self.assertEqual( copyAttributes["out"].attributes("/plane"), IECore.CompoundObject({ "b": bAttributes["out"].attributes("/plane")["b"], })) # We shouldn't even evaluate the incoming attributes if # we're going to delete them anyway. a["value"].setValue(20) # Invalidate cache b["value"].setValue(30) # Invalidate cache with Gaffer.PerformanceMonitor() as pm: copyAttributes["out"].attributes("/plane") self.assertIn(bAttributes["out"]["attributes"], pm.allStatistics()) self.assertNotIn(aAttributes["out"]["attributes"], pm.allStatistics())
def testOverrideAttributes( self ) : sphere = IECoreScene.SpherePrimitive() input = GafferSceneTest.CompoundObjectSource() input["in"].setValue( IECore.CompoundObject( { "bound" : IECore.Box3fData( sphere.bound() ), "children" : { "ball1" : { "object" : sphere, "bound" : IECore.Box3fData( sphere.bound() ), }, }, } ) ) a = GafferScene.CustomAttributes() a["in"].setInput( input["out"] ) a["attributes"].addChild( Gaffer.NameValuePlug( "ri:shadingRate", IECore.FloatData( 0.25 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic ) ) a["attributes"].addChild( Gaffer.NameValuePlug( "user:something", IECore.IntData( 1 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic ) ) self.assertEqual( a["out"].attributes( "/ball1" ), IECore.CompoundObject( { "ri:shadingRate" : IECore.FloatData( 0.25 ), "user:something" : IECore.IntData( 1 ), } ) ) a2 = GafferScene.CustomAttributes() a2["in"].setInput( a["out"] ) self.assertEqual( a2["out"].attributes( "/ball1" ), IECore.CompoundObject( { "ri:shadingRate" : IECore.FloatData( 0.25 ), "user:something" : IECore.IntData( 1 ), } ) ) a2["attributes"].addChild( Gaffer.NameValuePlug( "ri:shadingRate", IECore.FloatData( .5 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic ) ) a2["attributes"].addChild( Gaffer.NameValuePlug( "user:somethingElse", IECore.IntData( 10 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic ) ) self.assertEqual( a2["out"].attributes( "/ball1" ), IECore.CompoundObject( { "ri:shadingRate" : IECore.FloatData( 0.5 ), "user:something" : IECore.IntData( 1 ), "user:somethingElse" : IECore.IntData( 10 ), } ) )
def testDirtyPropagation(self): attributes = GafferScene.CustomAttributes() cs = GafferTest.CapturingSlot(attributes.plugDirtiedSignal()) # Adding or removing an attribute should dirty `out.attributes` attributes["attributes"].addChild( Gaffer.NameValuePlug("test", 10, flags=Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic)) self.assertIn(attributes["out"]["attributes"], {x[0] for x in cs}) del cs[:] del attributes["attributes"][0] self.assertIn(attributes["out"]["attributes"], {x[0] for x in cs}) # And although the Dynamic flag is currently required for proper serialisation # of CustomAttributes nodes, its absence shouldn't prevent dirty propagation. # We hope to be able to remove the Dynamic flag completely in the future. del cs[:] attributes["attributes"].addChild(Gaffer.NameValuePlug("test2", 10)) self.assertIn(attributes["out"]["attributes"], {x[0] for x in cs}) del cs[:] del attributes["attributes"][0] self.assertIn(attributes["out"]["attributes"], {x[0] for x in cs})
def testAssignShader(self): script = Gaffer.ScriptNode() script["sphere"] = GafferScene.Sphere() script["sphereFilter"] = GafferScene.PathFilter() script["sphereFilter"]["paths"].setValue( IECore.StringVectorData(["/sphere"])) attributes = IECore.CompoundObject({ "ai:surface": IECoreScene.ShaderNetwork({"output": IECoreScene.Shader("flat")}, output="output") }) script["attributes"] = GafferScene.CustomAttributes() script["attributes"]["in"].setInput(script["sphere"]["out"]) script["attributes"]["filter"].setInput(script["sphereFilter"]["out"]) script["attributes"]["extraAttributes"].setValue(attributes) self.assertEqual(script["attributes"]["out"].attributes("/sphere"), attributes) script2 = Gaffer.ScriptNode() script2.execute(script.serialise()) self.assertEqual(script2["attributes"]["out"].attributes("/sphere"), attributes)
def testAffects(self): s = Gaffer.ScriptNode() s["a"] = GafferScene.CustomAttributes() p = Gaffer.NameValuePlug("user:test", 10, flags=Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic) s["a"]["attributes"].addChild(p) self.assertEqual(set(s["a"].affects(p["value"])), set([s["a"]["out"]["attributes"]])) self.assertEqual(set(s["a"].affects(s["a"]["extraAttributes"])), set([s["a"]["out"]["attributes"]])) s["a"]["global"].setValue(True) self.assertEqual(set(s["a"].affects(p["value"])), set([s["a"]["out"]["globals"]])) self.assertEqual(set(s["a"].affects(s["a"]["extraAttributes"])), set([s["a"]["out"]["globals"]])) s["e"] = Gaffer.Expression() s["e"].setExpression( """parent["a"]["global"] = context.getFrame() > 10""") self.assertEqual( set(s["a"].affects(p["value"])), set([s["a"]["out"]["attributes"], s["a"]["out"]["globals"]]))
def testCopyPasteDoesntRetainFilterValue(self): s = Gaffer.ScriptNode() s["p"] = GafferScene.Plane() s["f"] = GafferScene.PathFilter() s["a"] = GafferScene.CustomAttributes() s["a"]["attributes"].addChild( Gaffer.NameValuePlug("user:test", IECore.IntData(10), flags=Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic)) self.assertTrue("user:test" in s["a"]["out"].attributes("/plane")) s["a"]["filter"].setInput(s["f"]["out"]) self.assertFalse("user:test" in s["a"]["out"].attributes("/plane")) ss = s.serialise(filter=Gaffer.StandardSet([s["p"], s["a"]])) s = Gaffer.ScriptNode() s.execute(ss) self.assertTrue("f" not in s) self.assertTrue("user:test" in s["a"]["out"].attributes("/plane"))
def testExtraAttributes( self ) : s = Gaffer.ScriptNode() s["sphere"] = GafferScene.Sphere() s["a"] = GafferScene.CustomAttributes() s["f"] = GafferScene.PathFilter() s["f"]["paths"].setValue( IECore.StringVectorData( [ "/sphere" ] ) ) s["a"]["filter"].setInput( s["f"]["out"] ) s["a"]["extraAttributes"].setValue(IECore.CompoundData({ "a1" : IECore.StringData( "from extra" ), "a2" : IECore.IntData( 2 ), })) s["a"]["attributes"].addChild( Gaffer.NameValuePlug( "a1", IECore.StringData( "from attributes" ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic ) ) s["a"]["attributes"].addChild( Gaffer.NameValuePlug( "a3", IECore.IntData( 5 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic ) ) self.assertEqual( s["a"]["out"].attributes( "/sphere" ), IECore.CompoundObject( { "a1" : IECore.StringData( "from extra" ), "a2" : IECore.IntData( 2 ), "a3" : IECore.IntData( 5 ), } ) )
def test(self): plane = GafferScene.Plane() customAttributes = GafferScene.CustomAttributes() customAttributes["in"].setInput(plane["out"]) customAttributes["attributes"].addMember("a", IECore.IntData(1)) customAttributes["attributes"].addMember("b", IECore.IntData(2)) # Node should do nothing without a filter applied. copyAttributes = GafferScene.CopyAttributes() copyAttributes["in"][0].setInput(plane["out"]) copyAttributes["in"][1].setInput(customAttributes["out"]) self.assertScenesEqual(plane["out"], copyAttributes["out"]) self.assertSceneHashesEqual(plane["out"], copyAttributes["out"]) # Applying a filter should kick it into action. f = GafferScene.PathFilter() f["paths"].setValue(IECore.StringVectorData(["/plane"])) copyAttributes["filter"].setInput(f["out"]) self.assertEqual(copyAttributes["out"].attributes("/plane"), customAttributes["out"].attributes("/plane")) # We should be able to copy just some attributes. copyAttributes["attributes"].setValue("a") self.assertEqual(copyAttributes["out"].attributes("/plane").keys(), ["a"]) self.assertEqual(copyAttributes["out"].attributes("/plane")["a"], customAttributes["out"].attributes("/plane")["a"])
def testLoadReferenceAndGIL( self ) : script = Gaffer.ScriptNode() script["plane"] = GafferScene.Plane() script["plane"]["divisions"].setValue( imath.V2i( 20 ) ) script["sphere"] = GafferScene.Sphere() script["expression"] = Gaffer.Expression() script["expression"].setExpression( "parent['sphere']['radius'] = 0.1 + context.getFrame()" ) script["instancer"] = GafferScene.Instancer() script["instancer"]["in"].setInput( script["plane"]["out"] ) script["instancer"]["instances"].setInput( script["sphere"]["out"] ) script["instancer"]["parent"].setValue( "/plane" ) script["box"] = Gaffer.Box() script["box"]["in"] = GafferScene.ScenePlug( flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic ) script["box"]["out"] = GafferScene.ScenePlug( direction = Gaffer.Plug.Direction.Out, flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic ) script["box"]["out"].setInput( script["box"]["in"] ) script["box"].exportForReference( self.temporaryDirectory() + "/test.grf" ) script["reference"] = Gaffer.Reference() script["reference"].load( self.temporaryDirectory() + "/test.grf" ) script["reference"]["in"].setInput( script["instancer"]["out"] ) script["attributes"] = GafferScene.CustomAttributes() script["attributes"]["in"].setInput( script["reference"]["out"] ) traverseConnection = Gaffer.ScopedConnection( GafferSceneTest.connectTraverseSceneToPlugDirtiedSignal( script["attributes"]["out"] ) ) with Gaffer.Context() as c : script["reference"].load( self.temporaryDirectory() + "/test.grf" )
def testNullObjects(self): camera = GafferScene.Camera() sphere = GafferScene.Sphere() light = GafferSceneTest.TestLight() lightAttr = GafferScene.StandardAttributes() lightAttr["in"].setInput(sphere["out"]) lightAttr["attributes"]["linkedLights"]["enabled"].setValue(True) lightAttr["attributes"]["linkedLights"]["value"].setValue( "defaultLights") group = GafferScene.Group() group["in"][0].setInput(camera["out"]) group["in"][1].setInput(sphere["out"]) group["in"][2].setInput(light["out"]) allFilter = GafferScene.PathFilter() allFilter["paths"].setValue(IECore.StringVectorData(["..."])) attr = GafferScene.CustomAttributes() unrenderableAttrPlug = Gaffer.NameValuePlug( "cr:unrenderable", IECore.BoolData(True), flags=Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic) attr["attributes"].addChild(unrenderableAttrPlug) attr["filter"].setInput(allFilter["out"]) attr["in"].setInput(group["out"]) renderer = GafferScene.Private.IECoreScenePreview.CapturingRenderer() controller = GafferScene.RenderController(attr["out"], Gaffer.Context(), renderer) controller.setMinimumExpansionDepth(10) controller.update()
def testDeleteSourceLocation(self): sphere = GafferScene.Sphere() sphereFilter = GafferScene.PathFilter() sphereFilter["paths"].setValue(IECore.StringVectorData(["/sphere"])) sphereAttributes = GafferScene.CustomAttributes() sphereAttributes["in"].setInput(sphere["out"]) sphereAttributes["filter"].setInput(sphereFilter["out"]) sphereAttributes["attributes"].addChild(Gaffer.NameValuePlug( "test", 1)) prune = GafferScene.Prune() prune["in"].setInput(sphereAttributes["out"]) copy = GafferScene.CopyAttributes() copy["in"].setInput(sphere["out"]) copy["source"].setInput(prune["out"]) copy["filter"].setInput(sphereFilter["out"]) copy["attributes"].setValue("*") self.assertScenesEqual(copy["out"], sphereAttributes["out"]) prune["filter"].setInput(sphereFilter["out"]) self.assertScenesEqual(copy["out"], sphere["out"])
def testWildcards(self): p = GafferScene.Plane() a = GafferScene.CustomAttributes() a["in"].setInput(p["out"]) a["attributes"].addMember("a1", 1) a["attributes"].addMember("a2", 2) a["attributes"].addMember("b1", 1) a["attributes"].addMember("b2", 1) d = GafferScene.DeleteAttributes() d["in"].setInput(a["out"]) self.assertEqual(set(d["out"].attributes("/plane").keys()), set(["a1", "a2", "b1", "b2"])) d["names"].setValue("a*") self.assertEqual(set(d["out"].attributes("/plane").keys()), set(["b1", "b2"])) d["names"].setValue("*1") self.assertEqual(set(d["out"].attributes("/plane").keys()), set(["a2", "b2"])) d["names"].setValue("*1 b2") self.assertEqual(set(d["out"].attributes("/plane").keys()), set(["a2"])) d["names"].setValue("b2 a*") self.assertEqual(set(d["out"].attributes("/plane").keys()), set(["b1"]))
def __createXRayShader(): # ideally this could be any type of node (eg Box), but # SceneView seems to require a SceneProcessor. xray = GafferScene.SceneProcessor("XRay") xray["attributes"] = GafferScene.CustomAttributes() xray["attributes"]["attributes"].addChild( Gaffer.NameValuePlug("gl:depthTest", Gaffer.BoolPlug("value", defaultValue=False), True, "depthTest")) xray["attributes"]["in"].setInput(xray["in"]) xray["assignment"] = GafferScene.ShaderAssignment() xray["assignment"]["in"].setInput(xray["attributes"]["out"]) xray["shader"] = GafferScene.OpenGLShader("XRay") xray["shader"]["name"].setValue("xray") xray["shader"]["type"].setValue("gl:surface") xray["shader"]["parameters"].addChild( Gaffer.StringPlug("glFragmentSource", defaultValue=inspect.cleandoc(''' in vec3 fragmentN; in vec3 fragmentI; void main() { float f = abs( dot( normalize( fragmentI ), normalize( fragmentN ) ) ); gl_FragColor = vec4( mix( vec3( 0.7 ), vec3( 0.5 ), f ), 0.5 ); } '''))) xray["shader"]["out"] = Gaffer.Plug() xray["assignment"]["shader"].setInput(xray["shader"]["out"]) xray["out"].setInput(xray["assignment"]["out"]) return xray
def testCopyFrom(self): plane = GafferScene.Plane() sphere = GafferScene.Sphere() sphereAttributes = GafferScene.CustomAttributes() sphereAttributes["in"].setInput(sphere["out"]) sphereAttributes["attributes"].addMember("a", IECore.IntData(2)) parent = GafferScene.Parent() parent["parent"].setValue("/") parent["in"].setInput(plane["out"]) parent["child"].setInput(sphereAttributes["out"]) copyAttributes = GafferScene.CopyAttributes() copyAttributes["in"][0].setInput(parent["out"]) copyAttributes["in"][1].setInput(parent["out"]) f = GafferScene.PathFilter() f["paths"].setValue(IECore.StringVectorData(["/plane"])) copyAttributes["filter"].setInput(f["out"]) self.assertEqual(copyAttributes["out"].attributes("/plane"), parent["out"].attributes("/plane")) copyAttributes["copyFrom"].setValue("/sphere") self.assertEqual(copyAttributes["out"].attributes("/plane"), parent["out"].attributes("/sphere"))
def testSourceLocation(self): plane = GafferScene.Plane() sphere = GafferScene.Sphere() sphereAttributes = GafferScene.CustomAttributes() sphereAttributes["in"].setInput(sphere["out"]) sphereAttributes["attributes"].addChild( Gaffer.NameValuePlug("a", IECore.IntData(2))) parent = GafferScene.Parent() parent["parent"].setValue("/") parent["in"].setInput(plane["out"]) parent["children"][0].setInput(sphereAttributes["out"]) copyAttributes = GafferScene.CopyAttributes() copyAttributes["in"].setInput(parent["out"]) copyAttributes["source"].setInput(parent["out"]) f = GafferScene.PathFilter() f["paths"].setValue(IECore.StringVectorData(["/plane"])) copyAttributes["filter"].setInput(f["out"]) self.assertEqual(copyAttributes["out"].attributes("/plane"), parent["out"].attributes("/plane")) copyAttributes["sourceLocation"].setValue("/sphere") self.assertEqual(copyAttributes["out"].attributes("/plane"), parent["out"].attributes("/sphere"))
def testOutPlugNotSerialised(self): s = Gaffer.ScriptNode() s["a"] = GafferScene.CustomAttributes() ss = s.serialise() self.failIf("out" in ss)
def testHashPassThrough(self): sphere = IECore.SpherePrimitive() input = GafferSceneTest.CompoundObjectSource() input["in"].setValue( IECore.CompoundObject({ "bound": IECore.Box3fData(sphere.bound()), "children": { "ball1": { "object": sphere, "bound": IECore.Box3fData(sphere.bound()), }, "ball2": { "object": sphere, "bound": IECore.Box3fData(sphere.bound()), }, }, })) a = GafferScene.CustomAttributes() a["in"].setInput(input["out"]) # when we have no attributes at all, everything should be a pass-through self.assertSceneHashesEqual(input["out"], a["out"]) # when we have some attributes, everything except the attributes plug should # be a pass-through. a["attributes"].addMember("ri:shadingRate", IECore.FloatData(2.0)) self.assertSceneHashesEqual(input["out"], a["out"], childPlugNames=("globals", "childNames", "transform", "bound", "object")) self.assertSceneHashesNotEqual(input["out"], a["out"], childPlugNames=("attributes", )) # when we add a filter, non-matching objects should become pass-throughs f = GafferScene.PathFilter() f["paths"].setValue(IECore.StringVectorData(["/ball1"])) a["filter"].setInput(f["match"]) self.assertSceneHashesEqual(input["out"], a["out"], pathsToIgnore=("/ball1", )) c = Gaffer.Context() c["scene:path"] = IECore.InternedStringVectorData(["ball1"]) with c: self.assertEqual(a["out"]["childNames"].hash(), input["out"]["childNames"].hash()) self.assertEqual(a["out"]["transform"].hash(), input["out"]["transform"].hash()) self.assertEqual(a["out"]["bound"].hash(), input["out"]["bound"].hash()) self.assertEqual(a["out"]["object"].hash(), input["out"]["object"].hash()) self.assertNotEqual(a["out"]["attributes"].hash(), input["out"]["attributes"].hash())
def testShaderSubstitutions( self ) : plane = GafferScene.Plane() planeAttrs = GafferScene.CustomAttributes() planeAttrs["in"].setInput( plane["out"] ) planeAttrs["attributes"].addChild( Gaffer.NameValuePlug( "A", Gaffer.StringPlug( "value", defaultValue = 'bar' ) ) ) planeAttrs["attributes"].addChild( Gaffer.NameValuePlug( "B", Gaffer.StringPlug( "value", defaultValue = 'foo' ) ) ) cube = GafferScene.Cube() cubeAttrs = GafferScene.CustomAttributes() cubeAttrs["in"].setInput( cube["out"] ) cubeAttrs["attributes"].addChild( Gaffer.NameValuePlug( "B", Gaffer.StringPlug( "value", defaultValue = 'override' ) ) ) parent = GafferScene.Parent() parent["in"].setInput( planeAttrs["out"] ) parent["child"].setInput( cubeAttrs["out"] ) parent["parent"].setValue( "/plane" ) shader = GafferOSL.OSLShader() shader.loadShader( "as_texture" ) shader["parameters"]["in_filename"].setValue( "<attr:A>/path/<attr:B>.tx" ) f = GafferScene.PathFilter() f["paths"].setValue( IECore.StringVectorData( [ "/plane" ] ) ) shaderAssignment = GafferScene.ShaderAssignment() shaderAssignment["in"].setInput( parent["out"] ) shaderAssignment["filter"].setInput( f["out"] ) shaderAssignment["shader"].setInput( shader["out"] ) render = GafferAppleseed.AppleseedRender() render["in"].setInput( shaderAssignment["out"] ) render["mode"].setValue( render.Mode.SceneDescriptionMode ) render["fileName"].setValue( os.path.join( self.temporaryDirectory(), "test.appleseed" ) ) self.assertNotEqual( render["task"].hash(), IECore.MurmurHash() ) render["task"].execute() self.assertTrue( os.path.exists( render["fileName"].getValue() ) ) f = open( render["fileName"].getValue(), "r" ) texturePaths = set( re.findall( '<parameter name="in_filename" value="string (.*)"', f.read()) ) self.assertEqual( texturePaths, set( ['bar/path/foo.tx', 'bar/path/override.tx' ] ) )
def test(self): sphere = IECoreScene.SpherePrimitive() input = GafferSceneTest.CompoundObjectSource() input["in"].setValue( IECore.CompoundObject({ "bound": IECore.Box3fData(sphere.bound()), "children": { "ball1": { "object": sphere, "bound": IECore.Box3fData(sphere.bound()), }, "ball2": { "object": sphere, "bound": IECore.Box3fData(sphere.bound()), }, }, })) a = GafferScene.CustomAttributes() a["in"].setInput(input["out"]) # should be no attributes until we've specified any self.assertEqual(a["out"].attributes("/"), IECore.CompoundObject()) self.assertEqual(a["out"].attributes("/ball1"), IECore.CompoundObject()) self.assertEqual(a["out"].attributes("/ball2"), IECore.CompoundObject()) # when we specify some, they should be applied to everything because # we haven't specified a filter yet. but not to the root because it # isn't allowed attributes. a["attributes"].addChild( Gaffer.NameValuePlug("ri:shadingRate", IECore.FloatData(0.25), flags=Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic)) self.assertEqual(a["out"].attributes("/"), IECore.CompoundObject()) self.assertEqual( a["out"].attributes("/ball1"), IECore.CompoundObject({"ri:shadingRate": IECore.FloatData(0.25)})) self.assertEqual( a["out"].attributes("/ball2"), IECore.CompoundObject({"ri:shadingRate": IECore.FloatData(0.25)})) # finally once we've applied a filter, we should get some attributes. f = GafferScene.PathFilter() f["paths"].setValue(IECore.StringVectorData(["/ball1"])) a["filter"].setInput(f["out"]) self.assertEqual(a["out"].attributes("/"), IECore.CompoundObject()) self.assertEqual( a["out"].attributes("/ball1"), IECore.CompoundObject({"ri:shadingRate": IECore.FloatData(0.25)})) self.assertEqual(a["out"].attributes("/ball2"), IECore.CompoundObject())
def testGlobalCameraVisibility( self ) : s = Gaffer.ScriptNode() s["s"] = GafferScene.Sphere() s["g"] = GafferScene.Group() s["g"]["in"].setInput( s["s"]["out"] ) s["a"] = GafferScene.CustomAttributes() s["a"]["in"].setInput( s["g"]["out"] ) s["a"]["global"].setValue( True ) visibilityPlug = s["a"]["attributes"].addMember( self._cameraVisibilityAttribute(), True ) s["o"] = GafferScene.Outputs() s["o"].addOutput( "beauty", IECore.Display( "test", "ieDisplay", "rgba", { "driverType" : "ImageDisplayDriver", "handle" : "myLovelySphere", } ) ) s["o"]["in"].setInput( s["a"]["out"] ) s["r"] = self._createInteractiveRender() s["r"]["in"].setInput( s["o"]["out"] ) s["r"]["state"].setValue( s["r"].State.Running ) time.sleep( 0.5 ) # Visible to start with image = IECore.ImageDisplayDriver.storedImage( "myLovelySphere" ) self.assertAlmostEqual( self.__color4fAtUV( image, IECore.V2f( 0.5 ) ).r, 1, delta = 0.01 ) # Hide visibilityPlug["value"].setValue( False ) time.sleep( 0.5 ) image = IECore.ImageDisplayDriver.storedImage( "myLovelySphere" ) self.assertAlmostEqual( self.__color4fAtUV( image, IECore.V2f( 0.5 ) ).r, 0, delta = 0.01 ) # Show again visibilityPlug["value"].setValue( True ) time.sleep( 0.5 ) image = IECore.ImageDisplayDriver.storedImage( "myLovelySphere" ) self.assertAlmostEqual( self.__color4fAtUV( image, IECore.V2f( 0.5 ) ).r, 1, delta = 0.01 )
def testSerialisation( self ) : s = Gaffer.ScriptNode() s["a"] = GafferScene.CustomAttributes() s["a"]["attributes"].addChild( Gaffer.NameValuePlug( "ri:shadingRate", IECore.FloatData( 1.0 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic) ) s2 = Gaffer.ScriptNode() s2.execute( s.serialise() ) self.assertEqual( len( s2["a"]["attributes"] ), 1 ) self.assertTrue( "attributes1" not in s2["a"] )
def testSerialisation(self): s = Gaffer.ScriptNode() s["a"] = GafferScene.CustomAttributes() s["a"]["attributes"].addMember("ri:shadingRate", IECore.FloatData(1.0)) s2 = Gaffer.ScriptNode() s2.execute(s.serialise()) self.assertEqual(len(s2["a"]["attributes"]), 1) self.assertTrue("attributes1" not in s2["a"])
def __createPhongShader() : phong = GafferScene.SceneProcessor( "Phong" ) phong["attributes"] = GafferScene.CustomAttributes() phong["attributes"]["in"].setInput( phong["in"] ) phong["assignment"] = GafferScene.ShaderAssignment() phong["assignment"]["in"].setInput( phong["attributes"]["out"] ) phong["shader"] = GafferScene.OpenGLShader( "phong" ) phong["shader"]["name"].setValue( "phong" ) phong["shader"]["type"].setValue( "gl:surface" ) phong["shader"]["parameters"].addChild( Gaffer.StringPlug( "glFragmentSource", defaultValue = inspect.cleandoc( ''' in vec3 fragmentN; in vec3 geometryP; in vec3 geometryCs; vec3 ADSLightModel(in vec3 normal, in vec3 pos){ vec3 lightPos = vec3(1.0, 0.5, 0.0); vec3 lightAmbient = vec3(0.3, 0.3, 0.3); vec3 lightDiffuse = vec3(1.0, 1.0, 1.0); vec3 lightSpecular = vec3(1.0, 1.0, 1.0); vec3 materialAmbient = vec3(0.9, 0.9, 0.9); vec3 materialDiffuse = vec3(0.5, 0.5, 0.6); vec3 materialSpecular = vec3(0.6, 0.6, 0.6); float materialShininess = 100.0; vec3 norm = normalize(normal); vec3 lightv = normalize(lightPos - pos); vec3 viewv = normalize(vec3(0.0) - pos); vec3 refl = reflect(vec3(0.0) - lightv, norm); vec3 ambient = materialAmbient * lightAmbient; vec3 diffuse = max(0.0, dot(lightv, norm)) * materialDiffuse * lightDiffuse; vec3 specular = vec3(0.0); if(dot(lightv, viewv) > 0.0) { specular = pow(max(0.0, dot(viewv, refl)), materialShininess)*materialSpecular*lightSpecular; } return clamp(ambient + diffuse + specular, 0.0, 1.0); } void main(){ vec3 colour = ADSLightModel(fragmentN, geometryP); if (geometryCs != vec3(0.0, 0.0, 0.0)){ colour = colour * geometryCs; } gl_FragColor = vec4(colour, 1.0); } ''' ) ) ) phong["shader"]["out"] = Gaffer.Plug() phong["assignment"]["shader"].setInput( phong["shader"]["out"] ) phong["out"].setInput( phong["assignment"]["out"] ) return phong
def testDuplicateRoots(self): sphere = GafferScene.Sphere() sphere["sets"].setValue("${collect:rootName}") sphereFilter = GafferScene.PathFilter() sphereFilter["paths"].setValue(IECore.StringVectorData(["/sphere"])) attributes = GafferScene.CustomAttributes() attributes["in"].setInput(sphere["out"]) attributes["filter"].setInput(sphereFilter["out"]) attributes["attributes"]["test"] = Gaffer.NameValuePlug( "test", "${collect:rootName}") options = GafferScene.CustomOptions() options["in"].setInput(attributes["out"]) options["options"]["test"] = Gaffer.NameValuePlug( "test", "${collect:rootName}") collect = GafferScene.CollectScenes() collect["in"].setInput(options["out"]) # The user might enter the exact same value multiple times by accident. # And because the values represent paths, they may even enter _different_ # values that map to the same path. collect["rootNames"].setValue( IECore.StringVectorData([ "A/B", "/A/B", "/A/B/", "A/B", ])) # We automatically uniquefy the names, using the first string as the # value of `collect:rootName`. self.assertEqual(collect["out"].childNames("/"), IECore.InternedStringVectorData(["A"])) self.assertEqual(collect["out"].childNames("/A"), IECore.InternedStringVectorData(["B"])) self.assertEqual( collect["out"].attributes("/A/B/sphere"), IECore.CompoundObject({"test": IECore.StringData("A/B")})) self.assertEqual(collect["out"].setNames(), IECore.InternedStringVectorData(["A/B"])) self.assertEqual(collect["out"].set("A/B").value, IECore.PathMatcher(["/A/B/sphere"])) self.assertEqual( collect["out"].globals(), IECore.CompoundObject({"option:test": IECore.StringData("A/B")}))
def testGlobalsDirtyPropagation( self ) : options = GafferScene.StandardOptions() attributes = GafferScene.CustomAttributes() attributes["in"].setInput( options["out"] ) attributes["global"].setValue( True ) self.assertEqual( attributes["out"].globals(), IECore.CompoundObject() ) cs = GafferTest.CapturingSlot( attributes.plugDirtiedSignal() ) options["options"]["renderCamera"]["enabled"].setValue( True ) self.assertIn( attributes["out"]["globals"], { x[0] for x in cs } ) self.assertEqual( attributes["out"].globals(), IECore.CompoundObject( { "option:render:camera" : IECore.StringData( "" ) } ) )
def testAffects( self ) : s = Gaffer.ScriptNode() s["a"] = GafferScene.CustomAttributes() p = s["a"]["attributes"].addMember( "user:test", 10 ) self.assertEqual( set( s["a"].affects( p["value"] ) ), set( [ s["a"]["out"]["attributes"] ] ) ) s["a"]["global"].setValue( True ) self.assertEqual( set( s["a"].affects( p["value"] ) ), set( [ s["a"]["out"]["globals"] ] ) ) s["e"] = Gaffer.Expression() s["e"].setExpression( """parent["a"]["global"] = context.getFrame() > 10""" ) self.assertEqual( set( s["a"].affects( p["value"] ) ), set( [ s["a"]["out"]["attributes"], s["a"]["out"]["globals"] ] ) )
def testDisconnectDoesntRetainFilterValue(self): s = Gaffer.ScriptNode() s["p"] = GafferScene.Plane() s["f"] = GafferScene.PathFilter() s["a"] = GafferScene.CustomAttributes() s["a"]["attributes"].addMember("user:test", IECore.IntData(10)) self.assertTrue("user:test" in s["a"]["out"].attributes("/plane")) s["a"]["filter"].setInput(s["f"]["match"]) self.assertFalse("user:test" in s["a"]["out"].attributes("/plane")) s["a"]["filter"].setInput(None) self.assertTrue("user:test" in s["a"]["out"].attributes("/plane"))
def testRootAttributes( self ) : # create node inheriting from SceneNode: node = GafferScene.CustomAttributes() node["attributes"].addChild( Gaffer.NameValuePlug( "user:foobar", True, True ) ) # scene nodes always have passthrough behaviour for attributes at the root, so this particular one should return an empty compound object: context = Gaffer.Context() context.set( "scene:path", IECore.InternedStringVectorData([]) ) with context: self.assertEqual( node["out"]["attributes"].getValue(), IECore.CompoundObject() ) # unless the caching system is misbehaving, it should return the attribute values we asked for at other locations: context.set( "scene:path", IECore.InternedStringVectorData(["yup"]) ) with context: self.assertEqual( node["out"]["attributes"].getValue(), IECore.CompoundObject({'user:foobar':IECore.BoolData( 1 )}) )
def testDisconnectDoesntRetainFilterValue( self ) : s = Gaffer.ScriptNode() s["p"] = GafferScene.Plane() s["f"] = GafferScene.PathFilter() s["a"] = GafferScene.CustomAttributes() s["a"]["attributes"].addChild( Gaffer.NameValuePlug( "user:test", IECore.IntData( 10 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic ) ) self.assertTrue( "user:test" in s["a"]["out"].attributes( "/plane" ) ) s["a"]["filter"].setInput( s["f"]["out"] ) self.assertFalse( "user:test" in s["a"]["out"].attributes( "/plane" ) ) s["a"]["filter"].setInput( None ) self.assertTrue( "user:test" in s["a"]["out"].attributes( "/plane" ) )
def testCompoundDataExpression( self ) : # `testLoadExtraAttributesFrom0_59()` gives us test coverage for loading # serialised expressions which assign CompoundData to `extraAttributes`. # But it's also possible to create such an expression directly via the # API, which is what this test provides coverage for. script = Gaffer.ScriptNode() script["a"] = GafferScene.CustomAttributes() script["e"] = Gaffer.Expression() script["e"].setExpression( 'parent["a"]["extraAttributes"] = IECore.CompoundData( { "test" : 10 } )' ) self.assertEqual( script["a"]["extraAttributes"].getValue(), IECore.CompoundObject( { "test" : IECore.IntData( 10 ) } ) )