def testAttributes(self): s = Gaffer.ScriptNode() s["p"] = GafferScene.Plane() s["p"]["transform"]["translate"].setValue(IECore.V3f(-0.1, -0.1, 0)) s["c"] = GafferScene.Camera() s["c"]["transform"]["translate"]["z"].setValue(1) s["g"] = GafferScene.Group() s["g"]["in"][0].setInput(s["p"]["out"]) s["g"]["in"][1].setInput(s["c"]["out"]) s["s"] = GafferRenderMan.RenderManShader() s["s"].loadShader( self.compileShader(os.path.dirname(__file__) + "/shaders/flat.sl")) s["s"]["parameters"]["c"].setValue(IECore.Color3f(1, 0.5, 0.25)) s["a"] = GafferScene.ShaderAssignment() s["a"]["in"].setInput(s["g"]["out"]) s["a"]["shader"].setInput(s["s"]["out"]) s["d"] = GafferScene.Outputs() s["d"].addOutput( "beauty", IECore.Display( "test", "ieDisplay", "rgba", { "quantize": IECore.FloatVectorData([0, 0, 0, 0]), "driverType": "ImageDisplayDriver", "handle": "myLovelyPlane", })) s["d"]["in"].setInput(s["a"]["out"]) s["o"] = GafferScene.StandardOptions() s["o"]["options"]["renderCamera"]["value"].setValue("/group/camera") s["o"]["options"]["renderCamera"]["enabled"].setValue(True) s["o"]["in"].setInput(s["d"]["out"]) s["r"] = GafferRenderMan.InteractiveRenderManRender() s["r"]["in"].setInput(s["o"]["out"]) # start a render, give it time to finish, and check the output s["r"]["state"].setValue(s["r"].State.Running) time.sleep(2) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertEqual(c, IECore.Color3f(1, 0.5, 0.25)) # adjust a shader parameter, wait, and check that it changed s["s"]["parameters"]["c"].setValue(IECore.Color3f(1, 1, 1)) time.sleep(1) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertEqual(c, IECore.Color3f(1)) # turn off shader updates, do the same, and check that it hasn't changed s["r"]["updateAttributes"].setValue(False) s["s"]["parameters"]["c"].setValue(IECore.Color3f(0.5)) time.sleep(1) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertEqual(c, IECore.Color3f(1)) # turn shader updates back on, and check that it updates s["r"]["updateAttributes"].setValue(True) time.sleep(1) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertEqual(c, IECore.Color3f(0.5))
def __init__(self, name="LDTShaderBall"): GafferScene.SceneNode.__init__(self, name) # Public plugs self["shader"] = GafferScene.ShaderPlug() self["resolution"] = Gaffer.IntPlug( defaultValue=512, minValue=0 ) self["scene"] = Gaffer.IntPlug("scene") Gaffer.Metadata.registerValue( self["scene"], 'nodule:type', '' ) Gaffer.Metadata.registerValue( self["scene"], 'plugValueWidget:type', 'GafferUI.PresetsPlugValueWidget' ) Gaffer.Metadata.registerValue( self["scene"], 'preset:shaderBall', 0 ) Gaffer.Metadata.registerValue( self["scene"], 'preset:customGeo', 1 ) self["custom_geo"] = Gaffer.StringPlug( defaultValue="${LOOKDEVTOOLS}/resources/assets/teapot/teapot.abc" ) # Private internal network # ShaderBall s = Gaffer.ScriptNode() __shaderBallReference = s["__shaderBallReference"] = Gaffer.Reference() __shaderBallReference.load("/run/media/ezequielm/misc/wrk/dev/EZLookdevTools/plugins/gaffer/boxes/LDTShaderBall.grf") self.addChild(__shaderBallReference) # Custom geo self["__teapot"] = GafferScene.SceneReader() self["__teapot"]["fileName"].setInput( self["custom_geo"] ) self["__teapot"]["transform"]["scale"].setValue( imath.V3f( 1, 1, 1 ) ) self["__teapotMeshType"] = GafferScene.MeshType("__teapotMeshType") self["__teapotPathFilter"] = GafferScene.PathFilter("__teapotPathFilter") self["__teapotMeshType"]["filter"].setInput(self["__teapotPathFilter"]["out"]) self["__teapotMeshType"]["meshType"].setValue("catmullClark") self["__teapotPathFilter"]["paths"].setValue(IECore.StringVectorData(["/..."])) self["__teapotMeshType"]["in"].setInput(self["__teapot"]["out"]) self["__teapotSet"] = GafferScene.Set( "SHADERBALL_material" ) self["__teapotSet"]["name"].setValue( 'SHADERBALL:material' ) self["__teapotSet"]["filter"].setInput(self["__teapotPathFilter"]["out"]) self["__teapotSet"]["in"].setInput(self["__teapotMeshType"]["out"]) # Root self["__sceneSwitch"] = Gaffer.Switch() self["__sceneSwitch"].setup(GafferScene.ScenePlug( "in")) self["__sceneSwitch"]["index"].setInput(self["scene"]) self["__sceneSwitch"]["in"].addChild( GafferScene.ScenePlug( "in0", flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic ) ) self["__sceneSwitch"]["in"].addChild( GafferScene.ScenePlug( "in1", flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic ) ) self["__sceneSwitch"]["in"]["in0"].setInput(self["__shaderBallReference"]["out"]) self["__sceneSwitch"]["in"]["in1"].setInput(self["__teapotSet"]["out"]) self["__camera"] = GafferScene.Camera() self["__camera"]["transform"]["translate"].setValue(imath.V3f(0, 70, 175)) self["__camera"]["transform"]["rotate"].setValue(imath.V3f(-16, 0, 0)) self["__camera"]["fieldOfView"].setValue(20.0) self["__group"] = GafferScene.Group() self["__group"]["in"][0].setInput( self["__sceneSwitch"]["out"] ) self["__group"]["in"][1].setInput( self["__camera"]["out"] ) # self["__group"]["in"][2].setInput(self["__plane"]["out"]) self["__subTree"] = GafferScene.SubTree() self["__subTree"]["in"].setInput( self["__group"]["out"] ) self["__subTree"]["root"].setValue("/group") self["__shaderAssignment"] = GafferScene.ShaderAssignment() self["__shaderAssignment"]["in"].setInput( self["__subTree"]["out"] ) self["__shaderAssignment"]["shader"].setInput( self["shader"] ) self["__shaderAssignmentFilter"] = GafferScene.SetFilter( "SetFilter" ) self["__shaderAssignmentFilter"]["setExpression"].setValue( 'SHADERBALL:material' ) self["__shaderAssignment"]["filter"].setInput(self["__shaderAssignmentFilter"]["out"]) self["__options"] = GafferScene.StandardOptions() self["__options"]["in"].setInput( self["__shaderAssignment"]["out"] ) self["__options"]["options"]["renderCamera"][ "enabled" ].setValue(True) self["__options"]["options"]["renderCamera"][ "value" ].setValue("/camera") self["__options"]["options"]["renderResolution"][ "enabled" ].setValue(True) self["__options"]["options"]["renderResolution"][ "value" ][0].setInput(self["resolution"]) self["__options"]["options"]["renderResolution"][ "value" ][1].setInput(self["resolution"]) self["__emptyScene"] = GafferScene.ScenePlug() self["__enabler"] = Gaffer.Switch() self["__enabler"].setup(GafferScene.ScenePlug()) self["__enabler"]["in"][0].setInput( self["__emptyScene"] ) self["__enabler"]["in"][1].setInput( self["__options"]["out"] ) self["__enabler"]["enabled"].setInput( self["enabled"] ) self["__enabler"]["index"].setValue(1) self["out"].setFlags( Gaffer.Plug.Flags.Serialisable, False ) self["out"].setInput(self["__enabler"]["out"])
def testLookThrough(self): script = Gaffer.ScriptNode() script["sphere"] = GafferScene.Sphere() script["camera"] = GafferScene.Camera() script["camera"]["transform"]["translate"].setValue(IECore.V3f( 1, 0, 0)) script["group"] = GafferScene.Group() script["group"]["in"][0].setInput(script["sphere"]["out"]) script["group"]["in"][1].setInput(script["camera"]["out"]) with GafferUI.Window() as window: viewer = GafferUI.Viewer(script) window.setVisible(True) viewer.setNodeSet(Gaffer.StandardSet([script["group"]])) view = viewer.view() self.assertTrue(isinstance(view, GafferSceneUI.SceneView)) def setViewCameraTransform(matrix): camera = view.viewportGadget().getCamera() camera.getTransform().matrix = matrix view.viewportGadget().setCamera(camera) def getViewCameraTransform(): return view.viewportGadget().getCamera().getTransform().transform() # Simulate the user translating the camera. setViewCameraTransform( IECore.M44f.createTranslated(IECore.V3f(100, 0, 0))) self.assertEqual(getViewCameraTransform(), IECore.M44f.createTranslated(IECore.V3f(100, 0, 0))) # Set the path for the look-through camera, but don't activate it - nothing should have changed. view["lookThrough"]["camera"].setValue("/group/camera") self.assertEqual(getViewCameraTransform(), IECore.M44f.createTranslated(IECore.V3f(100, 0, 0))) # Enable the look-through - the camera should update. view["lookThrough"]["enabled"].setValue(True) self.waitForIdle() self.assertEqual(getViewCameraTransform(), script["group"]["out"].transform("/group/camera")) # Disable the look-through - the camera should revert to its previous position. view["lookThrough"]["enabled"].setValue(False) self.waitForIdle() self.assertEqual(getViewCameraTransform(), IECore.M44f.createTranslated(IECore.V3f(100, 0, 0))) # Simulate the user moving the viewport camera, and then move the (now disabled) look-through # camera. The user movement should win out. setViewCameraTransform( IECore.M44f.createTranslated(IECore.V3f(200, 0, 0))) self.assertEqual(getViewCameraTransform(), IECore.M44f.createTranslated(IECore.V3f(200, 0, 0))) script["camera"]["transform"]["translate"].setValue(IECore.V3f( 2, 0, 0)) self.waitForIdle() self.assertEqual(getViewCameraTransform(), IECore.M44f.createTranslated(IECore.V3f(200, 0, 0))) # Change the viewer context - since look-through is disabled the user camera should not move. viewer.getContext().setFrame(10) self.waitForIdle() self.assertEqual(getViewCameraTransform(), IECore.M44f.createTranslated(IECore.V3f(200, 0, 0))) # Work around "Internal C++ object (PySide.QtGui.QWidget) already deleted" error. In an # ideal world we'll fix this, but it's unrelated to what we're testing here. window.removeChild(viewer)
def testSelection( self ) : script = Gaffer.ScriptNode() script["plane"] = GafferScene.Plane() script["group"] = GafferScene.Group() script["group"]["in"][0].setInput( script["plane"]["out"] ) script["transformFilter"] = GafferScene.PathFilter() script["transform"] = GafferScene.Transform() script["transform"]["in"].setInput( script["group"]["out"] ) script["transform"]["filter"].setInput( script["transformFilter"]["out"] ) view = GafferSceneUI.SceneView() view["in"].setInput( script["transform"]["out"] ) tool = GafferSceneUI.TranslateTool( view ) tool["active"].setValue( True ) self.assertEqual( len( tool.selection() ), 0 ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/group/plane" ] ) ) self.assertEqual( len( tool.selection() ), 1 ) self.assertEqual( tool.selection()[0].path(), "/group/plane" ) self.assertEqual( tool.selection()[0].context(), view.getContext() ) self.assertTrue( tool.selection()[0].upstreamScene().isSame( script["plane"]["out"] ) ) self.assertEqual( tool.selection()[0].upstreamPath(), "/plane" ) self.assertTrue( tool.selection()[0].editTarget().isSame( script["plane"]["transform"] ) ) self.assertEqual( tool.selection()[0].transformSpace(), imath.M44f() ) self.assertEqual( tool.selection()[0].warning(), "" ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/group" ] ) ) self.assertEqual( tool.selection()[0].path(), "/group" ) self.assertEqual( tool.selection()[0].context(), view.getContext() ) self.assertTrue( tool.selection()[0].upstreamScene().isSame( script["group"]["out"] ) ) self.assertEqual( tool.selection()[0].upstreamPath(), "/group" ) self.assertTrue( tool.selection()[0].editTarget().isSame( script["group"]["transform"] ) ) self.assertEqual( tool.selection()[0].transformSpace(), imath.M44f() ) self.assertEqual( tool.selection()[0].warning(), "" ) script["transformFilter"]["paths"].setValue( IECore.StringVectorData( [ "/group" ] ) ) self.assertTrue( tool.selection()[0].editTarget().isSame( script["transform"]["transform"] ) ) self.assertEqual( tool.selection()[0].warning(), "" ) script["transformFilter"]["enabled"].setValue( False ) self.assertTrue( tool.selection()[0].editTarget().isSame( script["group"]["transform"] ) ) self.assertEqual( tool.selection()[0].warning(), "" ) script["transformFilter"]["enabled"].setValue( True ) self.assertEqual( tool.selection()[0].path(), "/group" ) self.assertEqual( tool.selection()[0].context(), view.getContext() ) self.assertTrue( tool.selection()[0].upstreamScene().isSame( script["transform"]["out"] ) ) self.assertEqual( tool.selection()[0].upstreamPath(), "/group" ) self.assertTrue( tool.selection()[0].editTarget().isSame( script["transform"]["transform"] ) ) self.assertEqual( tool.selection()[0].transformSpace(), imath.M44f() ) self.assertEqual( tool.selection()[0].warning(), "" ) script["transform"]["enabled"].setValue( False ) self.assertTrue( tool.selection()[0].editTarget().isSame( script["group"]["transform"] ) ) self.assertEqual( tool.selection()[0].warning(), "" )
def testTransformMotion(self): s = Gaffer.ScriptNode() s["plane"] = GafferScene.Plane() s["sphere"] = GafferScene.Sphere() s["group"] = GafferScene.Group() s["group"]["in"][0].setInput(s["plane"]["out"]) s["group"]["in"][1].setInput(s["sphere"]["out"]) s["expression"] = Gaffer.Expression() s["expression"].setExpression( inspect.cleandoc(""" parent["plane"]["transform"]["translate"]["x"] = context.getFrame() parent["sphere"]["transform"]["translate"]["y"] = context.getFrame() * 2 parent["group"]["transform"]["translate"]["z"] = context.getFrame() - 1 """)) s["planeFilter"] = GafferScene.PathFilter() s["planeFilter"]["paths"].setValue( IECore.StringVectorData(["/group/plane"])) s["attributes"] = GafferScene.StandardAttributes() s["attributes"]["in"].setInput(s["group"]["out"]) s["attributes"]["filter"].setInput(s["planeFilter"]["out"]) s["attributes"]["attributes"]["transformBlur"]["enabled"].setValue( True) s["attributes"]["attributes"]["transformBlur"]["value"].setValue(False) s["options"] = GafferScene.StandardOptions() s["options"]["in"].setInput(s["attributes"]["out"]) s["options"]["options"]["shutter"]["enabled"].setValue(True) s["options"]["options"]["transformBlur"]["enabled"].setValue(True) s["render"] = GafferArnold.ArnoldRender() s["render"]["in"].setInput(s["options"]["out"]) s["render"]["mode"].setValue(s["render"].Mode.SceneDescriptionMode) s["render"]["fileName"].setValue(self.temporaryDirectory() + "/test.ass") # No motion blur s["options"]["options"]["transformBlur"]["value"].setValue(False) s["render"]["task"].execute() with IECoreArnold.UniverseBlock(writable=True): arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass") camera = arnold.AiNodeLookUpByName("gaffer:defaultCamera") sphere = arnold.AiNodeLookUpByName("/group/sphere") sphereMotionStart = arnold.AiNodeGetFlt(sphere, "motion_start") sphereMotionEnd = arnold.AiNodeGetFlt(sphere, "motion_end") sphereMatrix = arnold.AiNodeGetMatrix(sphere, "matrix") plane = arnold.AiNodeLookUpByName("/group/plane") planeMotionStart = arnold.AiNodeGetFlt(plane, "motion_start") planeMotionEnd = arnold.AiNodeGetFlt(plane, "motion_end") planeMatrix = arnold.AiNodeGetMatrix(plane, "matrix") # Motion parameters should be left at default self.assertEqual(sphereMotionStart, 0) self.assertEqual(sphereMotionEnd, 1) self.assertEqual(planeMotionStart, 0) self.assertEqual(planeMotionEnd, 1) expectedSphereMatrix = arnold.AiM4Translation( arnold.AtVector(0, 2, 0)) expectedPlaneMatrix = arnold.AiM4Translation( arnold.AtVector(1, 0, 0)) self.assertEqual(self.__m44f(sphereMatrix), self.__m44f(expectedSphereMatrix)) self.assertEqual(self.__m44f(planeMatrix), self.__m44f(expectedPlaneMatrix)) self.assertEqual(arnold.AiNodeGetFlt(camera, "shutter_start"), 1) self.assertEqual(arnold.AiNodeGetFlt(camera, "shutter_end"), 1) # Motion blur s["options"]["options"]["transformBlur"]["value"].setValue(True) s["render"]["task"].execute() with IECoreArnold.UniverseBlock(writable=True): arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass") camera = arnold.AiNodeLookUpByName("gaffer:defaultCamera") sphere = arnold.AiNodeLookUpByName("/group/sphere") sphereMotionStart = arnold.AiNodeGetFlt(sphere, "motion_start") sphereMotionEnd = arnold.AiNodeGetFlt(sphere, "motion_end") sphereMatrices = arnold.AiNodeGetArray(sphere, "matrix") plane = arnold.AiNodeLookUpByName("/group/plane") planeMotionStart = arnold.AiNodeGetFlt(plane, "motion_start") planeMotionEnd = arnold.AiNodeGetFlt(plane, "motion_end") planeMatrices = arnold.AiNodeGetArray(plane, "matrix") self.assertEqual(sphereMotionStart, 0.75) self.assertEqual(sphereMotionEnd, 1.25) self.assertEqual( arnold.AiArrayGetNumElements(sphereMatrices.contents), 1) self.assertEqual(arnold.AiArrayGetNumKeys(sphereMatrices.contents), 2) self.assertEqual(planeMotionStart, 0.75) self.assertEqual(planeMotionEnd, 1.25) self.assertEqual( arnold.AiArrayGetNumElements(planeMatrices.contents), 1) self.assertEqual(arnold.AiArrayGetNumKeys(planeMatrices.contents), 2) for i in range(0, 2): frame = 0.75 + 0.5 * i sphereMatrix = arnold.AiArrayGetMtx(sphereMatrices, i) expectedSphereMatrix = arnold.AiM4Translation( arnold.AtVector(0, frame * 2, frame - 1)) planeMatrix = arnold.AiArrayGetMtx(planeMatrices, i) expectedPlaneMatrix = arnold.AiM4Translation( arnold.AtVector(1, 0, frame - 1)) self.assertEqual(self.__m44f(sphereMatrix), self.__m44f(expectedSphereMatrix)) self.assertEqual(self.__m44f(planeMatrix), self.__m44f(expectedPlaneMatrix)) self.assertEqual(arnold.AiNodeGetFlt(camera, "shutter_start"), 0.75) self.assertEqual(arnold.AiNodeGetFlt(camera, "shutter_end"), 1.25) # Motion blur on, but sampleMotion off s["options"]["options"]["sampleMotion"]["enabled"].setValue(True) s["options"]["options"]["sampleMotion"]["value"].setValue(False) s["render"]["task"].execute() with IECoreArnold.UniverseBlock(writable=True): arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass") camera = arnold.AiNodeLookUpByName("gaffer:defaultCamera") sphere = arnold.AiNodeLookUpByName("/group/sphere") sphereMotionStart = arnold.AiNodeGetFlt(sphere, "motion_start") sphereMotionEnd = arnold.AiNodeGetFlt(sphere, "motion_end") sphereMatrices = arnold.AiNodeGetArray(sphere, "matrix") plane = arnold.AiNodeLookUpByName("/group/plane") planeMotionStart = arnold.AiNodeGetFlt(plane, "motion_start") planeMotionEnd = arnold.AiNodeGetFlt(plane, "motion_end") planeMatrices = arnold.AiNodeGetArray(plane, "matrix") self.assertEqual(sphereMotionStart, 0.75) self.assertEqual(sphereMotionEnd, 1.25) self.assertEqual( arnold.AiArrayGetNumElements(sphereMatrices.contents), 1) self.assertEqual(arnold.AiArrayGetNumKeys(sphereMatrices.contents), 2) self.assertEqual(planeMotionStart, 0.75) self.assertEqual(planeMotionEnd, 1.25) self.assertEqual( arnold.AiArrayGetNumElements(planeMatrices.contents), 1) self.assertEqual(arnold.AiArrayGetNumKeys(planeMatrices.contents), 2) for i in range(0, 2): frame = 0.75 + 0.5 * i sphereMatrix = arnold.AiArrayGetMtx(sphereMatrices, i) expectedSphereMatrix = arnold.AiM4Translation( arnold.AtVector(0, frame * 2, frame - 1)) planeMatrix = arnold.AiArrayGetMtx(planeMatrices, i) expectedPlaneMatrix = arnold.AiM4Translation( arnold.AtVector(1, 0, frame - 1)) self.assertEqual(self.__m44f(sphereMatrix), self.__m44f(expectedSphereMatrix)) self.assertEqual(self.__m44f(planeMatrix), self.__m44f(expectedPlaneMatrix)) self.assertEqual(arnold.AiNodeGetFlt(camera, "shutter_start"), 0.75) self.assertEqual(arnold.AiNodeGetFlt(camera, "shutter_end"), 0.75)
def testInAndContaining(self): # /group # /sphere # /group # /sphere # /sphere1 # /sphere sphere = GafferScene.Sphere() sphere["sets"].setValue("indubitablyASet containingThings") group = GafferScene.Group() group["in"][0].setInput(sphere["out"]) group["in"][0].setInput(sphere["out"]) group2 = GafferScene.Group() group2["in"][0].setInput(sphere["out"]) group2["in"][1].setInput(group["out"]) parent = GafferScene.Parent() parent["in"].setInput(group2["out"]) parent["child"].setInput(sphere["out"]) setA = GafferScene.Set() setA["in"].setInput(parent["out"]) setA["name"].setValue("A") setA["paths"].setValue(IECore.StringVectorData([ "/group/group", ])) setB = GafferScene.Set() setB["in"].setInput(setA["out"]) setB["name"].setValue("B") setB["paths"].setValue( IECore.StringVectorData([ "/group/group/sphere", "/group/sphere", ])) self.assertSceneValid(setB["out"]) # Test basic operation of `in` self.assertCorrectEvaluation(setB["out"], "A in B", []) self.assertCorrectEvaluation(setB["out"], "A in A", setA["paths"].getValue()) self.assertCorrectEvaluation(setB["out"], "B in A", ["/group/group/sphere"]) self.assertCorrectEvaluation(setB["out"], "B in B", setB["paths"].getValue()) self.assertCorrectEvaluation(setB["out"], "/group/group/sphere in /group", ["/group/group/sphere"]) self.assertCorrectEvaluation(setB["out"], "B in /group/group", ["/group/group/sphere"]) self.assertCorrectEvaluation(setB["out"], "B in ( /group/group /somewhereElse )", ["/group/group/sphere"]) # Test basic operation of `containing` self.assertCorrectEvaluation(setB["out"], "A containing B", ["/group/group"]) self.assertCorrectEvaluation(setB["out"], "A containing A", setA["paths"].getValue()) self.assertCorrectEvaluation(setB["out"], "B containing A", []) self.assertCorrectEvaluation(setB["out"], "B containing B", setB["paths"].getValue()) self.assertCorrectEvaluation(setB["out"], "/group containing /group/sphere", ["/group"]) self.assertCorrectEvaluation(setB["out"], "A containing /group/group/sphere", ["/group/group"]) # Test various problematic parses self.assertCorrectEvaluation(setB["out"], "A in (A)", setA["paths"].getValue()) self.assertCorrectEvaluation(setB["out"], "A in(A)", setA["paths"].getValue()) self.assertCorrectEvaluation(setB["out"], "(A)in(A)", setA["paths"].getValue()) self.assertCorrectEvaluation( setB["out"], "indubitablyASet", setB["out"].set("indubitablyASet").value.paths()) self.assertCorrectEvaluation(setB["out"], "A in indubitablyASet", []) self.assertCorrectEvaluation(setB["out"], "B in indubitablyASet", setB["paths"].getValue()) self.assertCorrectEvaluation(setB["out"], "A in in?*", []) self.assertCorrectEvaluation( setB["out"], "containingThings", setB["out"].set("containingThings").value.paths()) self.assertCorrectEvaluation(setB["out"], "B in containing*", setB["paths"].getValue())
def test( self ) : # - groupA # - groupB # - sphere # - cube # - sphere sphere = GafferScene.Sphere() sphere["sets"].setValue( "sphereSet" ) cube = GafferScene.Cube() cube["sets"].setValue( "cubeSet" ) groupB = GafferScene.Group() groupB["in"][0].setInput( sphere["out"] ) groupB["in"][1].setInput( sphere["out"] ) groupB["name"].setValue( "groupB" ) groupA = GafferScene.Group() groupA["in"][0].setInput( groupB["out"] ) groupA["in"][1].setInput( sphere["out"] ) groupA["name"].setValue( "groupA" ) # When there is no filter attached, the node # should be an exact pass-through. encapsulate = GafferScene.Encapsulate() encapsulate["in"].setInput( groupA["out"] ) self.assertSceneHashesEqual( encapsulate["out"], groupA["out"], checks = self.allSceneChecks - { "sets" } ) self.assertScenesEqual( encapsulate["out"], groupA["out"] ) # The same goes if there is a filter but it # doesn't match anything. pathFilter = GafferScene.PathFilter() encapsulate["filter"].setInput( pathFilter["out"] ) self.assertSceneHashesEqual( encapsulate["out"], groupA["out"], checks = self.allSceneChecks - { "sets" } ) self.assertScenesEqual( encapsulate["out"], groupA["out"] ) # Even when the filter does match something, the # unmatched paths should be unaffected, and the # globals and set names should be unchanged. pathFilter["paths"].setValue( IECore.StringVectorData( [ "/groupA/groupB" ] ) ) for path in [ "/", "/groupA", "/groupA/sphere" ] : self.assertPathHashesEqual( groupA["out"], path, encapsulate["out"], path ) self.assertPathsEqual( groupA["out"], path, encapsulate["out"], path ) for plugName in [ "globals", "setNames" ] : self.assertEqual( groupA["out"][plugName].hash(), encapsulate["out"][plugName].hash() ) self.assertEqual( groupA["out"][plugName].getValue(), encapsulate["out"][plugName].getValue() ) # And even for matched paths, the attributes, transform # and bound should be passed through unchanged. self.assertEqual( groupA["out"].attributesHash( "/groupA/groupB" ), encapsulate["out"].attributesHash( "/groupA/groupB" ) ) self.assertEqual( groupA["out"].attributes( "/groupA/groupB" ), encapsulate["out"].attributes( "/groupA/groupB" ) ) self.assertEqual( groupA["out"].transformHash( "/groupA/groupB" ), encapsulate["out"].transformHash( "/groupA/groupB" ) ) self.assertEqual( groupA["out"].transform( "/groupA/groupB" ), encapsulate["out"].transform( "/groupA/groupB" ) ) self.assertEqual( groupA["out"].boundHash( "/groupA/groupB" ), encapsulate["out"].boundHash( "/groupA/groupB" ) ) self.assertEqual( groupA["out"].bound( "/groupA/groupB" ), encapsulate["out"].bound( "/groupA/groupB" ) ) # But the children should all have been pruned away # and replaced by an appropriate Capsule. self.assertEqual( encapsulate["out"].childNames( "/groupA/groupB" ), IECore.InternedStringVectorData() ) capsule = encapsulate["out"].object( "/groupA/groupB" ) self.assertIsInstance( capsule, GafferScene.Capsule ) self.assertEqual( capsule.scene(), groupA["out"] ) self.assertEqual( capsule.root(), "/groupA/groupB" ) self.assertEqual( capsule.bound(), groupA["out"].bound( "/groupA/groupB" ) ) # And the sets should also have been pruned so they # don't include the objects beneath the capsule. self.assertEqual( encapsulate["out"].set( "sphereSet" ).value.paths(), [ "/groupA/sphere" ] ) self.assertEqual( encapsulate["out"].set( "cubeSet" ).value.paths(), [] )
def testMoveCoordinateSystem(self): shader = self.compileShader( os.path.dirname(__file__) + "/shaders/coordSysDot.sl") s = Gaffer.ScriptNode() s["plane"] = GafferScene.Plane() s["shader"] = GafferRenderMan.RenderManShader() s["shader"].loadShader(shader) s["shader"]["parameters"]["coordSys"].setValue( "/group/coordinateSystem") s["shaderAssignment"] = GafferScene.ShaderAssignment() s["shaderAssignment"]["in"].setInput(s["plane"]["out"]) s["shaderAssignment"]["shader"].setInput(s["shader"]["out"]) s["camera"] = GafferScene.Camera() s["camera"]["transform"]["translate"]["z"].setValue(1) s["coordSys"] = GafferScene.CoordinateSystem() s["g"] = GafferScene.Group() s["g"]["in"][0].setInput(s["shaderAssignment"]["out"]) s["g"]["in"][1].setInput(s["camera"]["out"]) s["g"]["in"][2].setInput(s["coordSys"]["out"]) s["d"] = GafferScene.Outputs() s["d"].addOutput( "beauty", IECore.Display( "test", "ieDisplay", "rgba", { "quantize": IECore.FloatVectorData([0, 0, 0, 0]), "driverType": "ImageDisplayDriver", "handle": "myLovelyPlane", })) s["d"]["in"].setInput(s["g"]["out"]) s["o"] = GafferScene.StandardOptions() s["o"]["options"]["renderCamera"]["value"].setValue("/group/camera") s["o"]["options"]["renderCamera"]["enabled"].setValue(True) s["o"]["in"].setInput(s["d"]["out"]) s["r"] = GafferRenderMan.InteractiveRenderManRender() s["r"]["in"].setInput(s["o"]["out"]) # start a render, give it time to finish, and check the output s["r"]["state"].setValue(s["r"].State.Running) time.sleep(2) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertAlmostEqual(c[1], 1, delta=0.001) # move the coordinate system, and check the output s["coordSys"]["transform"]["translate"]["x"].setValue(0.1) time.sleep(2) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.6, 0.5), ) self.assertAlmostEqual(c[0], 1) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.6, 0.7), ) self.assertAlmostEqual(c[0], 0) # scale the coordinate system to cover everything, and check again s["coordSys"]["transform"]["scale"].setValue(IECore.V3f(100)) time.sleep(2) for p in [ IECore.V2f(0.5), IECore.V2f(0.15), IECore.V2f(0.85), ]: c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), p, ) self.assertAlmostEqual(c[0], 1, delta=0.001)
def __init__( self, name = "__CameraSetup" ) : GafferScene.FilteredSceneProcessor.__init__( self, name ) # Public plugs self["cameraGroup"] = Gaffer.StringPlug( "cameraGroup", Gaffer.Plug.Direction.In, "__TEXTUREBAKE_CAMERAS" ) self["bakeDirectory"] = Gaffer.StringPlug( "bakeDirectory", Gaffer.Plug.Direction.In, "" ) self["defaultFileName"] = Gaffer.StringPlug( "defaultFileName", Gaffer.Plug.Direction.In, "${bakeDirectory}/<AOV>/<AOV>.<UDIM>.exr" ) self["defaultResolution"] = Gaffer.IntPlug( "defaultResolution", Gaffer.Plug.Direction.In, 512 ) self["uvSet"] = Gaffer.StringPlug( "uvSet", Gaffer.Plug.Direction.In, "uv" ) self["normalOffset"] = Gaffer.FloatPlug( "normalOffset", Gaffer.Plug.Direction.In, 0.1 ) self["aovs"] = Gaffer.StringPlug( "aovs", Gaffer.Plug.Direction.In, "beauty:rgba" ) self["tasks"] = Gaffer.IntPlug( "tasks", Gaffer.Plug.Direction.In, 1 ) self["taskIndex"] = Gaffer.IntPlug( "taskIndex", Gaffer.Plug.Direction.In, 0 ) # Output self["renderFileList"] = Gaffer.StringVectorDataPlug( "renderFileList", Gaffer.Plug.Direction.Out, defaultValue = IECore.StringVectorData() ) self["renderFileList"].setFlags( Gaffer.Plug.Flags.Serialisable, False ) # Private internal network self["__udimQuery"] = GafferScene.UDIMQuery() self["__udimQuery"]["in"].setInput( self["in"] ) self["__udimQuery"]["uvSet"].setInput( self["uvSet"] ) self["__udimQuery"]["attributes"].setValue( "bake:resolution bake:fileName" ) self["__udimQuery"]["filter"].setInput( self["filter"] ) self["__chunkedBakeInfo"] = Gaffer.CompoundObjectPlug( "__chunkedBakeInfo", Gaffer.Plug.Direction.In, IECore.CompoundObject() ) self["__chunkedBakeInfo"].setFlags( Gaffer.Plug.Flags.Serialisable, False ) self["__chunkExpression"] = Gaffer.Expression() self["__chunkExpression"].setExpression( inspect.cleandoc( """ # Locate the next point in the list of files to bake where we can split the list into chunks without # seperating two files that need to get combined into the same texture def nextChunkBreak( i, l ): while i > 0 and i < len( l ) and ( l[i - 1].get("udim") == l[i].get("udim") and l[i - 1].get("fileName") == l[i].get("fileName") ): i += 1 return i rawInfo = parent["__udimQuery"]["out"] defaultFileName = parent["defaultFileName"] defaultResolution = parent["defaultResolution"] listInfo = [] for udim, meshes in rawInfo.items(): for mesh, extraAttributes in meshes.items(): resolution = defaultResolution if "bake:resolution" in extraAttributes: resolution = extraAttributes["bake:resolution"].value fileName = defaultFileName if "bake:fileName" in extraAttributes: fileName = extraAttributes["bake:fileName"].value listInfo.append( { "udim" : int( udim ), "mesh" : mesh, "resolution" : resolution, "fileName" : fileName } ) listInfo.sort( key = lambda i: (i["fileName"], i["udim"] ) ) info = IECore.CompoundObject() numTasks = parent["tasks"] taskIndex = parent["taskIndex"] chunkStart = nextChunkBreak( ( taskIndex * len( listInfo ) ) / numTasks, listInfo ) chunkEnd = nextChunkBreak( ( ( taskIndex + 1 ) * len( listInfo ) ) / numTasks, listInfo ) dupeCount = 0 prevFileName = "" for i in listInfo[chunkStart:chunkEnd]: o = IECore.CompoundObject() o["mesh"] = IECore.StringData( i["mesh"] ) o["udim"] = IECore.IntData( i["udim"] ) o["resolution"] = IECore.IntData( i["resolution"] ) udimStr = str( i["udim"] ) fileName = i["fileName"].replace( "<UDIM>", udimStr ) if fileName == prevFileName: dupeCount += 1 fileName = fileName + ".layer" + str( dupeCount ) else: prevFileName = fileName dupeCount = 0 o["fileName"] = IECore.StringData( fileName ) name = o["mesh"].value.replace( "/", "_" ) + "." + udimStr info[ name ] = o parent["__chunkedBakeInfo"] = info fileList = [] for name, i in info.items(): fileName = i["fileName"].value for nameAndAov in parent["aovs"].strip( " " ).split( " " ): fileList.append( i["fileName"].value.replace( "<AOV>", nameAndAov.split(":")[0] ) ) parent["renderFileList"] = IECore.StringVectorData( fileList ) """ ), "python" ) self["__parent"] = GafferScene.Parent() self["__parent"]["parent"].setValue( "/" ) for c in ['bound', 'transform', 'attributes', 'object', 'childNames', 'setNames', 'set']: self["__parent"]["in"][c].setInput( self["in"][c] ) self["__outputExpression"] = Gaffer.Expression() self["__outputExpression"].setExpression( inspect.cleandoc( """ import IECoreScene # Transfer all input globals except for outputs inGlobals = parent["in"]["globals"] outGlobals = IECore.CompoundObject() for key, value in inGlobals.items(): if not key.startswith( "output:" ): outGlobals[key] = value # Make our own outputs info = parent["__chunkedBakeInfo"] for cameraName, i in info.items(): params = IECore.CompoundData() fileName = i["fileName"].value params["camera"] = IECore.StringData( "/" + parent["cameraGroup"] + "/" + cameraName ) for nameAndAov in parent["aovs"].strip( " " ).split( " " ): tokens = nameAndAov.split( ":" ) if len( tokens ) != 2: raise RuntimeError( "Invalid bake aov specification: %s It should contain a : between name and data." ) ( aovName, aov ) = tokens aovFileName = fileName.replace( "<AOV>", aovName ) outGlobals["output:" + cameraName + "." + aov] = IECoreScene.Output( aovFileName, "exr", aov + " RGBA", params ) parent["__parent"]["in"]["globals"] = outGlobals """ ), "python" ) self["__camera"] = GafferScene.Camera() self["__camera"]["projection"].setValue( "orthographic" ) self["__cameraTweaks"] = GafferScene.CameraTweaks() self["__cameraTweaks"]["in"].setInput( self["__camera"]["out"] ) self["__cameraTweaks"]["tweaks"]["projection"] = GafferScene.TweakPlug( "projection", "uv_camera" ) self["__cameraTweaks"]["tweaks"]["resolution"] = GafferScene.TweakPlug( "resolution", imath.V2i( 0 ) ) self["__cameraTweaks"]["tweaks"]["u_offset"] = GafferScene.TweakPlug( "u_offset", 0.0 ) self["__cameraTweaks"]["tweaks"]["v_offset"] = GafferScene.TweakPlug( "v_offset", 0.0 ) self["__cameraTweaks"]["tweaks"]["mesh"] = GafferScene.TweakPlug( "mesh", "" ) self["__cameraTweaks"]["tweaks"]["uv_set"] = GafferScene.TweakPlug( "uv_set", "" ) self["__cameraTweaks"]["tweaks"]["extend_edges"] = GafferScene.TweakPlug( "extend_edges", False ) self["__cameraTweaks"]["tweaks"]["offset"] = GafferScene.TweakPlug( "offset", 0.1 ) self["__cameraTweaks"]["tweaks"]["offset"]["value"].setInput( self["normalOffset"] ) self["__cameraTweaksFilter"] = GafferScene.PathFilter() self["__cameraTweaksFilter"]["paths"].setValue( IECore.StringVectorData( [ '/camera' ] ) ) self["__cameraTweaks"]["filter"].setInput( self["__cameraTweaksFilter"]["out"] ) self["__collectScenes"] = GafferScene.CollectScenes() self["__collectScenes"]["sourceRoot"].setValue( "/camera" ) self["__collectScenes"]["rootNameVariable"].setValue( "collect:cameraName" ) self["__collectScenes"]["in"].setInput( self["__cameraTweaks"]["out"] ) self["__group"] = GafferScene.Group() self["__group"]["in"][0].setInput( self["__collectScenes"]["out"] ) self["__group"]["name"].setInput( self["cameraGroup"] ) self["__parent"]["child"].setInput( self["__group"]["out"] ) self["__collectSceneRootsExpression"] = Gaffer.Expression() self["__collectSceneRootsExpression"].setExpression( inspect.cleandoc( """ info = parent["__chunkedBakeInfo"] parent["__collectScenes"]["rootNames"] = IECore.StringVectorData( info.keys() ) """ ), "python" ) self["__cameraSetupExpression"] = Gaffer.Expression() self["__cameraSetupExpression"].setExpression( inspect.cleandoc( """ cameraName = context["collect:cameraName"] info = parent["__chunkedBakeInfo"] i = info[cameraName] udimOffset = i["udim"].value - 1001 parent["__cameraTweaks"]["tweaks"]["resolution"]["value"] = imath.V2i( i["resolution"].value ) parent["__cameraTweaks"]["tweaks"]["u_offset"]["value"] = -( udimOffset % 10 ) parent["__cameraTweaks"]["tweaks"]["v_offset"]["value"] = -( udimOffset / 10 ) parent["__cameraTweaks"]["tweaks"]["mesh"]["value"] = i["mesh"].value parent["__cameraTweaks"]["tweaks"]["uv_set"]["value"] = parent["uvSet"] if parent["uvSet"] != "uv" else "" """ ), "python" ) self["out"].setFlags( Gaffer.Plug.Flags.Serialisable, False ) self["out"].setInput( self["__parent"]["out"] )
def testLights(self): s = Gaffer.ScriptNode() s["l"] = GafferRenderMan.RenderManLight() s["l"].loadShader("pointlight") s["l"]["parameters"]["lightcolor"].setValue( IECore.Color3f(1, 0.5, 0.25)) s["l"]["transform"]["translate"]["z"].setValue(1) s["p"] = GafferScene.Plane() s["c"] = GafferScene.Camera() s["c"]["transform"]["translate"]["z"].setValue(1) s["g"] = GafferScene.Group() s["g"]["in"][0].setInput(s["l"]["out"]) s["g"]["in"][1].setInput(s["p"]["out"]) s["g"]["in"][2].setInput(s["c"]["out"]) s["s"] = GafferRenderMan.RenderManShader() s["s"].loadShader("matte") s["a"] = GafferScene.ShaderAssignment() s["a"]["in"].setInput(s["g"]["out"]) s["a"]["shader"].setInput(s["s"]["out"]) s["d"] = GafferScene.Outputs() s["d"].addOutput( "beauty", IECore.Display( "test", "ieDisplay", "rgba", { "quantize": IECore.FloatVectorData([0, 0, 0, 0]), "driverType": "ImageDisplayDriver", "handle": "myLovelyPlane", })) s["d"]["in"].setInput(s["a"]["out"]) s["o"] = GafferScene.StandardOptions() s["o"]["options"]["renderCamera"]["value"].setValue("/group/camera") s["o"]["options"]["renderCamera"]["enabled"].setValue(True) s["o"]["in"].setInput(s["d"]["out"]) s["r"] = GafferRenderMan.InteractiveRenderManRender() s["r"]["in"].setInput(s["o"]["out"]) # start a render, give it time to finish, and check the output s["r"]["state"].setValue(s["r"].State.Running) time.sleep(2) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertEqual(c / c[0], IECore.Color3f(1, 0.5, 0.25)) # adjust a parameter, give it time to update, and check the output s["l"]["parameters"]["lightcolor"].setValue( IECore.Color3f(0.25, 0.5, 1)) time.sleep(1) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertEqual(c / c[2], IECore.Color3f(0.25, 0.5, 1)) # pause it, adjust a parameter, wait, and check that nothing changed s["r"]["state"].setValue(s["r"].State.Paused) s["l"]["parameters"]["lightcolor"].setValue( IECore.Color3f(1, 0.5, 0.25)) time.sleep(1) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertEqual(c / c[2], IECore.Color3f(0.25, 0.5, 1)) # unpause it, wait, and check that the update happened s["r"]["state"].setValue(s["r"].State.Running) time.sleep(1) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertEqual(c / c[0], IECore.Color3f(1, 0.5, 0.25)) # turn off light updates, adjust a parameter, wait, and check nothing happened s["r"]["updateLights"].setValue(False) s["l"]["parameters"]["lightcolor"].setValue( IECore.Color3f(0.25, 0.5, 1)) time.sleep(1) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertEqual(c / c[0], IECore.Color3f(1, 0.5, 0.25)) # turn light updates back on and check that it updates s["r"]["updateLights"].setValue(True) time.sleep(1) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertEqual(c / c[2], IECore.Color3f(0.25, 0.5, 1)) # stop the render, tweak a parameter and check that nothing happened s["r"]["state"].setValue(s["r"].State.Stopped) s["l"]["parameters"]["lightcolor"].setValue( IECore.Color3f(1, 0.5, 0.25)) time.sleep(1) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertEqual(c / c[2], IECore.Color3f(0.25, 0.5, 1))
def testMoveCamera(self): s = Gaffer.ScriptNode() s["p"] = GafferScene.Plane() s["c"] = GafferScene.Camera() s["c"]["transform"]["translate"]["z"].setValue(1) s["g"] = GafferScene.Group() s["g"]["in"][0].setInput(s["p"]["out"]) s["g"]["in"][1].setInput(s["c"]["out"]) s["d"] = GafferScene.Outputs() s["d"].addOutput( "beauty", IECore.Display( "test", "ieDisplay", "rgba", { "quantize": IECore.FloatVectorData([0, 0, 0, 0]), "driverType": "ImageDisplayDriver", "handle": "myLovelyPlane", })) s["d"]["in"].setInput(s["g"]["out"]) s["o"] = GafferScene.StandardOptions() s["o"]["options"]["renderCamera"]["value"].setValue("/group/camera") s["o"]["options"]["renderCamera"]["enabled"].setValue(True) s["o"]["in"].setInput(s["d"]["out"]) s["r"] = GafferRenderMan.InteractiveRenderManRender() s["r"]["in"].setInput(s["o"]["out"]) # start a render, give it time to finish, and check the output s["r"]["state"].setValue(s["r"].State.Running) time.sleep(2) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertAlmostEqual(c[1], 1, delta=0.001) # move the camera so it can't see the plane, and check the output s["c"]["transform"]["translate"]["x"].setValue(2) time.sleep(2) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertAlmostEqual(c[0], 0) # move the camera back and recheck s["c"]["transform"]["translate"]["x"].setValue(0) time.sleep(2) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertAlmostEqual(c[1], 1, delta=0.001)
def testHideLight(self): s = Gaffer.ScriptNode() s["l"] = GafferRenderMan.RenderManLight() s["l"].loadShader("pointlight") s["l"]["transform"]["translate"]["z"].setValue(1) s["v"] = GafferScene.StandardAttributes() s["v"]["attributes"]["visibility"]["enabled"].setValue(True) s["v"]["in"].setInput(s["l"]["out"]) s["p"] = GafferScene.Plane() s["c"] = GafferScene.Camera() s["c"]["transform"]["translate"]["z"].setValue(1) s["g"] = GafferScene.Group() s["g"]["in"][0].setInput(s["v"]["out"]) s["g"]["in"][1].setInput(s["p"]["out"]) s["g"]["in"][2].setInput(s["c"]["out"]) s["s"] = GafferRenderMan.RenderManShader() s["s"].loadShader("matte") s["a"] = GafferScene.ShaderAssignment() s["a"]["in"].setInput(s["g"]["out"]) s["a"]["shader"].setInput(s["s"]["out"]) s["d"] = GafferScene.Outputs() s["d"].addOutput( "beauty", IECore.Display( "test", "ieDisplay", "rgba", { "quantize": IECore.FloatVectorData([0, 0, 0, 0]), "driverType": "ImageDisplayDriver", "handle": "myLovelyPlane", })) s["d"]["in"].setInput(s["a"]["out"]) s["o"] = GafferScene.StandardOptions() s["o"]["options"]["renderCamera"]["value"].setValue("/group/camera") s["o"]["options"]["renderCamera"]["enabled"].setValue(True) s["o"]["in"].setInput(s["d"]["out"]) s["r"] = GafferRenderMan.InteractiveRenderManRender() s["r"]["in"].setInput(s["o"]["out"]) # start a render, give it time to finish, and check the output s["r"]["state"].setValue(s["r"].State.Running) time.sleep(2) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertNotEqual(c[0], 0.0) # remove the light by hiding it s["v"]["attributes"]["visibility"]["value"].setValue(False) time.sleep(2) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertEqual(c[0], 0.0) # put the light back by showing it s["v"]["attributes"]["visibility"]["value"].setValue(True) time.sleep(2) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertNotEqual(c[0], 0.0)
def testAddLight(self): s = Gaffer.ScriptNode() s["l"] = GafferRenderMan.RenderManLight() s["l"].loadShader("pointlight") s["l"]["parameters"]["lightcolor"].setValue(IECore.Color3f(1, 0, 0)) s["l"]["transform"]["translate"]["z"].setValue(1) s["p"] = GafferScene.Plane() s["c"] = GafferScene.Camera() s["c"]["transform"]["translate"]["z"].setValue(1) s["g"] = GafferScene.Group() s["g"]["in"][0].setInput(s["l"]["out"]) s["g"]["in"][1].setInput(s["p"]["out"]) s["g"]["in"][2].setInput(s["c"]["out"]) s["s"] = GafferRenderMan.RenderManShader() s["s"].loadShader("matte") s["a"] = GafferScene.ShaderAssignment() s["a"]["in"].setInput(s["g"]["out"]) s["a"]["shader"].setInput(s["s"]["out"]) s["d"] = GafferScene.Outputs() s["d"].addOutput( "beauty", IECore.Display( "test", "ieDisplay", "rgba", { "quantize": IECore.FloatVectorData([0, 0, 0, 0]), "driverType": "ImageDisplayDriver", "handle": "myLovelyPlane", })) s["d"]["in"].setInput(s["a"]["out"]) s["o"] = GafferScene.StandardOptions() s["o"]["options"]["renderCamera"]["value"].setValue("/group/camera") s["o"]["options"]["renderCamera"]["enabled"].setValue(True) s["o"]["in"].setInput(s["d"]["out"]) s["r"] = GafferRenderMan.InteractiveRenderManRender() s["r"]["in"].setInput(s["o"]["out"]) # start a render, give it time to finish, and check the output s["r"]["state"].setValue(s["r"].State.Running) time.sleep(2) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertEqual(c / c[0], IECore.Color3f(1, 0, 0)) # add a light s["l2"] = GafferRenderMan.RenderManLight() s["l2"].loadShader("pointlight") s["l2"]["parameters"]["lightcolor"].setValue(IECore.Color3f(0, 1, 0)) s["l2"]["transform"]["translate"]["z"].setValue(1) s["g"]["in"][3].setInput(s["l2"]["out"]) # give it time to update, and check the output time.sleep(1) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlane"), IECore.V2f(0.5), ) self.assertEqual(c / c[0], IECore.Color3f(1, 1, 0))
def testScopesDontLeak(self): s = Gaffer.ScriptNode() s["p"] = GafferScene.Plane() s["p"]["transform"]["translate"].setValue(IECore.V3f(-0.6, -0.1, 0)) s["p1"] = GafferScene.Plane() s["p1"]["transform"]["translate"].setValue(IECore.V3f(0.6, 0.1, 0)) s["c"] = GafferScene.Camera() s["c"]["transform"]["translate"]["z"].setValue(2) s["g"] = GafferScene.Group() s["g"]["in"][0].setInput(s["p"]["out"]) s["g"]["in"][1].setInput(s["p1"]["out"]) s["g"]["in"][2].setInput(s["c"]["out"]) s["s"] = GafferRenderMan.RenderManShader() s["s"].loadShader( self.compileShader(os.path.dirname(__file__) + "/shaders/flat.sl")) s["s"]["parameters"]["c"].setValue(IECore.Color3f(1, 0, 0)) s["f"] = GafferScene.PathFilter() s["f"]["paths"].setValue(IECore.StringVectorData(["/group/plane"])) s["a"] = GafferScene.ShaderAssignment() s["a"]["in"].setInput(s["g"]["out"]) s["a"]["shader"].setInput(s["s"]["out"]) s["a"]["filter"].setInput(s["f"]["out"]) s["d"] = GafferScene.Outputs() s["d"].addOutput( "beauty", IECore.Display( "test", "ieDisplay", "rgba", { "quantize": IECore.FloatVectorData([0, 0, 0, 0]), "driverType": "ImageDisplayDriver", "handle": "myLovelyPlanes", })) s["d"]["in"].setInput(s["a"]["out"]) s["o"] = GafferScene.StandardOptions() s["o"]["options"]["renderCamera"]["value"].setValue("/group/camera") s["o"]["options"]["renderCamera"]["enabled"].setValue(True) s["o"]["options"]["renderResolution"]["value"].setValue( IECore.V2i(512)) s["o"]["options"]["renderResolution"]["enabled"].setValue(True) s["o"]["in"].setInput(s["d"]["out"]) s["r"] = GafferRenderMan.InteractiveRenderManRender() s["r"]["in"].setInput(s["o"]["out"]) # start a render, give it time to finish, and check the output. # we should have a red plane on the left, and a facing ratio # shaded plane on the right, because we attached no shader to the # second plane. s["r"]["state"].setValue(s["r"].State.Running) time.sleep(2) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlanes"), IECore.V2f(0.25, 0.5), ) self.assertEqual(c, IECore.Color3f(1, 0, 0)) c1 = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlanes"), IECore.V2f(0.75, 0.5), ) self.assertTrue(c1[0] > 0.9) self.assertEqual(c1[0], c1[1]) self.assertEqual(c1[0], c1[2]) # adjust a shader parameter, wait, and check that the plane # on the left changed. check that the plane on the right didn't # change at all. s["s"]["parameters"]["c"].setValue(IECore.Color3f(0, 1, 0)) time.sleep(2) c = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlanes"), IECore.V2f(0.25, 0.5), ) self.assertEqual(c, IECore.Color3f(0, 1, 0)) c1 = self.__colorAtUV( IECore.ImageDisplayDriver.storedImage("myLovelyPlanes"), IECore.V2f(0.75, 0.5), ) self.assertTrue(c1[0] > 0.9) self.assertEqual(c1[0], c1[1]) self.assertEqual(c1[0], c1[2])
def testTransformMotion( self ) : s = Gaffer.ScriptNode() s["plane"] = GafferScene.Plane() s["sphere"] = GafferScene.Sphere() s["group"] = GafferScene.Group() s["group"]["in"][0].setInput( s["plane"]["out"] ) s["group"]["in"][1].setInput( s["sphere"]["out"] ) s["expression"] = Gaffer.Expression() s["expression"].setExpression( inspect.cleandoc( """ parent["plane"]["transform"]["translate"]["x"] = context.getFrame() parent["sphere"]["transform"]["translate"]["y"] = context.getFrame() * 2 parent["group"]["transform"]["translate"]["z"] = context.getFrame() - 1 """ ) ) s["planeFilter"] = GafferScene.PathFilter() s["planeFilter"]["paths"].setValue( IECore.StringVectorData( [ "/group/plane" ] ) ) s["attributes"] = GafferScene.StandardAttributes() s["attributes"]["in"].setInput( s["group"]["out"] ) s["attributes"]["filter"].setInput( s["planeFilter"]["out"] ) s["attributes"]["attributes"]["transformBlur"]["enabled"].setValue( True ) s["attributes"]["attributes"]["transformBlur"]["value"].setValue( False ) s["options"] = GafferScene.StandardOptions() s["options"]["in"].setInput( s["attributes"]["out"] ) s["options"]["options"]["transformBlur"]["enabled"].setValue( True ) s["render"] = GafferArnold.ArnoldRender() s["render"]["in"].setInput( s["options"]["out"] ) s["render"]["mode"].setValue( s["render"].Mode.SceneDescriptionMode ) s["render"]["fileName"].setValue( self.temporaryDirectory() + "/test.ass" ) # No motion blur s["options"]["options"]["transformBlur"]["value"].setValue( False ) s["render"]["task"].execute() with IECoreArnold.UniverseBlock() : arnold.AiASSLoad( self.temporaryDirectory() + "/test.ass" ) sphere = arnold.AiNodeLookUpByName( "/group/sphere" ) sphereTimes = arnold.AiNodeGetArray( sphere, "transform_time_samples" ) sphereMatrix = arnold.AtMatrix() arnold.AiNodeGetMatrix( sphere, "matrix", sphereMatrix ) plane = arnold.AiNodeLookUpByName( "/group/plane" ) planeTimes = arnold.AiNodeGetArray( plane, "transform_time_samples" ) planeMatrix = arnold.AtMatrix() arnold.AiNodeGetMatrix( plane, "matrix", planeMatrix ) expectedSphereMatrix = arnold.AtMatrix() arnold.AiM4Translation( expectedSphereMatrix, arnold.AtVector( 0, 2, 0 ) ) expectedPlaneMatrix = arnold.AtMatrix() arnold.AiM4Translation( expectedPlaneMatrix, arnold.AtVector( 1, 0, 0 ) ) self.__assertStructsEqual( sphereMatrix, expectedSphereMatrix ) self.__assertStructsEqual( planeMatrix, expectedPlaneMatrix ) # Motion blur s["options"]["options"]["transformBlur"]["value"].setValue( True ) s["render"]["task"].execute() with IECoreArnold.UniverseBlock() : arnold.AiASSLoad( self.temporaryDirectory() + "/test.ass" ) sphere = arnold.AiNodeLookUpByName( "/group/sphere" ) sphereTimes = arnold.AiNodeGetArray( sphere, "transform_time_samples" ) sphereMatrices = arnold.AiNodeGetArray( sphere, "matrix" ) plane = arnold.AiNodeLookUpByName( "/group/plane" ) planeTimes = arnold.AiNodeGetArray( plane, "transform_time_samples" ) planeMatrices = arnold.AiNodeGetArray( plane, "matrix" ) self.assertEqual( sphereTimes.contents.nelements, 2 ) self.assertEqual( sphereTimes.contents.nkeys, 1 ) self.assertEqual( sphereMatrices.contents.nelements, 1 ) self.assertEqual( sphereMatrices.contents.nkeys, 2 ) self.assertEqual( planeTimes.contents.nelements, 2 ) self.assertEqual( planeTimes.contents.nkeys, 1 ) self.assertEqual( planeMatrices.contents.nelements, 1 ) self.assertEqual( planeMatrices.contents.nkeys, 2 ) for i in range( 0, 2 ) : frame = 0.75 + 0.5 * i self.assertEqual( arnold.AiArrayGetFlt( sphereTimes, i ), frame ) self.assertEqual( arnold.AiArrayGetFlt( planeTimes, i ), frame ) sphereMatrix = arnold.AtMatrix() arnold.AiArrayGetMtx( sphereMatrices, i, sphereMatrix ) expectedSphereMatrix = arnold.AtMatrix() arnold.AiM4Translation( expectedSphereMatrix, arnold.AtVector( 0, frame * 2, frame - 1 ) ) planeMatrix = arnold.AtMatrix() arnold.AiArrayGetMtx( planeMatrices, i, planeMatrix ) expectedPlaneMatrix = arnold.AtMatrix() arnold.AiM4Translation( expectedPlaneMatrix, arnold.AtVector( 1, 0, frame - 1 ) ) self.__assertStructsEqual( sphereMatrix, expectedSphereMatrix ) self.__assertStructsEqual( planeMatrix, expectedPlaneMatrix )
def testDestination(self): # /group # /sphere1 # /sphere2 script = Gaffer.ScriptNode() script["sphere1"] = GafferScene.Sphere() script["sphere1"]["name"].setValue("sphere1") script["sphere1"]["transform"]["translate"]["x"].setValue(1) script["sphere2"] = GafferScene.Sphere() script["sphere2"]["name"].setValue("sphere2") script["sphere2"]["transform"]["translate"]["x"].setValue(2) script["group"] = GafferScene.Group() script["group"]["in"][0].setInput(script["sphere1"]["out"]) script["group"]["in"][1].setInput(script["sphere2"]["out"]) # "Parenting" a cube to each sphere, but putting the results at # the root of the scene. Using an expression to vary the dimensions # and sets of each cube. script["spheresFilter"] = GafferScene.PathFilter() script["spheresFilter"]["paths"].setValue( IECore.StringVectorData(["/group/sphere*"])) script["cube"] = GafferScene.Cube() script["expression"] = Gaffer.Expression() script["expression"].setExpression( inspect.cleandoc(""" first = context.get( "parent", "" ) == "/group/sphere1" parent["cube"]["sets"] = "set1" if first else "set2" parent["cube"]["dimensions"]["x"] = 1 if first else 2 """)) script["parent"] = GafferScene.Parent() script["parent"]["in"].setInput(script["group"]["out"]) script["parent"]["children"][0].setInput(script["cube"]["out"]) script["parent"]["filter"].setInput(script["spheresFilter"]["out"]) script["parent"]["parentVariable"].setValue("parent") script["parent"]["destination"].setValue("${scene:path}/../..") self.assertSceneValid(script["parent"]["out"]) # Because two cubes are being added below one location, the second will # have a numeric suffix to keep it unique from the other. It's ambiguous # as to which one should be the second, so we define it by sorting them # based on their original parent. self.assertEqual( script["parent"]["out"].childNames("/"), IECore.InternedStringVectorData(["group", "cube", "cube1"])) self.assertEqual( script["parent"]["out"].object("/cube").bound().size().x, 1) self.assertEqual( script["parent"]["out"].object("/cube1").bound().size().x, 2) self.assertEqual( script["parent"]["out"].childNames("/group"), IECore.InternedStringVectorData(["sphere1", "sphere2"])) self.assertEqual(script["parent"]["out"].childNames("/cube"), IECore.InternedStringVectorData()) self.assertEqual(script["parent"]["out"].childNames("/cube1"), IECore.InternedStringVectorData()) # The contents of the sets should reflect the same sorting and uniquefying. self.assertEqual(script["parent"]["out"].setNames(), IECore.InternedStringVectorData(["set1", "set2"])) self.assertEqual(script["parent"]["out"].set("set1").value, IECore.PathMatcher(["/cube"])) self.assertEqual(script["parent"]["out"].set("set2").value, IECore.PathMatcher(["/cube1"])) # We want the cubes to be positioned as if they were parented below the spheres. self.assertEqual( script["parent"]["out"].fullTransform("/cube"), script["parent"]["in"].fullTransform("/group/sphere1")) self.assertEqual( script["parent"]["out"].fullTransform("/cube1"), script["parent"]["in"].fullTransform("/group/sphere2")) # And if we move the cubes to a different location, we want all that to apply still. script["parent"]["destination"].setValue("/group") self.assertSceneValid(script["parent"]["out"]) self.assertEqual(script["parent"]["out"].childNames("/"), IECore.InternedStringVectorData(["group"])) self.assertEqual( script["parent"]["out"].childNames("/group"), IECore.InternedStringVectorData( ["sphere1", "sphere2", "cube", "cube1"])) self.assertEqual( script["parent"]["out"].object("/group/cube").bound().size().x, 1) self.assertEqual( script["parent"]["out"].object("/group/cube1").bound().size().x, 2) self.assertEqual(script["parent"]["out"].childNames("/group/cube"), IECore.InternedStringVectorData()) self.assertEqual(script["parent"]["out"].childNames("/group/cube1"), IECore.InternedStringVectorData()) self.assertEqual(script["parent"]["out"].setNames(), IECore.InternedStringVectorData(["set1", "set2"])) self.assertEqual(script["parent"]["out"].set("set1").value, IECore.PathMatcher(["/group/cube"])) self.assertEqual(script["parent"]["out"].set("set2").value, IECore.PathMatcher(["/group/cube1"])) self.assertEqual( script["parent"]["out"].fullTransform("/group/cube"), script["parent"]["in"].fullTransform("/group/sphere1")) self.assertEqual( script["parent"]["out"].fullTransform("/group/cube1"), script["parent"]["in"].fullTransform("/group/sphere2"))
def testWildcardInSetName(self): sphereA = GafferScene.Sphere("SphereA") sphereA["sets"].setValue('sphereA') sphereA["name"].setValue('sphereA') sphereB = GafferScene.Sphere("SphereB") sphereB["sets"].setValue('sphereB') sphereB["name"].setValue('sphereB') sphereC = GafferScene.Sphere("SphereC") sphereC["sets"].setValue('sphereC') sphereC["name"].setValue('sphereC') sphereC2 = GafferScene.Sphere("SphereC2") sphereC2["sets"].setValue('sphereC') sphereC2["name"].setValue('sphereC2') # sphere that we don't want in the resulting set undesired = GafferScene.Sphere("undesired") undesired["sets"].setValue('undesired') undesired["name"].setValue('undesired') group = GafferScene.Group("Group") group["in"][0].setInput(sphereA["out"]) group["in"][1].setInput(sphereB["out"]) group["in"][2].setInput(sphereC["out"]) group["in"][3].setInput(sphereC2["out"]) group["in"][4].setInput(undesired["out"]) oldHash = GafferScene.SetAlgo.setExpressionHash( "sphere*", group["out"]) # Test different features of StringAlgo. # Note that '-' is reserved as a SetExpression operator and the # respective range related feature of StringAlgo isn't supported ("myFoo[A-Z]"). self.assertCorrectEvaluation(group["out"], "sphere*", [ "/group/sphereA", "/group/sphereB", "/group/sphereC", "/group/sphereC2" ]) self.assertCorrectEvaluation(group["out"], "sphere* | undesired", [ "/group/sphereA", "/group/sphereB", "/group/sphereC", "/group/sphereC2", "/group/undesired" ]) self.assertCorrectEvaluation(group["out"], "sphere[AB]", ["/group/sphereA", "/group/sphereB"]) self.assertCorrectEvaluation(group["out"], "sphere[!AB]", ["/group/sphereC", "/group/sphereC2"]) self.assertCorrectEvaluation(group["out"], "sphere?", [ "/group/sphereA", "/group/sphereB", "/group/sphereC", "/group/sphereC2" ]) sphereC2["sets"].setValue('sphere?') self.assertCorrectEvaluation(group["out"], "sphere\?", ["/group/sphereC2"]) self.assertNotEqual( oldHash, GafferScene.SetAlgo.setExpressionHash("sphere*", group["out"]))
def testLightAndShadowLinking(self): sphere1 = GafferScene.Sphere() sphere2 = GafferScene.Sphere() attributes = GafferScene.StandardAttributes() arnoldAttributes = GafferArnold.ArnoldAttributes() light1 = GafferArnold.ArnoldLight() light1.loadShader("point_light") light2 = GafferArnold.ArnoldLight() light2.loadShader("point_light") group = GafferScene.Group() group["in"].addChild(GafferScene.ScenePlug("in1")) group["in"].addChild(GafferScene.ScenePlug("in2")) group["in"].addChild(GafferScene.ScenePlug("in3")) group["in"].addChild(GafferScene.ScenePlug("in4")) evaluate = GafferScene.EvaluateLightLinks() render = GafferArnold.ArnoldRender() attributes["in"].setInput(sphere1["out"]) arnoldAttributes["in"].setInput(attributes["out"]) group["in"]["in1"].setInput(arnoldAttributes["out"]) group["in"]["in2"].setInput(light1["out"]) group["in"]["in3"].setInput(light2["out"]) group["in"]["in4"].setInput(sphere2["out"]) evaluate["in"].setInput(group["out"]) render["in"].setInput(evaluate["out"]) # Illumination attributes["attributes"]["linkedLights"]["enabled"].setValue(True) attributes["attributes"]["linkedLights"]["value"].setValue( "/group/light /group/light1") # Shadows arnoldAttributes["attributes"]["shadowGroup"]["enabled"].setValue(True) arnoldAttributes["attributes"]["shadowGroup"]["value"].setValue( "/group/light /group/light1") # make sure we pass correct data into the renderer self.assertEqual( set(render["in"].attributes("/group/sphere")["linkedLights"]), set(IECore.StringVectorData(["/group/light", "/group/light1"]))) self.assertEqual( set(render["in"].attributes("/group/sphere") ["ai:visibility:shadow_group"]), set(IECore.StringVectorData(["/group/light", "/group/light1"]))) render["mode"].setValue(render.Mode.SceneDescriptionMode) render["fileName"].setValue(self.temporaryDirectory() + "/test.ass") render["task"].execute() with IECoreArnold.UniverseBlock(writable=True): arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass") # the first sphere had linked lights sphere = arnold.AiNodeLookUpByName("/group/sphere") # check illumination lights = arnold.AiNodeGetArray(sphere, "light_group") lightNames = [] for i in range(arnold.AiArrayGetNumElements(lights.contents)): light = arnold.cast(arnold.AiArrayGetPtr(lights, i), arnold.POINTER(arnold.AtNode)) lightNames.append(arnold.AiNodeGetName(light.contents)) doLinking = arnold.AiNodeGetBool(sphere, "use_light_group") self.assertEqual(set(lightNames), {"light:/group/light", "light:/group/light1"}) self.assertEqual(doLinking, True) # check shadows shadows = arnold.AiNodeGetArray(sphere, "shadow_group") lightNames = [] for i in range(arnold.AiArrayGetNumElements(shadows.contents)): light = arnold.cast(arnold.AiArrayGetPtr(shadows, i), arnold.POINTER(arnold.AtNode)) lightNames.append(arnold.AiNodeGetName(light.contents)) doLinking = arnold.AiNodeGetBool(sphere, "use_shadow_group") self.assertEqual(set(lightNames), {"light:/group/light", "light:/group/light1"}) self.assertEqual(doLinking, True) # the second sphere does not have any light linking enabled sphere1 = arnold.AiNodeLookUpByName("/group/sphere1") # check illumination lights = arnold.AiNodeGetArray(sphere1, "light_group") lightNames = [] for i in range(arnold.AiArrayGetNumElements(lights.contents)): light = arnold.cast(arnold.AiArrayGetPtr(lights, i), arnold.POINTER(arnold.AtNode)) lightNames.append(arnold.AiNodeGetName(light.contents)) doLinking = arnold.AiNodeGetBool(sphere1, "use_light_group") self.assertEqual(lightNames, []) self.assertEqual(doLinking, False) # check shadows shadows = arnold.AiNodeGetArray(sphere1, "shadow_group") lightNames = [] for i in range(arnold.AiArrayGetNumElements(shadows.contents)): light = arnold.cast(arnold.AiArrayGetPtr(shadows, i), arnold.POINTER(arnold.AtNode)) lightNames.append(arnold.AiNodeGetName(light.contents)) doLinking = arnold.AiNodeGetBool(sphere1, "use_shadow_group") self.assertEqual(lightNames, []) self.assertEqual(doLinking, False)
def test(self): sphere1 = GafferScene.Sphere("Sphere1") sphere1["name"].setValue('sphere1') sphere2 = GafferScene.Sphere("Sphere2") sphere2["name"].setValue('sphere2') sphere3 = GafferScene.Sphere("Sphere3") sphere3["name"].setValue('sphere3') group1 = GafferScene.Group("Group1") group1["in"].addChild(GafferScene.ScenePlug("in1")) group1["in"].addChild(GafferScene.ScenePlug("in2")) group1["in"]["in0"].setInput(sphere1["out"]) group1["in"]["in1"].setInput(sphere2["out"]) setA = GafferScene.Set("SetA") setA["name"].setValue('setA') setA["paths"].setValue( IECore.StringVectorData(['/group/sphere1', '/group/sphere2'])) setB = GafferScene.Set("SetB") setB["name"].setValue('setB') setB["paths"].setValue(IECore.StringVectorData(['/group/sphere2'])) setC = GafferScene.Set("SetC") setC["name"].setValue('setC') setC["paths"].setValue(IECore.StringVectorData(['/sphere3'])) setD = GafferScene.Set("SetD") setD["name"].setValue('setD') setD["paths"].setValue(IECore.StringVectorData([])) group2 = GafferScene.Group("Group2") group2["in"].addChild(GafferScene.ScenePlug("in1")) group2["in"].addChild(GafferScene.ScenePlug("in2")) group2["in"].addChild(GafferScene.ScenePlug("in3")) setA["in"].setInput(group1["out"]) setB["in"].setInput(setA["out"]) setC["in"].setInput(sphere3["out"]) setD["in"].setInput(setC["out"]) group2["in"]["in0"].setInput(setB["out"]) group2["in"]["in2"].setInput(setD["out"]) # Set memberships: # A: ( /group/group/sphere1, /group/group/sphere2 ) # B: ( /group/group/sphere2 ) # C: ( /group/sphere3 ) # D: ( ) expressionCheck = functools.partial(self.assertCorrectEvaluation, group2["out"]) expressionCheck('', []) expressionCheck('setA', ['/group/group/sphere1', '/group/group/sphere2']) expressionCheck('/group/sphere3', ['/group/sphere3']) # Test expressions that contain only sets and have a clearly defined evaluation order expressionCheck( '(setA | setC)', ['/group/group/sphere1', '/group/group/sphere2', '/group/sphere3']) expressionCheck('(setA | setB)', ['/group/group/sphere1', '/group/group/sphere2']) expressionCheck('(setA & setB)', ['/group/group/sphere2']) expressionCheck('(setA & setC)', []) expressionCheck('(setA | setB) & setD', []) expressionCheck('(setA & setB) | setD', ['/group/group/sphere2']) expressionCheck('(setA - setB)', ['/group/group/sphere1']) expressionCheck('(setA - setC)', ['/group/group/sphere1', '/group/group/sphere2']) expressionCheck('(setB - setC)', ['/group/group/sphere2']) # Test expressions that omit the explicit grouping and rely on operator precedence expressionCheck( 'setA setC', ['/group/group/sphere1', '/group/group/sphere2', '/group/sphere3']) expressionCheck( 'setA | setB | setC', ['/group/group/sphere1', '/group/group/sphere2', '/group/sphere3']) expressionCheck('setA | setB & setC', ['/group/group/sphere1', '/group/group/sphere2']) expressionCheck('setA & setB | setC', ['/group/group/sphere2', '/group/sphere3']) expressionCheck('setA & setB - setC', ['/group/group/sphere2']) expressionCheck('setA - setB | setC', ['/group/group/sphere1', '/group/sphere3']) # Test more complex expressions that contain explicit object names and lists thereof expressionCheck('/group/light1 /group/light2', ['/group/light1', '/group/light2']) expressionCheck('(/group/light1 /group/light2)', ['/group/light1', '/group/light2']) expressionCheck('/group/light1 /group/light2 setA', [ '/group/light1', '/group/light2', '/group/group/sphere1', '/group/group/sphere2' ]) expressionCheck('(/group/light1 /group/light2) | setA', [ '/group/light1', '/group/light2', '/group/group/sphere1', '/group/group/sphere2' ]) expressionCheck('setA & (/group/group/sphere1 /group/group/sphere42)', ['/group/group/sphere1']) expressionCheck('setA - /group/group/sphere2', ['/group/group/sphere1']) expressionCheck('(setA - /group/group/sphere2)', ['/group/group/sphere1']) expressionCheck('setA - ((setC /group/group/sphere2) & setB)', ['/group/group/sphere1']) expressionCheck('(setA - ((setC /group/group/sphere2) & setB))', ['/group/group/sphere1']) expressionCheck( 'setA - (/group/group/sphere1 /group/group/sphere2) | (setA setB setC) & setC', ['/group/sphere3']) # Test if proper exception is thrown for invalid expression with self.assertRaises(RuntimeError) as e: # note the missing ) GafferScene.SetAlgo.evaluateSetExpression( 'setA - (/group/group/sphere2', group2["out"]) self.assertEqual( str(e.exception), 'Syntax error in indicated part of SetExpression.\nsetA - (/group/group/sphere2\n |---------------------|\n.' ) # Sets that don't exist should be replaced with an empty PathMatcher expressionCheck('A', []) # Test that changing set contents will result in an updated hash h = GafferScene.SetAlgo.setExpressionHash("setA", group2["out"]) setA["paths"].setValue(IECore.StringVectorData(['/group/sphere1'])) self.assertNotEqual( h, GafferScene.SetAlgo.setExpressionHash("setA", group2["out"]))
def testFrom(self): # - group1 # - group2 # - light1 # - light2 # - light3 # - plane light1 = GafferSceneTest.TestLight() light1["name"].setValue("light1") light2 = GafferSceneTest.TestLight() light2["name"].setValue("light2") light3 = GafferSceneTest.TestLight() light3["name"].setValue("light3") group1 = GafferScene.Group() group1["name"].setValue("group1") group2 = GafferScene.Group() group2["name"].setValue("group2") group1["in"][0].setInput(group2["out"]) group1["in"][1].setInput(light3["out"]) group2["in"][0].setInput(light1["out"]) group2["in"][1].setInput(light2["out"]) plane = GafferScene.Plane() parent = GafferScene.Parent() parent["parent"].setValue("/") parent["in"].setInput(group1["out"]) parent["child"].setInput(plane["out"]) isolate = GafferScene.Isolate() isolate["in"].setInput(parent["out"]) self.assertSceneValid(isolate["out"]) self.assertEqual(isolate["out"].childNames("/"), IECore.InternedStringVectorData(["group1", "plane"])) self.assertEqual(isolate["out"].childNames("/group1"), IECore.InternedStringVectorData(["group2", "light3"])) self.assertEqual(isolate["out"].childNames("/group1/group2"), IECore.InternedStringVectorData(["light1", "light2"])) filter = GafferScene.PathFilter() filter["paths"].setValue( IECore.StringVectorData(["/group1/group2/light1"])) isolate["filter"].setInput(filter["out"]) self.assertSceneValid(isolate["out"]) self.assertEqual(isolate["out"].childNames("/"), IECore.InternedStringVectorData(["group1"])) self.assertEqual(isolate["out"].childNames("/group1"), IECore.InternedStringVectorData(["group2"])) self.assertEqual(isolate["out"].childNames("/group1/group2"), IECore.InternedStringVectorData(["light1"])) isolate["from"].setValue("/group1") self.assertSceneValid(isolate["out"]) self.assertEqual(isolate["out"].childNames("/"), IECore.InternedStringVectorData(["group1", "plane"])) self.assertEqual(isolate["out"].childNames("/group1"), IECore.InternedStringVectorData(["group2"])) self.assertEqual(isolate["out"].childNames("/group1/group2"), IECore.InternedStringVectorData(["light1"])) isolate["from"].setValue("/group1/group2") self.assertSceneValid(isolate["out"]) self.assertEqual(isolate["out"].childNames("/"), IECore.InternedStringVectorData(["group1", "plane"])) self.assertEqual(isolate["out"].childNames("/group1"), IECore.InternedStringVectorData(["group2", "light3"])) self.assertEqual(isolate["out"].childNames("/group1/group2"), IECore.InternedStringVectorData(["light1"]))
def testOrientation( self ) : script = Gaffer.ScriptNode() script["plane"] = GafferScene.Plane() script["plane"]["transform"]["rotate"]["y"].setValue( 90 ) script["group"] = GafferScene.Group() script["group"]["in"][0].setInput( script["plane"]["out"] ) script["group"]["transform"]["rotate"]["y"].setValue( 90 ) view = GafferSceneUI.SceneView() view["in"].setInput( script["group"]["out"] ) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), IECore.PathMatcher( [ "/group/plane" ] ) ) tool = GafferSceneUI.TranslateTool( view ) tool["active"].setValue( True ) # Local tool["orientation"].setValue( tool.Orientation.Local ) with Gaffer.UndoScope( script ) : tool.translate( imath.V3f( 1, 0, 0 ) ) self.assertTrue( imath.V3f( -1, 0, 0 ).equalWithAbsError( script["group"]["out"].fullTransform( "/group/plane" ).translation(), 0.000001 ) ) script.undo() # Parent tool["orientation"].setValue( tool.Orientation.Parent ) with Gaffer.UndoScope( script ) : tool.translate( imath.V3f( 1, 0, 0 ) ) self.assertTrue( imath.V3f( 0, 0, -1 ).equalWithAbsError( script["group"]["out"].fullTransform( "/group/plane" ).translation(), 0.0000001 ) ) script.undo() # World tool["orientation"].setValue( tool.Orientation.World ) with Gaffer.UndoScope( script ) : tool.translate( imath.V3f( 1, 0, 0 ) ) self.assertTrue( imath.V3f( 1, 0, 0 ).equalWithAbsError( script["group"]["out"].fullTransform( "/group/plane" ).translation(), 0.0000001 ) )
def testKeepLightsAndCameras(self): # - group # - light # - camera # - model1 # - sphere # - light # - model2 # - sphere # - light light = GafferSceneTest.TestLight() light["sets"].setValue("lightsAndSpheres") sphere = GafferScene.Sphere() sphere["sets"].setValue("lightsAndSpheres") camera = GafferScene.Camera() model1 = GafferScene.Group() model1["in"][0].setInput(sphere["out"]) model1["in"][1].setInput(light["out"]) model1["name"].setValue("model1") model2 = GafferScene.Group() model2["in"][0].setInput(sphere["out"]) model2["in"][1].setInput(light["out"]) model2["name"].setValue("model2") group = GafferScene.Group() group["in"][0].setInput(light["out"]) group["in"][1].setInput(camera["out"]) group["in"][2].setInput(model1["out"]) group["in"][3].setInput(model2["out"]) self.assertSceneValid(group["out"]) filter = GafferScene.PathFilter() filter["paths"].setValue(IECore.StringVectorData(["/group/model1"])) isolate = GafferScene.Isolate() isolate["in"].setInput(group["out"]) isolate["filter"].setInput(filter["out"]) # Keep neither self.assertSceneValid(isolate["out"]) self.assertTrue( GafferScene.SceneAlgo.exists(isolate["out"], "/group/model1/sphere")) self.assertTrue( GafferScene.SceneAlgo.exists(isolate["out"], "/group/model1/light")) self.assertTrue( GafferScene.SceneAlgo.exists(isolate["out"], "/group/model1")) self.assertFalse( GafferScene.SceneAlgo.exists(isolate["out"], "/group/model2/sphere")) self.assertFalse( GafferScene.SceneAlgo.exists(isolate["out"], "/group/model2")) self.assertFalse( GafferScene.SceneAlgo.exists(isolate["out"], "/group/light")) self.assertFalse( GafferScene.SceneAlgo.exists(isolate["out"], "/group/camera")) self.assertEqual(isolate["out"].set("__lights").value.paths(), ["/group/model1/light"]) self.assertEqual(isolate["out"].set("__cameras").value.paths(), []) self.assertEqual( isolate["out"].set("lightsAndSpheres").value, GafferScene.PathMatcher( ["/group/model1/sphere", "/group/model1/light"])) self.assertNotEqual(isolate["out"].setHash("__lights"), group["out"].setHash("__lights")) self.assertNotEqual(isolate["out"].setHash("__cameras"), group["out"].setHash("__cameras")) # Keep lights isolate["keepLights"].setValue(True) self.assertSceneValid(isolate["out"]) self.assertFalse( GafferScene.SceneAlgo.exists(isolate["out"], "/group/camera")) self.assertEqual(isolate["out"].set("__lights"), group["out"].set("__lights")) self.assertEqual(isolate["out"].set("__cameras").value.paths(), []) self.assertEqual( isolate["out"].set("lightsAndSpheres").value, GafferScene.PathMatcher( ["/group/model1/sphere"] + group["out"].set("__lights").value.paths())) self.assertEqual(isolate["out"].setHash("__lights"), group["out"].setHash("__lights")) self.assertNotEqual(isolate["out"].setHash("__cameras"), group["out"].setHash("__cameras")) # Keep cameras too isolate["keepCameras"].setValue(True) self.assertSceneValid(isolate["out"]) self.assertTrue( GafferScene.SceneAlgo.exists(isolate["out"], "/group/camera")) self.assertEqual(isolate["out"].set("__lights"), group["out"].set("__lights")) self.assertEqual(isolate["out"].set("__cameras"), group["out"].set("__cameras")) self.assertEqual( isolate["out"].set("lightsAndSpheres").value, GafferScene.PathMatcher( ["/group/model1/sphere"] + group["out"].set("__lights").value.paths())) self.assertEqual(isolate["out"].setHash("__lights"), group["out"].setHash("__lights")) self.assertEqual(isolate["out"].setHash("__cameras"), group["out"].setHash("__cameras"))
def __init__( self, name = "__CameraSetup" ) : GafferScene.FilteredSceneProcessor.__init__( self, name ) # Public plugs self["cameraGroup"] = Gaffer.StringPlug( "cameraGroup", Gaffer.Plug.Direction.In, "__TEXTUREBAKE_CAMERAS" ) self["bakeDirectory"] = Gaffer.StringPlug( "bakeDirectory", Gaffer.Plug.Direction.In, "" ) self["defaultFileName"] = Gaffer.StringPlug( "defaultFileName", Gaffer.Plug.Direction.In, "${bakeDirectory}/<AOV>/<AOV>.<UDIM>.exr" ) self["defaultResolution"] = Gaffer.IntPlug( "defaultResolution", Gaffer.Plug.Direction.In, 512 ) self["uvSet"] = Gaffer.StringPlug( "uvSet", Gaffer.Plug.Direction.In, "uv" ) self["udims"] = Gaffer.StringPlug( "udims", Gaffer.Plug.Direction.In, "" ) self["normalOffset"] = Gaffer.FloatPlug( "normalOffset", Gaffer.Plug.Direction.In, 0.1 ) self["aovs"] = Gaffer.StringPlug( "aovs", Gaffer.Plug.Direction.In, "beauty:rgba" ) self["tasks"] = Gaffer.IntPlug( "tasks", Gaffer.Plug.Direction.In, 1 ) self["taskIndex"] = Gaffer.IntPlug( "taskIndex", Gaffer.Plug.Direction.In, 0 ) # Output self["renderFileList"] = Gaffer.StringVectorDataPlug( "renderFileList", Gaffer.Plug.Direction.Out, defaultValue = IECore.StringVectorData() ) self["renderFileList"].setFlags( Gaffer.Plug.Flags.Serialisable, False ) # Private internal network self["__udimQuery"] = GafferScene.UDIMQuery() self["__udimQuery"]["in"].setInput( self["in"] ) self["__udimQuery"]["uvSet"].setInput( self["uvSet"] ) self["__udimQuery"]["attributes"].setValue( "bake:resolution bake:fileName" ) self["__udimQuery"]["filter"].setInput( self["filter"] ) self["__chunkedBakeInfo"] = Gaffer.CompoundObjectPlug( "__chunkedBakeInfo", Gaffer.Plug.Direction.In, IECore.CompoundObject() ) self["__chunkedBakeInfo"].setFlags( Gaffer.Plug.Flags.Serialisable, False ) self["__chunkExpression"] = Gaffer.Expression() self["__chunkExpression"].setExpression( inspect.cleandoc( """ import collections import re rawInfo = parent["__udimQuery"]["out"] defaultFileName = parent["defaultFileName"] defaultResolution = parent["defaultResolution"] selectUdimsStr = parent["udims"] # FrameList really ought to take care of this check, instead of just doing # something obviously wrong if re.match( ".*[0-9] +[0-9].*", selectUdimsStr ): raise RuntimeError( "ArnoldTextureBake : Udim list must be comma separated." ) selectUdims = set( IECore.FrameList.parse( selectUdimsStr ).asList() ) allMeshes = collections.defaultdict( lambda : [] ) for udim, meshes in rawInfo.items(): if selectUdims and not int( udim ) in selectUdims: continue for mesh, extraAttributes in meshes.items(): resolution = defaultResolution if "bake:resolution" in extraAttributes: resolution = extraAttributes["bake:resolution"].value fileName = defaultFileName if "bake:fileName" in extraAttributes: fileName = extraAttributes["bake:fileName"].value allMeshes[ (fileName, udim) ].append( { "mesh" : mesh, "resolution" : resolution } ) fileList = sorted( allMeshes.keys() ) info = IECore.CompoundObject() numTasks = min( parent["tasks"], len( fileList ) ) taskIndex = parent["taskIndex"] if taskIndex < numTasks: chunkStart = ( taskIndex * len( fileList ) ) / numTasks chunkEnd = ( ( taskIndex + 1 ) * len( fileList ) ) / numTasks dupeCount = 0 prevFileName = "" for fileNameTemplate, udim in fileList[chunkStart:chunkEnd]: for meshData in allMeshes[(fileNameTemplate, udim)]: o = IECore.CompoundObject() o["mesh"] = IECore.StringData( meshData["mesh"] ) o["udim"] = IECore.IntData( int( udim ) ) o["resolution"] = IECore.IntData( meshData["resolution"] ) udimStr = str( udim ) fileName = fileNameTemplate.replace( "<UDIM>", udimStr ) if fileName == prevFileName: dupeCount += 1 fileName = fileName + ".layer" + str( dupeCount ) else: prevFileName = fileName dupeCount = 0 o["fileName"] = IECore.StringData( fileName ) name = o["mesh"].value.replace( "/", "_" ) + "." + udimStr info[ name ] = o parent["__chunkedBakeInfo"] = info fileList = [] for name, i in info.items(): fileName = i["fileName"].value for nameAndAov in parent["aovs"].strip( " " ).split( " " ): fileList.append( i["fileName"].value.replace( "<AOV>", nameAndAov.split(":")[0] ) ) parent["renderFileList"] = IECore.StringVectorData( fileList ) """ ), "python" ) self["__parent"] = GafferScene.Parent() self["__parent"]["parent"].setValue( "/" ) for c in ['bound', 'transform', 'attributes', 'object', 'childNames', 'setNames', 'set']: self["__parent"]["in"][c].setInput( self["in"][c] ) self["__outputExpression"] = Gaffer.Expression() self["__outputExpression"].setExpression( inspect.cleandoc( """ import IECoreScene # Transfer all input globals except for outputs inGlobals = parent["in"]["globals"] outGlobals = IECore.CompoundObject() for key, value in inGlobals.items(): if not key.startswith( "output:" ): outGlobals[key] = value # Make our own outputs info = parent["__chunkedBakeInfo"] for cameraName, i in info.items(): params = IECore.CompoundData() fileName = i["fileName"].value params["camera"] = IECore.StringData( "/" + parent["cameraGroup"] + "/" + cameraName ) for nameAndAov in parent["aovs"].strip( " " ).split( " " ): tokens = nameAndAov.split( ":" ) if len( tokens ) != 2: raise RuntimeError( "Invalid bake aov specification: %s It should contain a : between name and data." ) ( aovName, aov ) = tokens aovFileName = fileName.replace( "<AOV>", aovName ) outGlobals["output:" + cameraName + "." + aov] = IECoreScene.Output( aovFileName, "exr", aov + " RGBA", params ) parent["__parent"]["in"]["globals"] = outGlobals """ ), "python" ) self["__camera"] = GafferScene.Camera() self["__camera"]["projection"].setValue( "orthographic" ) self["__cameraTweaks"] = GafferScene.CameraTweaks() self["__cameraTweaks"]["in"].setInput( self["__camera"]["out"] ) self["__cameraTweaks"]["tweaks"]["projection"] = GafferScene.TweakPlug( "projection", "uv_camera" ) self["__cameraTweaks"]["tweaks"]["resolution"] = GafferScene.TweakPlug( "resolution", imath.V2i( 0 ) ) self["__cameraTweaks"]["tweaks"]["u_offset"] = GafferScene.TweakPlug( "u_offset", 0.0 ) self["__cameraTweaks"]["tweaks"]["v_offset"] = GafferScene.TweakPlug( "v_offset", 0.0 ) self["__cameraTweaks"]["tweaks"]["mesh"] = GafferScene.TweakPlug( "mesh", "" ) self["__cameraTweaks"]["tweaks"]["uv_set"] = GafferScene.TweakPlug( "uv_set", "" ) self["__cameraTweaks"]["tweaks"]["extend_edges"] = GafferScene.TweakPlug( "extend_edges", False ) self["__cameraTweaks"]["tweaks"]["offset"] = GafferScene.TweakPlug( "offset", 0.1 ) self["__cameraTweaks"]["tweaks"]["offset"]["value"].setInput( self["normalOffset"] ) self["__cameraTweaksFilter"] = GafferScene.PathFilter() self["__cameraTweaksFilter"]["paths"].setValue( IECore.StringVectorData( [ '/camera' ] ) ) self["__cameraTweaks"]["filter"].setInput( self["__cameraTweaksFilter"]["out"] ) self["__collectScenes"] = GafferScene.CollectScenes() self["__collectScenes"]["sourceRoot"].setValue( "/camera" ) self["__collectScenes"]["rootNameVariable"].setValue( "collect:cameraName" ) self["__collectScenes"]["in"].setInput( self["__cameraTweaks"]["out"] ) self["__group"] = GafferScene.Group() self["__group"]["in"][0].setInput( self["__collectScenes"]["out"] ) self["__group"]["name"].setInput( self["cameraGroup"] ) self["__parent"]["children"][0].setInput( self["__group"]["out"] ) self["__collectSceneRootsExpression"] = Gaffer.Expression() self["__collectSceneRootsExpression"].setExpression( inspect.cleandoc( """ info = parent["__chunkedBakeInfo"] parent["__collectScenes"]["rootNames"] = IECore.StringVectorData( info.keys() ) """ ), "python" ) self["__cameraSetupExpression"] = Gaffer.Expression() self["__cameraSetupExpression"].setExpression( inspect.cleandoc( """ cameraName = context["collect:cameraName"] info = parent["__chunkedBakeInfo"] i = info[cameraName] udimOffset = i["udim"].value - 1001 parent["__cameraTweaks"]["tweaks"]["resolution"]["value"] = imath.V2i( i["resolution"].value ) parent["__cameraTweaks"]["tweaks"]["u_offset"]["value"] = -( udimOffset % 10 ) parent["__cameraTweaks"]["tweaks"]["v_offset"]["value"] = -( udimOffset / 10 ) parent["__cameraTweaks"]["tweaks"]["mesh"]["value"] = i["mesh"].value parent["__cameraTweaks"]["tweaks"]["uv_set"]["value"] = parent["uvSet"] if parent["uvSet"] != "uv" else "" """ ), "python" ) self["out"].setFlags( Gaffer.Plug.Flags.Serialisable, False ) self["out"].setInput( self["__parent"]["out"] )
def testRoot(self): script = Gaffer.ScriptNode() script["sphere"] = GafferScene.Sphere() script["sphere"]["sets"].setValue("sphereSet") script["group"] = GafferScene.Group() script["group"]["in"][0].setInput(script["sphere"]["out"]) script["cube"] = GafferScene.Cube() script["cube"]["sets"].setValue("cubeSet") script["switch"] = Gaffer.Switch() script["switch"].setup(GafferScene.ScenePlug()) script["switch"]["in"][0].setInput(script["group"]["out"]) script["switch"]["in"][1].setInput(script["cube"]["out"]) script["collect"] = GafferScene.CollectScenes() script["collect"]["in"].setInput(script["switch"]["out"]) script["collect"]["rootNames"].setValue( IECore.StringVectorData(["0", "1", "2", "3"])) script["expression"] = Gaffer.Expression() script["expression"].setExpression( inspect.cleandoc(""" root = context.get( "collect:rootName", "0" ) parent["switch"]["index"] = int( root ) > 1 parent["collect"]["sourceRoot"] = { "0" : "", "1" : "/group", "2" : "/", "3" : "/cube" }[root] """)) self.assertEqual(script["collect"]["out"].childNames("/"), IECore.InternedStringVectorData(["0", "1", "2", "3"])) self.assertEqual(script["collect"]["out"].childNames("/0"), IECore.InternedStringVectorData(["group"])) self.assertEqual(script["collect"]["out"].childNames("/1"), IECore.InternedStringVectorData(["sphere"])) self.assertEqual(script["collect"]["out"].childNames("/2"), IECore.InternedStringVectorData(["cube"])) self.assertEqual(script["collect"]["out"].childNames("/3"), IECore.InternedStringVectorData()) self.assertEqual(script["collect"]["out"].object("/0"), IECore.NullObject()) self.assertEqual(script["collect"]["out"].object("/1"), IECore.NullObject()) self.assertEqual(script["collect"]["out"].object("/2"), IECore.NullObject()) self.assertEqual(script["collect"]["out"].object("/3"), script["cube"]["out"].object("/cube")) self.assertEqual(script["collect"]["out"].childNames("/0/group"), IECore.InternedStringVectorData(["sphere"])) self.assertEqual(script["collect"]["out"].childNames("/1/sphere"), IECore.InternedStringVectorData()) self.assertEqual(script["collect"]["out"].childNames("/2/cube"), IECore.InternedStringVectorData()) self.assertEqual(script["collect"]["out"].object("/0/group"), IECore.NullObject()) self.assertEqual(script["collect"]["out"].object("/1/sphere"), script["sphere"]["out"].object("/sphere")) self.assertEqual(script["collect"]["out"].object("/2/cube"), script["cube"]["out"].object("/cube")) self.assertEqual( script["collect"]["out"].childNames("/0/group/sphere"), IECore.InternedStringVectorData()) self.assertEqual(script["collect"]["out"].object("/0/group/sphere"), script["sphere"]["out"].object("/sphere")) self.assertEqual( script["collect"]["out"]["setNames"].getValue(), IECore.InternedStringVectorData(["sphereSet", "cubeSet"])) self.assertEqual( set(script["collect"]["out"].set("sphereSet").value.paths()), { "/0/group/sphere", "/1/sphere", }) self.assertEqual( set(script["collect"]["out"].set("cubeSet").value.paths()), { "/2/cube", "/3", })
def testLightAndShadowLinking(self): sphere1 = GafferScene.Sphere() sphere2 = GafferScene.Sphere() attributes = GafferScene.StandardAttributes() arnoldAttributes = GafferArnold.ArnoldAttributes() light1 = GafferArnold.ArnoldLight() light1.loadShader("point_light") light2 = GafferArnold.ArnoldLight() light2.loadShader("point_light") group = GafferScene.Group() render = GafferArnold.ArnoldRender() attributes["in"].setInput(sphere1["out"]) arnoldAttributes["in"].setInput(attributes["out"]) group["in"][0].setInput(arnoldAttributes["out"]) group["in"][1].setInput(light1["out"]) group["in"][2].setInput(light2["out"]) group["in"][3].setInput(sphere2["out"]) render["in"].setInput(group["out"]) # Illumination attributes["attributes"]["linkedLights"]["enabled"].setValue(True) attributes["attributes"]["linkedLights"]["value"].setValue( "/group/light") # Shadows arnoldAttributes["attributes"]["shadowGroup"]["enabled"].setValue(True) arnoldAttributes["attributes"]["shadowGroup"]["value"].setValue( "/group/light1") render["mode"].setValue(render.Mode.SceneDescriptionMode) render["fileName"].setValue(self.temporaryDirectory() + "/test.ass") render["task"].execute() with IECoreArnold.UniverseBlock(writable=True): arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass") # the first sphere had linked lights sphere = arnold.AiNodeLookUpByName("/group/sphere") # check illumination self.assertTrue(arnold.AiNodeGetBool(sphere, "use_light_group")) lights = arnold.AiNodeGetArray(sphere, "light_group") self.assertEqual(arnold.AiArrayGetNumElements(lights), 1) self.assertEqual( arnold.AiNodeGetName(arnold.AiArrayGetPtr(lights, 0)), "light:/group/light") # check shadows self.assertTrue(arnold.AiNodeGetBool(sphere, "use_shadow_group")) shadows = arnold.AiNodeGetArray(sphere, "shadow_group") self.assertEqual(arnold.AiArrayGetNumElements(shadows), 1) self.assertEqual( arnold.AiNodeGetName(arnold.AiArrayGetPtr(shadows, 0)), "light:/group/light1") # the second sphere does not have any light linking enabled sphere1 = arnold.AiNodeLookUpByName("/group/sphere1") # check illumination self.assertFalse(arnold.AiNodeGetBool(sphere1, "use_light_group")) lights = arnold.AiNodeGetArray(sphere1, "light_group") self.assertEqual(arnold.AiArrayGetNumElements(lights), 0) # check shadows self.assertFalse(arnold.AiNodeGetBool(sphere1, "use_shadow_group")) shadows = arnold.AiNodeGetArray(sphere1, "shadow_group") self.assertEqual(arnold.AiArrayGetNumElements(shadows), 0)
def test(self): # Make a few input scenes script = Gaffer.ScriptNode() script["sphere"] = GafferScene.Sphere() script["sphere"]["sets"].setValue("spheres") script["cube"] = GafferScene.Cube() script["cube"]["sets"].setValue("cubes") script["group"] = GafferScene.Group() script["group"]["in"][0].setInput(script["sphere"]["out"]) script["group"]["in"][1].setInput(script["cube"]["out"]) script["switch"] = Gaffer.Switch() script["switch"].setup(GafferScene.ScenePlug()) script["switch"]["in"][0].setInput(script["sphere"]["out"]) script["switch"]["in"][1].setInput(script["cube"]["out"]) script["switch"]["in"][2].setInput(script["group"]["out"]) # Make an empty CollectScenes script["collect"] = GafferScene.CollectScenes() script["collect"]["in"].setInput(script["switch"]["out"]) self.assertSceneValid(script["collect"]["out"]) self.assertEqual(script["collect"]["out"].childNames("/"), IECore.InternedStringVectorData()) # Configure it to collect the input scenes script["collect"]["rootNames"].setValue( IECore.StringVectorData(["sphere", "cube", "group"])) script["expression"] = Gaffer.Expression() script["expression"].setExpression( inspect.cleandoc(""" scenes = parent["collect"]["rootNames"] parent["switch"]["index"] = scenes.index( context.get( "collect:rootName", "sphere" ) ) """)) # Check we get what we expect self.assertEqual( script["collect"]["out"].childNames("/"), IECore.InternedStringVectorData(["sphere", "cube", "group"])) self.assertSceneValid(script["collect"]["out"]) script["subTree"] = GafferScene.SubTree() script["subTree"]["in"].setInput(script["collect"]["out"]) script["subTree"]["root"].setValue("/sphere") self.assertScenesEqual(script["subTree"]["out"], script["sphere"]["out"], checks=self.allSceneChecks - {"sets"}) script["subTree"]["root"].setValue("/cube") self.assertScenesEqual(script["subTree"]["out"], script["cube"]["out"], checks=self.allSceneChecks - {"sets"}) script["subTree"]["root"].setValue("/group") self.assertScenesEqual(script["subTree"]["out"], script["group"]["out"]) # Check the sets too self.assertEqual(script["collect"]["out"]["setNames"].getValue(), IECore.InternedStringVectorData(["spheres", "cubes"])) self.assertEqual( script["collect"]["out"].set("spheres").value, IECore.PathMatcher(["/sphere/sphere", "/group/group/sphere"])) self.assertEqual( script["collect"]["out"].set("cubes").value, IECore.PathMatcher(["/cube/cube", "/group/group/cube"]))
def testCustomPosition(self): littleCube = GafferScene.Cube() littleCube["name"].setValue("little") bigCube = GafferScene.Cube() bigCube["dimensions"].setValue(imath.V3f(10, 10, 10)) bigCube["name"].setValue("big") camera = GafferScene.Camera() camera["transform"]["translate"]["z"].setValue(10) group = GafferScene.Group() group["in"][0].setInput(littleCube["out"]) group["in"][1].setInput(bigCube["out"]) group["in"][2].setInput(camera["out"]) self.assertNotEqual( group["out"].object("/group/little")["P"].data, group["out"].object("/group/big")["P"].data, ) bigCubeFilter = GafferScene.PathFilter() bigCubeFilter["paths"].setValue(IECore.StringVectorData(["/group/big" ])) shuffle = GafferScene.ShufflePrimitiveVariables() shuffle["in"].setInput(group["out"]) shuffle["filter"].setInput(bigCubeFilter["out"]) shuffle["shuffles"].addChild(Gaffer.ShufflePlug("P", "Pref")) littleCubeFilter = GafferScene.PathFilter() littleCubeFilter["paths"].setValue( IECore.StringVectorData(["/group/little"])) copy = GafferScene.CopyPrimitiveVariables() copy["in"].setInput(shuffle["out"]) copy["source"].setInput(shuffle["out"]) copy["filter"].setInput(littleCubeFilter["out"]) copy["sourceLocation"].setValue("/group/big") copy["primitiveVariables"].setValue("Pref") self.assertEqual( copy["out"].object("/group/little")["Pref"].data, copy["out"].object("/group/big")["Pref"].data, ) unionFilter = GafferScene.UnionFilter() unionFilter["in"][0].setInput(littleCubeFilter["out"]) unionFilter["in"][1].setInput(bigCubeFilter["out"]) projection = GafferScene.MapProjection() projection["in"].setInput(copy["out"]) projection["filter"].setInput(unionFilter["out"]) projection["camera"].setValue("/group/camera") projection["uvSet"].setValue("projectedUV") self.assertNotEqual( projection["out"].object("/group/little")["projectedUV"].data, projection["out"].object("/group/big")["projectedUV"].data, ) projection["position"].setValue("Pref") self.assertEqual( projection["out"].object("/group/little")["projectedUV"].data[0], projection["out"].object("/group/big")["projectedUV"].data[0], ) self.assertEqual( projection["out"].object("/group/little")["projectedUV"].data, projection["out"].object("/group/big")["projectedUV"].data, )
def test(self): sphere = GafferScene.Sphere("Sphere") attributes = GafferScene.StandardAttributes() attributes["attributes"]["linkedLights"]["enabled"].setValue(True) attributes["in"].setInput(sphere["out"]) mainGroup = GafferScene.Group("MainGroup") mainGroup["in"].addChild(GafferScene.ScenePlug("in1")) mainGroup["in"].addChild(GafferScene.ScenePlug("in2")) light1 = GafferSceneTest.TestLight() light2 = GafferSceneTest.TestLight() lightGroup = GafferScene.Group("LightGroup") lightGroup["in"].addChild(GafferScene.ScenePlug("in1")) lightGroup["in"].addChild(GafferScene.ScenePlug("in2")) lightGroup["in"]["in1"].setInput(light1["out"]) lightGroup["in"]["in2"].setInput(light2["out"]) mainGroup["in"]["in1"].setInput(attributes["out"]) mainGroup["in"]["in2"].setInput(lightGroup["out"]) lightSet = GafferScene.Set("lightSet") lightSet["in"].setInput(mainGroup["out"]) lightSet["name"].setValue('lightSet') lightSet["paths"].setValue( IECore.StringVectorData( ['/group/group/light', '/group/group/light1'])) evalNode = GafferScene.EvaluateLightLinks() evalNode["in"].setInput(lightSet["out"]) # Test a single light attributes["attributes"]["linkedLights"]["value"].setValue( "/group/group/light") self.assertEqual( set( map( str, evalNode["out"].attributes("/group/sphere") ["linkedLights"])), set(["/group/group/light"])) # Test a simple list of lights attributes["attributes"]["linkedLights"]["value"].setValue( "/group/group/light /group/group/light1") self.assertEqual( set( map( str, evalNode["out"].attributes("/group/sphere") ["linkedLights"])), set(["/group/group/light", "/group/group/light1"])) # Make sure only lights come through attributes["attributes"]["linkedLights"]["value"].setValue( "/group/group/light /group/group/light1 /group/sphere") self.assertEqual( set( map( str, evalNode["out"].attributes("/group/sphere") ["linkedLights"])), set(["/group/group/light", "/group/group/light1"])) # Make sure changing sets updates the result of the expression evaluation attributes["attributes"]["linkedLights"]["value"].setValue("lightSet") self.assertEqual( set( map( str, evalNode["out"].attributes("/group/sphere") ["linkedLights"])), set(["/group/group/light", "/group/group/light1"])) lightSet["paths"].setValue( IECore.StringVectorData(['/group/group/light'])) self.assertEqual( set( map( str, evalNode["out"].attributes("/group/sphere") ["linkedLights"])), set(["/group/group/light"]))
def testFrame(self): script = Gaffer.ScriptNode() script["Sphere"] = GafferScene.Sphere() script["Sphere1"] = GafferScene.Sphere() script["Sphere"]["transform"]["translate"].setValue( IECore.V3f(-10, 0, 0)) script["Sphere1"]["transform"]["translate"].setValue( IECore.V3f(10, 0, 0)) script["Group"] = GafferScene.Group() script["Group"]["in"][0].setInput(script["Sphere"]["out"]) script["Group"]["in"][1].setInput(script["Sphere1"]["out"]) view = GafferUI.View.create(script["Group"]["out"]) self.assertTrue(isinstance(view, GafferSceneUI.SceneView)) self.assertTrue(view["in"].getInput().isSame(script["Group"]["out"])) def cameraContains(scene, objectPath): camera = view.viewportGadget().getCamera() screen = IECore.Box2f( IECore.V2f(0), IECore.V2f(camera.parameters()["resolution"].value)) worldBound = scene.bound(objectPath).transform( scene.fullTransform(objectPath)) for p in [ IECore.V3f(worldBound.min.x, worldBound.min.y, worldBound.min.z), IECore.V3f(worldBound.min.x, worldBound.min.y, worldBound.max.z), IECore.V3f(worldBound.min.x, worldBound.max.y, worldBound.max.z), IECore.V3f(worldBound.min.x, worldBound.max.y, worldBound.min.z), IECore.V3f(worldBound.max.x, worldBound.max.y, worldBound.min.z), IECore.V3f(worldBound.max.x, worldBound.min.y, worldBound.min.z), IECore.V3f(worldBound.max.x, worldBound.min.y, worldBound.max.z), IECore.V3f(worldBound.max.x, worldBound.max.y, worldBound.max.z), ]: rp = view.viewportGadget().worldToRasterSpace(p) if not screen.intersects(rp): return False return True self.assertFalse(cameraContains(script["Group"]["out"], "/group")) self.assertFalse( cameraContains(script["Group"]["out"], "/group/sphere")) self.assertFalse( cameraContains(script["Group"]["out"], "/group/sphere1")) view.frame(GafferScene.PathMatcher(["/group/sphere"]), direction=IECore.V3f(0, 0, 1)) self.assertFalse(cameraContains(script["Group"]["out"], "/group")) self.assertTrue(cameraContains(script["Group"]["out"], "/group/sphere")) self.assertFalse( cameraContains(script["Group"]["out"], "/group/sphere1")) view.frame(GafferScene.PathMatcher(["/group/sphere1"]), direction=IECore.V3f(0, 0, 1)) self.assertFalse(cameraContains(script["Group"]["out"], "/group")) self.assertFalse( cameraContains(script["Group"]["out"], "/group/sphere")) self.assertTrue( cameraContains(script["Group"]["out"], "/group/sphere1")) view.frame(GafferScene.PathMatcher(["/group/sp*"]), direction=IECore.V3f(0, 0, 1)) self.assertTrue(cameraContains(script["Group"]["out"], "/group")) self.assertTrue(cameraContains(script["Group"]["out"], "/group/sphere")) self.assertTrue( cameraContains(script["Group"]["out"], "/group/sphere1"))
def testSwitch(self): # Build a scene with a sphere, a plane, and # a filter switch controlling an attribute # assignment. Index 0 should assign to the # plane and index 1 should assign to the # sphere. script = Gaffer.ScriptNode() script["plane"] = GafferScene.Plane() script["sphere"] = GafferScene.Sphere() script["group"] = GafferScene.Group() script["group"]["in"][0].setInput(script["plane"]["out"]) script["group"]["in"][1].setInput(script["sphere"]["out"]) script["planeSet"] = GafferScene.Set() script["planeSet"]["paths"].setValue( IECore.StringVectorData(["/group/plane"])) script["planeSet"]["in"].setInput(script["group"]["out"]) script["attributes"] = GafferScene.StandardAttributes() script["attributes"]["attributes"]["visibility"]["enabled"].setValue( True) script["attributes"]["in"].setInput(script["planeSet"]["out"]) script["setFilter"] = GafferScene.SetFilter() script["setFilter"]["setExpression"].setValue("set") script["pathFilter"] = GafferScene.PathFilter() script["pathFilter"]["paths"].setValue( IECore.StringVectorData(["/group/sphere"])) script["switchFilter"] = GafferScene.FilterSwitch() script["switchFilter"]["in"][0].setInput(script["setFilter"]["out"]) script["switchFilter"]["in"][1].setInput(script["pathFilter"]["out"]) script["attributes"]["filter"].setInput(script["switchFilter"]["out"]) # Check that we get the assignments we expect for each index. self.assertEqual( len(script["attributes"]["out"].attributes("/group/plane")), 1) self.assertEqual( len(script["attributes"]["out"].attributes("/group/sphere")), 0) script["switchFilter"]["index"].setValue(1) self.assertEqual( len(script["attributes"]["out"].attributes("/group/plane")), 0) self.assertEqual( len(script["attributes"]["out"].attributes("/group/sphere")), 1) # Check that we get dirtiness signalled when changing the # index. cs = GafferTest.CapturingSlot(script["attributes"].plugDirtiedSignal()) self.assertEqual(len(cs), 0) script["switchFilter"]["index"].setValue(0) self.assertTrue(script["attributes"]["out"] in [c[0] for c in cs]) # Check that we get dirtiness signalled for the attributes # when changing the set used by the set filter. del cs[:] script["planeSet"]["paths"].setValue( IECore.StringVectorData(["/group", "/group/plane"])) self.assertTrue( script["attributes"]["out"]["attributes"] in [c[0] for c in cs]) # But also check that we don't get it signalled unnecessarily when # the set filter isn't the current index. script["switchFilter"]["index"].setValue(1) del cs[:] script["planeSet"]["paths"].setValue( IECore.StringVectorData(["/group/plane"])) self.assertFalse( script["attributes"]["out"]["attributes"] in [c[0] for c in cs]) # Now check that we can use expressions successfully on the index. script["expression"] = Gaffer.Expression() script["expression"].setExpression( 'parent["switchFilter"]["index"] = int( context.getFrame() )') with script.context(): script.context().setFrame(0) self.assertEqual( len(script["attributes"]["out"].attributes("/group/plane")), 1) self.assertEqual( len(script["attributes"]["out"].attributes("/group/sphere")), 0) script.context().setFrame(1) self.assertEqual( len(script["attributes"]["out"].attributes("/group/plane")), 0) self.assertEqual( len(script["attributes"]["out"].attributes("/group/sphere")), 1) # Now we have an expression based on the context, changing the upstream set should # always signal dirtiness for the attributes, because we don't know which index # the switch will use until we actually compute. del cs[:] script["planeSet"]["paths"].setValue( IECore.StringVectorData(["/group", "/group/plane"])) self.assertTrue( script["attributes"]["out"]["attributes"] in [c[0] for c in cs])