def test( self ) : sphere = GafferScene.Sphere() plane = GafferScene.Plane() group = GafferScene.Group() group["in"][0].setInput( sphere["out"] ) group["in"][1].setInput( plane["out"] ) plane2 = GafferScene.Plane() plane2["divisions"].setValue( IECore.V2i( 99, 99 ) ) # 10000 instances instancer = GafferScene.Instancer() instancer["in"].setInput( plane2["out"] ) instancer["parent"].setValue( "/plane" ) instancer["instance"].setInput( group["out"] ) filter = GafferScene.PathFilter() filter["paths"].setValue( IECore.StringVectorData( [ "/plane/instances/*1/group/plane" ] ) ) matchingPaths = GafferScene.PathMatcher() GafferScene.matchingPaths( filter, instancer["out"], matchingPaths ) self.assertEqual( len( matchingPaths.paths() ), 1000 ) self.assertEqual( matchingPaths.match( "/plane/instances/1/group/plane" ), GafferScene.Filter.Result.ExactMatch ) self.assertEqual( matchingPaths.match( "/plane/instances/1121/group/plane" ), GafferScene.Filter.Result.ExactMatch ) self.assertEqual( matchingPaths.match( "/plane/instances/1121/group/sphere" ), GafferScene.Filter.Result.NoMatch )
def testAdaptors( self ) : sphere = GafferScene.Sphere() def a() : result = GafferArnold.ArnoldAttributes() result["attributes"]["matte"]["enabled"].setValue( True ) result["attributes"]["matte"]["value"].setValue( True ) return result GafferScene.registerAdaptor( "Test", a ) sphere = GafferScene.Sphere() render = GafferArnold.ArnoldRender() render["in"].setInput( sphere["out"] ) 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" ) node = arnold.AiNodeLookUpByName( "/sphere" ) self.assertEqual( arnold.AiNodeGetBool( node, "matte" ), True )
def testDefaultCamera( self ) : o = GafferScene.StandardOptions() c1 = GafferScene.camera( o["out"] ) self.assertTrue( isinstance( c1, IECore.Camera ) ) o["options"]["renderCamera"]["enabled"].setValue( True ) c2 = GafferScene.camera( o["out"] ) self.assertEqual( c1, c2 )
def testSetExists( self ) : plane = GafferScene.Plane() plane["sets"].setValue( "A B" ) self.assertTrue( GafferScene.setExists( plane["out"], "A" ) ) self.assertTrue( GafferScene.setExists( plane["out"], "B" ) ) self.assertFalse( GafferScene.setExists( plane["out"], " " ) ) self.assertFalse( GafferScene.setExists( plane["out"], "" ) ) self.assertFalse( GafferScene.setExists( plane["out"], "C" ) )
def testMatchingPathsWithPathMatcher( self ) : s = GafferScene.Sphere() g = GafferScene.Group() g["in"][0].setInput( s["out"] ) g["in"][1].setInput( s["out"] ) g["in"][2].setInput( s["out"] ) f = GafferScene.PathMatcher( [ "/group/s*" ] ) m = GafferScene.PathMatcher() GafferScene.matchingPaths( f, g["out"], m ) self.assertEqual( set( m.paths() ), { "/group/sphere", "/group/sphere1", "/group/sphere2" } )
def testSetsNeedContextEntry( self ) : script = Gaffer.ScriptNode() script["light"] = GafferSceneTest.TestLight() script["light"]["sets"].setValue( "A B C" ) script["expression"] = Gaffer.Expression() script["expression"].setExpression( """parent["light"]["name"] = context["lightName"]""" ) for i in range( 0, 100 ) : with Gaffer.Context() as context : context["lightName"] = "light%d" % i GafferScene.sets( script["light"]["out"] )
def testSets( self ) : light = GafferSceneTest.TestLight() light["sets"].setValue( "A B C" ) sets = GafferScene.sets( light["out"] ) self.assertEqual( set( sets.keys() ), { "__lights", "A", "B", "C" } ) for n in sets.keys() : self.assertEqual( sets[n], light["out"].set( n ) ) self.assertFalse( sets[n].isSame( light["out"].set( n, _copy = False ) ) ) sets = GafferScene.sets( light["out"], _copy = False ) self.assertEqual( set( sets.keys() ), { "__lights", "A", "B", "C" } ) for n in sets.keys() : self.assertTrue( sets[n].isSame( light["out"].set( n, _copy = False ) ) )
def testAdaptors( self ) : s = Gaffer.ScriptNode() s["s"] = GafferScene.Sphere() def a() : result = GafferScene.SceneProcessor() result["__shader"], colorPlug = self._createConstantShader() colorPlug.setValue( imath.Color3f( 1, 0, 0 ) ) result["__assignment"] = GafferScene.ShaderAssignment() result["__assignment"]["in"].setInput( result["in"] ) result["__assignment"]["shader"].setInput( result["__shader"]["out"] ) result["out"].setInput( result["__assignment"]["out"] ) return result GafferScene.registerAdaptor( "Test", a ) s["o"] = GafferScene.Outputs() s["o"].addOutput( "beauty", IECoreScene.Display( "test", "ieDisplay", "rgba", { "driverType" : "ImageDisplayDriver", "handle" : "myLovelySphere", } ) ) s["o"]["in"].setInput( s["s"]["out"] ) s["r"] = self._createInteractiveRender() s["r"]["in"].setInput( s["o"]["out"] ) s["r"]["state"].setValue( s["r"].State.Running ) time.sleep( 0.5 ) # Render red sphere image = IECoreImage.ImageDisplayDriver.storedImage( "myLovelySphere" ) self.__assertColorsAlmostEqual( self.__color4fAtUV( image, imath.V2f( 0.5 ) ), imath.Color4f( 1, 0, 0, 1 ), delta = 0.01 )
def __update( self ) : self.__pendingUpdate = False assert( len( self.__scenePlugs ) <= 2 ) if self.__targetPaths is not None : paths = self.__targetPaths else : paths = self.getContext().get( "ui:scene:selectedPaths", [] ) paths = paths[:2] if len( self.__scenePlugs ) < 2 else paths[:1] if not paths : paths = [ "/" ] targets = [] for scene in self.__scenePlugs : for path in paths : if not GafferScene.exists( scene, path ) : # selection may not be valid for both scenes, # and we can't inspect invalid paths. path = None targets.append( self.Target( scene, path ) ) if next( (target.path for target in targets if target.path is not None), None ) is None : # all target paths have become invalid - if we're # in a popup window then close it. window = self.ancestor( _SectionWindow ) if window is not None : window.parent().removeChild( window ) with self.getContext() : for section in self.__sections : section.update( targets ) return False # remove idle callback
def test( self ) : sphere = GafferScene.Sphere() adaptors = GafferScene.createAdaptors() adaptors["in"].setInput( sphere["out"] ) self.assertScenesEqual( sphere["out"], adaptors["out"] ) self.assertSceneHashesEqual( sphere["out"], adaptors["out"] ) def a() : r = GafferScene.StandardAttributes() r["attributes"]["doubleSided"]["enabled"].setValue( True ) r["attributes"]["doubleSided"]["value"].setValue( False ) return r GafferScene.registerAdaptor( "Test", a ) adaptors = GafferScene.createAdaptors() adaptors["in"].setInput( sphere["out"] ) self.assertFalse( "doubleSided" in sphere["out"].attributes( "/sphere" ) ) self.assertTrue( "doubleSided" in adaptors["out"].attributes( "/sphere" ) ) self.assertEqual( adaptors["out"].attributes( "/sphere" )["doubleSided"].value, False ) GafferScene.deregisterAdaptor( "Test" ) adaptors = GafferScene.createAdaptors() adaptors["in"].setInput( sphere["out"] ) self.assertScenesEqual( sphere["out"], adaptors["out"] ) self.assertSceneHashesEqual( sphere["out"], adaptors["out"] )
def testSetFilter(self): sphere = GafferScene.Sphere() sphere["sets"].setValue("A") filter = GafferScene.SetFilter() filter["set"].setValue("A") isolate = GafferScene.Isolate() isolate["in"].setInput(sphere["out"]) isolate["filter"].setInput(filter["out"]) self.assertSceneValid(isolate["out"]) self.assertTrue(GafferScene.exists(isolate["out"], "/sphere"))
def __selectAffected(node, context): if isinstance(node, GafferScene.FilteredSceneProcessor): filter = node["filter"] scenes = [node["in"]] else: filter = node scenes = [] def walkOutputs(plug): for output in plug.outputs(): node = output.node() if isinstance(node, GafferScene.FilteredSceneProcessor) and output.isSame(node["filter"]): scenes.append(node["in"]) walkOutputs(output) walkOutputs(filter["out"]) pathMatcher = GafferScene.PathMatcher() with context: for scene in scenes: GafferScene.matchingPaths(filter, scene, pathMatcher) context["ui:scene:selectedPaths"] = IECore.StringVectorData(pathMatcher.paths())
def testExists( self ) : sphere = GafferScene.Sphere() plane = GafferScene.Plane() group = GafferScene.Group() group["in"][0].setInput( sphere["out"] ) group["in"][1].setInput( plane["out"] ) self.assertTrue( GafferScene.exists( group["out"], "/" ) ) self.assertTrue( GafferScene.exists( group["out"], "/group" ) ) self.assertTrue( GafferScene.exists( group["out"], "/group/sphere" ) ) self.assertTrue( GafferScene.exists( group["out"], "/group/plane" ) ) self.assertFalse( GafferScene.exists( group["out"], "/a" ) ) self.assertFalse( GafferScene.exists( group["out"], "/group2" ) ) self.assertFalse( GafferScene.exists( group["out"], "/group/sphere2" ) ) self.assertFalse( GafferScene.exists( group["out"], "/group/plane/child" ) )
def __sourceTarget( self, target ) : if isinstance( target.scene.node(), Gaffer.DependencyNode ) : sourceScene = target.scene.node().correspondingInput( target.scene ) if sourceScene is None : return None sourceScene = sourceScene.source() if sourceScene.node() == target.scene.node() : return None if not GafferScene.exists( sourceScene, target.path ) : return None return SceneInspector.Target( sourceScene, target.path ) return None
def __init__(self, name="FilterSwitch"): Gaffer.Switch.__init__(self, name) self.setup( GafferScene.FilterPlug(flags=Gaffer.Plug.Flags.Default & ~Gaffer.Plug.Flags.Cacheable))
def testLightLinkingAfterParameterUpdates(self): s = Gaffer.ScriptNode() s["s"] = GafferScene.Sphere() s["PathFilter"] = GafferScene.PathFilter("PathFilter") s["PathFilter"]["paths"].setValue(IECore.StringVectorData(['/sphere'])) s["ShaderAssignment"] = GafferScene.ShaderAssignment( "ShaderAssignment") s["ShaderAssignment"]["in"].setInput(s["s"]["out"]) s["ShaderAssignment"]["filter"].setInput(s["PathFilter"]["out"]) s["lambert"], _ = self._createMatteShader() s["ShaderAssignment"]["shader"].setInput(s["lambert"]["out"]) s["StandardAttributes"] = GafferScene.StandardAttributes( "StandardAttributes") s["StandardAttributes"]["attributes"]["linkedLights"][ "enabled"].setValue(True) s["StandardAttributes"]["attributes"]["linkedLights"][ "value"].setValue("defaultLights") s["StandardAttributes"]["filter"].setInput(s["PathFilter"]["out"]) s["StandardAttributes"]["in"].setInput(s["ShaderAssignment"]["out"]) s["Light"] = GafferArnold.ArnoldLight("skydome_light") s["Light"].loadShader("skydome_light") s["FloatToRGB"] = GafferArnold.ArnoldShader("FloatToRGB") s["FloatToRGB"].loadShader("float_to_rgb") s["FloatToRGB"]["parameters"]["r"].setValue(1.0) s["FloatToRGB"]["parameters"]["g"].setValue(1.0) s["FloatToRGB"]["parameters"]["b"].setValue(1.0) s["Light"]["parameters"]["color"].setInput(s["FloatToRGB"]["out"]) s["c"] = GafferScene.Camera() s["c"]["transform"]["translate"]["z"].setValue(2) s["group"] = GafferScene.Group() s["group"]["in"][0].setInput(s["StandardAttributes"]["out"]) s["group"]["in"][1].setInput(s["Light"]["out"]) s["group"]["in"][2].setInput(s["c"]["out"]) s["o"] = GafferScene.Outputs() s["o"].addOutput( "beauty", IECoreScene.Output("test", "ieDisplay", "rgba", { "driverType": "ImageDisplayDriver", "handle": "litByEnvironment", })) s["o"]["in"].setInput(s["group"]["out"]) s["so"] = GafferScene.StandardOptions() s["so"]["options"]["renderCamera"]["value"].setValue("/group/camera") s["so"]["options"]["renderCamera"]["enabled"].setValue(True) s["so"]["in"].setInput(s["o"]["out"]) s["r"] = self._createInteractiveRender() s["r"]["in"].setInput(s["so"]["out"]) # Start rendering and make sure the light is linked to the sphere s["r"]["state"].setValue(s["r"].State.Running) time.sleep(0.5) c = self._color3fAtUV( IECoreImage.ImageDisplayDriver.storedImage("litByEnvironment"), imath.V2f(0.5)) self.assertEqual(c, imath.Color3f(1.0)) # Change a value on the light causing it to get reconstructed in the # backend. At this point the light should still be linked to the sphere # and we should get the same result as before. s["Light"]['parameters']['shadow_density'].setValue(0.0) time.sleep(0.5) c = self._color3fAtUV( IECoreImage.ImageDisplayDriver.storedImage("litByEnvironment"), imath.V2f(0.5)) self.assertEqual(c, imath.Color3f(1.0))
def testCameraMotionBlur( self ) : s = Gaffer.ScriptNode() s["camera"] = GafferScene.Camera() s["attributes"] = GafferScene.StandardAttributes() s["attributes"]["in"].setInput( s["camera"]["out"] ) s["options"] = GafferScene.StandardOptions() s["options"]["in"].setInput( s["attributes"]["out"] ) s["options"]["options"]["renderCamera"]["enabled"].setValue( True ) s["options"]["options"]["renderCamera"]["value"].setValue( "/camera" ) s["render"] = GafferRenderMan.RenderManRender() s["render"]["in"].setInput( s["options"]["out"] ) s["render"]["mode"].setValue( "generate" ) s["render"]["ribFileName"].setValue( self.temporaryDirectory() + "/test.rib" ) s["fileName"].setValue( self.temporaryDirectory() + "/test.gfr" ) s.save() s["render"]["task"].execute() self.assertTrue( os.path.exists( self.temporaryDirectory() + "/test.rib" ) ) # camera motion off, we should have no motion statements r = "".join( file( self.temporaryDirectory() + "/test.rib" ).readlines() ) self.failIf( "MotionBegin" in r ) # camera motion on, we should have no motion statements s["options"]["options"]["cameraBlur"]["enabled"].setValue( True ) s["options"]["options"]["cameraBlur"]["value"].setValue( True ) s["render"]["task"].execute() r = "".join( file( self.temporaryDirectory() + "/test.rib" ).readlines() ) self.failUnless( "MotionBegin" in r ) # motion disabled on camera object, we should have no motion statements # even though motion blur is enabled in the globals. s["attributes"]["attributes"]["transformBlur"]["enabled"].setValue( True ) s["attributes"]["attributes"]["transformBlur"]["value"].setValue( False ) s["render"]["task"].execute() r = "".join( file( self.temporaryDirectory() + "/test.rib" ).readlines() ) self.failIf( "MotionBegin" in r ) # motion enabled on camera object, with extra samples specified. we should # have a motion statement with multiple segments s["attributes"]["attributes"]["transformBlur"]["value"].setValue( True ) s["attributes"]["attributes"]["transformBlurSegments"]["enabled"].setValue( True ) s["attributes"]["attributes"]["transformBlurSegments"]["value"].setValue( 5 ) s["render"]["task"].execute() def motionTimes( ribFileName ) : for line in file( ribFileName ).readlines() : if "MotionBegin" in line : times = line.partition( "[" )[2].partition( "]" )[0] times = times.strip().split() return [ float( t ) for t in times ] return [] self.assertEqual( len( motionTimes( self.temporaryDirectory() + "/test.rib" ) ), 6 ) # different shutter times s["attributes"]["attributes"]["transformBlurSegments"]["enabled"].setValue( False ) s["options"]["options"]["shutter"]["enabled"].setValue( True ) s["render"]["task"].execute() self.assertEqual( motionTimes( self.temporaryDirectory() + "/test.rib" ), [ 0.75, 1.25 ] ) s["options"]["options"]["shutter"]["value"].setValue( IECore.V2f( -0.1, 0.3 ) ) s["render"]["task"].execute() self.assertEqual( motionTimes( self.temporaryDirectory() + "/test.rib" ), [ 0.9, 1.3 ] )
def testCanShadeVertexInterpolatedPrimitiveVariablesAsUniform(self): s = Gaffer.ScriptNode() c = GafferScene.Cube() s.addChild(c) o = GafferOSL.OSLObject() s.addChild(o) f = GafferScene.PathFilter("PathFilter") s.addChild(f) f["paths"].setValue(IECore.StringVectorData(['/cube'])) o["filter"].setInput(f["out"]) # ensure the source position primitive variable interpolation is set to Vertex self.assertEqual(c["out"].object("/cube")['P'].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Vertex) o['in'].setInput(c["out"]) o['interpolation'].setValue( IECoreScene.PrimitiveVariable.Interpolation.Uniform) inPoint = GafferOSL.OSLShader("InPoint") s.addChild(inPoint) inPoint.loadShader("ObjectProcessing/InPoint") vectorAdd = GafferOSL.OSLShader("VectorAdd") s.addChild(vectorAdd) vectorAdd.loadShader("Maths/VectorAdd") vectorAdd["parameters"]["b"].setValue(imath.V3f(1, 2, 3)) vectorAdd["parameters"]["a"].setInput(inPoint["out"]["value"]) outPoint = GafferOSL.OSLShader("OutPoint") s.addChild(outPoint) outPoint.loadShader("ObjectProcessing/OutPoint") outPoint['parameters']['name'].setValue("P_copy") outPoint["parameters"]["value"].setInput(vectorAdd["out"]["out"]) outObject = GafferOSL.OSLShader("OutObject") s.addChild(outObject) outObject.loadShader("ObjectProcessing/OutObject") outObject["parameters"]["in0"].setInput( outPoint["out"]["primitiveVariable"]) o["shader"].setInput(outObject["out"]) cubeObject = s['OSLObject']['out'].object("/cube") self.assertTrue("P_copy" in cubeObject.keys()) self.assertEqual(cubeObject["P_copy"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Uniform) self.assertEqual(cubeObject["P_copy"].data[0], imath.V3f(0.0, 0.0, -0.5) + imath.V3f(1, 2, 3)) self.assertEqual(cubeObject["P_copy"].data[1], imath.V3f(0.5, 0.0, 0.0) + imath.V3f(1, 2, 3)) self.assertEqual(cubeObject["P_copy"].data[2], imath.V3f(0.0, 0.0, 0.5) + imath.V3f(1, 2, 3)) self.assertEqual(cubeObject["P_copy"].data[3], imath.V3f(-0.5, 0.0, 0.0) + imath.V3f(1, 2, 3)) self.assertEqual(cubeObject["P_copy"].data[4], imath.V3f(0.0, 0.5, 0.0) + imath.V3f(1, 2, 3)) self.assertEqual(cubeObject["P_copy"].data[5], imath.V3f(0.0, -0.5, 0.0) + imath.V3f(1, 2, 3))
def testDefaultName( self ) : s = GafferScene.SceneLoop() self.assertEqual( s.getName(), "SceneLoop" )
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"]))
# * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided with # the distribution. # # * Neither the name of John Haddon nor the names of # any other contributors to this software may be used to endorse or # promote products derived from this software without specific prior # written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ########################################################################## import GafferScene # Registering an adaptor by providing a callable that returns a SceneProcessor. # If it's necessary to set attributes on the node, provide a function object # that wraps a call to the class object. GafferScene.registerAdaptor( "LightLinking", GafferScene.EvaluateLightLinks )
def testCanReadAndWriteMatrices( self ) : s = Gaffer.ScriptNode() p = GafferScene.Plane() p["divisions"].setValue( imath.V2i( 2, 2 ) ) # 2x2 plane = 4 quads & 9 vertices s.addChild( p ) o = GafferOSL.OSLObject() s.addChild( o ) o['in'].setInput( p["out"] ) f = GafferScene.PathFilter( "PathFilter" ) s.addChild( f ) f["paths"].setValue( IECore.StringVectorData( ['/plane'] ) ) o["filter"].setInput( f["out"] ) outMatrix = GafferOSL.OSLShader( "OutMatrix" ) s.addChild( outMatrix ) outMatrix.loadShader( "ObjectProcessing/OutMatrix" ) outMatrix['parameters']['name'].setValue( "out_foo" ) inInt = GafferOSL.OSLShader( "InInt" ) s.addChild( inInt ) inInt.loadShader( "ObjectProcessing/InInt" ) oslCode = GafferOSL.OSLCode( "OSLCode" ) oslCode["code"].setValue( 'outMat = matrix(inIndex, inIndex, inIndex, inIndex, inIndex, inIndex, inIndex, inIndex, inIndex, inIndex, inIndex, inIndex, inIndex, inIndex, inIndex, inIndex);' ) s.addChild( oslCode ) inIntPlug = Gaffer.IntPlug( "inIndex", defaultValue = 0, flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) oslCode["parameters"].addChild( inIntPlug ) inIntPlug.setInput( inInt['out']['value'] ) oslCode["out"].addChild( Gaffer.M44fPlug( "outMat", direction = Gaffer.Plug.Direction.Out, defaultValue = imath.M44f( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) ) outMatrix["parameters"]["value"].setInput( oslCode['out']['outMat'] ) outObject = GafferOSL.OSLShader( "OutObject" ) s.addChild( outObject ) outObject.loadShader( "ObjectProcessing/OutObject" ) outObject["parameters"]["in0"].setInput( outMatrix["out"]["primitiveVariable"] ) o["shader"].setInput( outObject["out"]["out"] ) matrixPrimvar = o['out'].object( "/plane" )["out_foo"] for index, m in enumerate( matrixPrimvar.data ) : self.assertEqual( m, imath.M44f( index ) ) # check we can read the matrix44 primvar by reading and writing as out_foo2 inMatrix = GafferOSL.OSLShader( "InMatrix" ) s.addChild( inMatrix ) inMatrix.loadShader( "ObjectProcessing/InMatrix" ) inMatrix["parameters"]["name"].setValue( 'out_foo' ) outMatrix2 = GafferOSL.OSLShader( "OutMatrix" ) s.addChild( outMatrix2 ) outMatrix2.loadShader( "ObjectProcessing/OutMatrix" ) outMatrix2["parameters"]["name"].setValue( 'out_foo2' ) outMatrix2["parameters"]["value"].setInput( inMatrix["out"]["value"] ) outObject2 = GafferOSL.OSLShader( "OutObject" ) s.addChild( outObject2 ) outObject2.loadShader( "ObjectProcessing/OutObject" ) outObject2["parameters"]["in0"].setInput( outMatrix2["out"]["primitiveVariable"] ) o2 = GafferOSL.OSLObject() s.addChild(o2) o2['in'].setInput( o["out"] ) o2["shader"].setInput( outObject2["out"]["out"] ) o2["filter"].setInput( f["out"] ) matrixPrimvar = o2['out'].object( "/plane" )["out_foo2"] for index, m in enumerate( matrixPrimvar.data ) : self.assertEqual( m, imath.M44f( index ) )
def testAttributes( self ): p = GafferScene.Plane() a = GafferScene.CustomAttributes() a["attributes"].addChild( Gaffer.NameValuePlug( "a", 42.5 ) ) a["attributes"].addChild( Gaffer.NameValuePlug( "b", 12 ) ) a["attributes"].addChild( Gaffer.NameValuePlug( "c", True ) ) a["attributes"].addChild( Gaffer.NameValuePlug( "d", "blah" ) ) a["attributes"].addChild( Gaffer.NameValuePlug( "e", imath.V3f( 0.1, 0.2, 0.3 ) ) ) a["attributes"].addChild( Gaffer.NameValuePlug( "f", imath.V2f( 0.4, 0.5 ) ) ) a["attributes"].addChild( Gaffer.NameValuePlug( "g", imath.Color3f( 0.6, 0.7, 0.8 ) ) ) a["attributes"].addChild( Gaffer.NameValuePlug( "h", imath.M44f( 3 ) ) ) # There's no Color4f type in OSL, so We can't currently get the 4th component, but we can # get the first 3 a["attributes"].addChild( Gaffer.NameValuePlug( "i", imath.Color4f( 0.6, 0.7, 0.8, 0.9 ) ) ) a["in"].setInput( p["out"] ) o = GafferOSL.OSLObject() o["in"].setInput( p["out"] ) o["in"].setInput( a["out"] ) # shading network to output attributes as formatted string. inPoint = GafferOSL.OSLShader() inPoint.loadShader( "ObjectProcessing/InPoint" ) code = GafferOSL.OSLCode() code["out"].addChild( Gaffer.StringPlug( "testString", direction = Gaffer.Plug.Direction.Out ) ) o["primitiveVariables"].addChild( Gaffer.NameValuePlug( "testString", "" ) ) o["primitiveVariables"][0]["value"].setInput( code["out"]["testString"] ) f = GafferScene.PathFilter() f["paths"].setValue( IECore.StringVectorData( [ "/plane" ] ) ) a["filter"].setInput( f["out"] ) o["filter"].setInput( f["out"] ) code["code"].setValue( inspect.cleandoc( """ float a = -1; getattribute( "a", a ); float ax = -1; getattribute( "ax", ax ); int b = -1; getattribute( "b", b ); int c = -1; getattribute( "c", c ); string d = ""; getattribute( "d", d ); vector e = -1; getattribute( "e", e ); vector f = -1; getattribute( "f", f ); color g = -1; getattribute( "g", g ); matrix h = -1; getattribute( "h", h ); color i = -1; getattribute( "i", i ); testString = format( "TEST STRING : <%.2f><%.2f><%i><%i><%s><%.2f><%.2f><%.2f><%.2f %.2f %.2f %.2f><%.2f>", a, ax, b, c, d, e, f, g, h[0][0], h[0][1], h[1][0], h[1][1], i ); """ ) ) self.assertEqual( o["out"].object( "/plane" )["testString"].data[0], "TEST STRING : <-1.00><-1.00><-1><-1><><-1.00 -1.00 -1.00><-1.00 -1.00 -1.00><-1.00 -1.00 -1.00><-1.00 0.00 0.00 -1.00><-1.00 -1.00 -1.00>" ) o["useAttributes"].setValue( True ) self.assertEqual( o["out"].object( "/plane" )["testString"].data[0], "TEST STRING : <42.50><-1.00><12><1><blah><0.10 0.20 0.30><0.40 0.50 0.00><0.60 0.70 0.80><3.00 3.00 3.00 3.00><0.60 0.70 0.80>" ) # Try some bogus attributes code["code"].setValue( inspect.cleandoc( """ string badAttribute = "NOT FOUND"; getattribute( "badAttribute", badAttribute ); testString = badAttribute; """ ) ) a["attributes"].addChild( Gaffer.NameValuePlug( "badAttribute", imath.Box2f( imath.V2f( -0.5 ), imath.V2f( 0.5 ) ) ) ) # Check that bad attribute isn't found self.assertEqual( o["out"].object( "/plane" )["testString"].data[0], "NOT FOUND" ) while a["attributes"].children(): del a["attributes"][0] a["attributes"].addChild( Gaffer.NameValuePlug( "badAttribute", IECore.FloatVectorData([0,1,2]) ) ) self.assertEqual( o["out"].object( "/plane" )["testString"].data[0], "NOT FOUND" ) # Try something that isn't even data code["code"].setValue( inspect.cleandoc( """ string badAttribute = "NOT FOUND"; getattribute( "osl:surface", badAttribute ); testString = badAttribute; """ ) ) c = GafferOSL.OSLShader() c.loadShader( "Surface/Constant" ) s = GafferScene.ShaderAssignment() s["shader"].setInput( c["out"] ) s["filter"].setInput( f["out"] ) s["in"].setInput( p["out"] ) o["in"].setInput( s["out"] ) self.assertEqual( o["out"].object( "/plane" )["testString"].data[0], "NOT FOUND" )
def testTagFilteringPartialScene(self): s = IECore.SceneCache("/tmp/test.scc", IECore.IndexedIO.OpenMode.Write) sphereGroup = s.createChild("sphereGroup") sphereGroup.writeTags(["chrome"]) sphere = sphereGroup.createChild("sphere") sphere.writeObject(IECore.SpherePrimitive(), 0) planeGroup = s.createChild("planeGroup") plane = planeGroup.createChild("plane") plane.writeTags(["wood", "something"]) plane.writeObject( IECore.MeshPrimitive.createPlane( IECore.Box2f(IECore.V2f(-1), IECore.V2f(1))), 0) del s, sphereGroup, sphere, planeGroup, plane refreshCount = self.uniqueInt("/tmp/test.scc") # this one will load everything s1 = GafferScene.SceneReader() s1["fileName"].setValue("/tmp/test.scc") s1["refreshCount"].setValue(refreshCount) # this one should load just the sphere s2 = GafferScene.SceneReader() s2["fileName"].setValue("/tmp/test.scc") s2["refreshCount"].setValue(refreshCount) s2["tags"].setValue("chrome") # this one should load just the plane s3 = GafferScene.SceneReader() s3["fileName"].setValue("/tmp/test.scc") s3["refreshCount"].setValue(refreshCount) s3["tags"].setValue("wood") # check childnames self.assertEqual(set([str(x) for x in s1["out"].childNames("/")]), set(["sphereGroup", "planeGroup"])) self.assertEqual(set([str(x) for x in s2["out"].childNames("/")]), set(["sphereGroup"])) self.assertEqual(set([str(x) for x in s3["out"].childNames("/")]), set(["planeGroup"])) self.assertEqual( set([str(x) for x in s1["out"].childNames("/sphereGroup")]), set(["sphere"])) self.assertEqual( set([str(x) for x in s2["out"].childNames("/sphereGroup")]), set(["sphere"])) self.assertEqual( set([str(x) for x in s1["out"].childNames("/planeGroup")]), set(["plane"])) self.assertEqual( set([str(x) for x in s3["out"].childNames("/planeGroup")]), set(["plane"])) # check equality of the locations which are preserved self.assertPathsEqual(s1["out"], "/", s2["out"], "/", childPlugNamesToIgnore=("childNames", )) self.assertPathsEqual(s1["out"], "/", s3["out"], "/", childPlugNamesToIgnore=("childNames", )) self.assertPathsEqual(s1["out"], "/sphereGroup/sphere", s2["out"], "/sphereGroup/sphere", childPlugNamesToIgnore=("childNames", )) self.assertPathsEqual(s1["out"], "/sphereGroup/sphere", s2["out"], "/sphereGroup/sphere", childPlugNamesToIgnore=("childNames", )) self.assertPathsEqual(s1["out"], "/planeGroup/plane", s3["out"], "/planeGroup/plane", childPlugNamesToIgnore=("childNames", )) self.assertPathsEqual(s1["out"], "/planeGroup/plane", s3["out"], "/planeGroup/plane", childPlugNamesToIgnore=("childNames", ))
def testCanReadFromConstantPrimitiveVariables( self ) : s = Gaffer.ScriptNode() p = GafferScene.Plane() p["divisions"].setValue( imath.V2i( 2, 2 ) ) # 2x2 plane = 4 quads & 9 vertices s.addChild( p ) o = GafferOSL.OSLObject() s.addChild( o ) f = GafferScene.PathFilter( "PathFilter" ) s.addChild( f ) f["paths"].setValue( IECore.StringVectorData( [ '/plane' ] ) ) o["filter"].setInput( f["out"] ) pv = GafferScene.PrimitiveVariables( "PrimitiveVariables" ) s.addChild( pv ) pv["primitiveVariables"].addChild( Gaffer.CompoundDataPlug.MemberPlug( "member1", flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) ) pv["primitiveVariables"]["member1"].addChild( Gaffer.StringPlug( "name", defaultValue = '', flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) ) pv["primitiveVariables"]["member1"]["name"].setValue( 'const_foo' ) pv["primitiveVariables"]["member1"].addChild( Gaffer.FloatPlug( "value", defaultValue = 0.0, flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) ) pv["primitiveVariables"]["member1"]["value"].setValue( 1 ) pv["primitiveVariables"]["member1"].addChild( Gaffer.BoolPlug( "enabled", defaultValue = True, flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) ) pv["in"].setInput( p["out"] ) pv["filter"].setInput( f["out"] ) o['in'].setInput( pv["out"] ) o['interpolation'].setValue( IECoreScene.PrimitiveVariable.Interpolation.Vertex ) inConstFoo = GafferOSL.OSLShader( "InFloat" ) s.addChild( inConstFoo ) inConstFoo.loadShader( "ObjectProcessing/InFloat" ) inConstFoo['parameters']['name'].setValue('const_foo') outFloat = GafferOSL.OSLShader( "OutFloat" ) s.addChild( outFloat ) outFloat.loadShader( "ObjectProcessing/OutFloat" ) outFloat['parameters']['name'].setValue("out_foo") outFloat["parameters"]["value"].setInput( inConstFoo["out"]["value"] ) outObject = GafferOSL.OSLShader( "OutObject" ) s.addChild( outObject ) outObject.loadShader( "ObjectProcessing/OutObject" ) outObject["parameters"]["in0"].setInput( outFloat["out"]["primitiveVariable"] ) o["shader"].setInput( outObject["out"]["out"] ) planeObject = s['OSLObject']['out'].object( "/plane" ) self.assertTrue( "out_foo" in planeObject.keys() ) self.assertEqual( planeObject["out_foo"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Vertex) self.assertEqual( planeObject["out_foo"].data[0], 1) self.assertEqual( planeObject["out_foo"].data[1], 1) self.assertEqual( planeObject["out_foo"].data[2], 1) self.assertEqual( planeObject["out_foo"].data[3], 1) self.assertEqual( planeObject["out_foo"].data[4], 1) self.assertEqual( planeObject["out_foo"].data[5], 1) self.assertEqual( planeObject["out_foo"].data[6], 1) self.assertEqual( planeObject["out_foo"].data[7], 1) self.assertEqual( planeObject["out_foo"].data[8], 1)
def testDefault(self): eq = GafferScene.ExistenceQuery() self.assertTrue(eq["exists"].getValue() == False) self.assertTrue(eq["closestAncestor"].getValue() == "")
def testInvalidFileName(self): a = GafferScene.AlembicSource() a["fileName"].setValue("nonexistent.abc") self.assertRaises(RuntimeError, a["out"].childNames, "/")
def testCanShadeFaceVaryingInterpolatedPrimitiveVariablesAsVertex(self): s = Gaffer.ScriptNode() p = GafferScene.Plane() p["divisions"].setValue(imath.V2i( 2, 2)) # 2x2 plane = 4 quads & 9 vertices s.addChild(p) o = GafferOSL.OSLObject() s.addChild(o) f = GafferScene.PathFilter("PathFilter") s.addChild(f) f["paths"].setValue(IECore.StringVectorData(['/plane'])) o["filter"].setInput(f["out"]) # We're going to copy the FaceVarying UV primvar # into a Vertex Color3f primvar. Assert that the source # is indeed FaceVarying. self.assertEqual( p["out"].object("/plane")["uv"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.FaceVarying) o['in'].setInput(p["out"]) o['interpolation'].setValue( IECoreScene.PrimitiveVariable.Interpolation.Vertex) s["inUV"] = GafferOSL.OSLShader() s["inUV"].loadShader("ObjectProcessing/InVector") s["inUV"]["parameters"]["name"].setValue("uv") s["outColor"] = GafferOSL.OSLShader() s["outColor"].loadShader("ObjectProcessing/OutColor") s["outColor"]["parameters"]["value"].setInput( s["inUV"]["out"]["value"]) s["outColor"]["parameters"]["name"].setValue("c") s["outObject"] = GafferOSL.OSLShader() s["outObject"].loadShader("ObjectProcessing/OutObject") s["outObject"]["parameters"]["in0"].setInput( s["outColor"]["out"]["primitiveVariable"]) o["shader"].setInput(s["outObject"]["out"]) planeObject = s['OSLObject']['out'].object("/plane") self.assertIn("c", planeObject) self.assertEqual(planeObject["c"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Vertex) self.assertEqual(planeObject["c"].data[0], imath.Color3f(0.0, 0.0, 0.0)) self.assertEqual(planeObject["c"].data[1], imath.Color3f(0.5, 0.0, 0.0)) self.assertEqual(planeObject["c"].data[2], imath.Color3f(1.0, 0.0, 0.0)) self.assertEqual(planeObject["c"].data[3], imath.Color3f(0.0, 0.5, 0.0)) self.assertEqual(planeObject["c"].data[4], imath.Color3f(0.5, 0.5, 0.0)) self.assertEqual(planeObject["c"].data[5], imath.Color3f(1.0, 0.5, 0.0)) self.assertEqual(planeObject["c"].data[6], imath.Color3f(0.0, 1.0, 0.0)) self.assertEqual(planeObject["c"].data[7], imath.Color3f(0.5, 1.0, 0.0)) self.assertEqual(planeObject["c"].data[8], imath.Color3f(1.0, 1.0, 0.0))
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 testFrustum(self): c = GafferScene.Camera() self.assertAlmostEqual( c["out"].object("/camera").frustum( IECoreScene.Camera.FilmFit.Distort).max()[0] * 2.0, 2.0 * math.tan(0.5 * math.radians(c["fieldOfView"].getValue())), places=6) c["fieldOfView"].setValue(100) self.assertAlmostEqual( c["out"].object("/camera").frustum( IECoreScene.Camera.FilmFit.Distort).max()[0] * 2.0, 2.0 * math.tan(0.5 * math.radians(c["fieldOfView"].getValue())), places=6) self.assertAlmostEqual( c["out"].object("/camera").frustum( IECoreScene.Camera.FilmFit.Distort).max()[1] * 2.0, 2.0 * math.tan(0.5 * math.radians(c["fieldOfView"].getValue())), places=6) c["apertureAspectRatio"].setValue(3) self.assertAlmostEqual( c["out"].object("/camera").frustum( IECoreScene.Camera.FilmFit.Distort).max()[0] * 2.0, 2.0 * math.tan(0.5 * math.radians(c["fieldOfView"].getValue())), places=6) self.assertAlmostEqual( c["out"].object("/camera").frustum( IECoreScene.Camera.FilmFit.Distort).max()[1] * 2.0, 2.0 / 3.0 * math.tan(0.5 * math.radians(c["fieldOfView"].getValue())), places=6) c["perspectiveMode"].setValue( GafferScene.Camera.PerspectiveMode.ApertureFocalLength) self.assertNotAlmostEqual( c["out"].object("/camera").frustum( IECoreScene.Camera.FilmFit.Distort).max()[0] * 2.0, 2.0 * math.tan(0.5 * math.radians(c["fieldOfView"].getValue())), places=6) self.assertAlmostEqual(c["out"].object("/camera").frustum( IECoreScene.Camera.FilmFit.Distort).max()[0] * 2.0, c["aperture"].getValue()[0] / c["focalLength"].getValue(), places=6) c["aperture"].setValue(imath.V2f(100)) self.assertAlmostEqual(c["out"].object("/camera").frustum( IECoreScene.Camera.FilmFit.Distort).max()[0] * 2.0, c["aperture"].getValue()[0] / c["focalLength"].getValue(), places=6) c["focalLength"].setValue(200) self.assertAlmostEqual(c["out"].object("/camera").frustum( IECoreScene.Camera.FilmFit.Distort).max()[0] * 2.0, c["aperture"].getValue()[0] / c["focalLength"].getValue(), places=6) c["projection"].setValue("orthographic") self.assertNotAlmostEqual(c["out"].object("/camera").frustum( IECoreScene.Camera.FilmFit.Distort).max()[0] * 2.0, c["aperture"].getValue()[0] / c["focalLength"].getValue(), places=6) self.assertEqual( c["out"].object("/camera").frustum( IECoreScene.Camera.FilmFit.Distort).max() * 2.0, c["orthographicAperture"].getValue()) c["orthographicAperture"].setValue(imath.V2f(0.1, 12)) self.assertEqual( c["out"].object("/camera").frustum( IECoreScene.Camera.FilmFit.Distort).max() * 2.0, c["orthographicAperture"].getValue())
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.exists(isolate["out"], "/group/model1/sphere")) self.assertTrue(GafferScene.exists(isolate["out"], "/group/model1/light")) self.assertTrue(GafferScene.exists(isolate["out"], "/group/model1")) self.assertFalse(GafferScene.exists(isolate["out"], "/group/model2/sphere")) self.assertFalse(GafferScene.exists(isolate["out"], "/group/model2")) self.assertFalse(GafferScene.exists(isolate["out"], "/group/light")) self.assertFalse(GafferScene.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.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.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 testInPlug(self): c = GafferScene.CollectScenes() self.assertIsInstance(c["in"], GafferScene.ScenePlug)
def __selectAffected( node, context ) : with context : pathMatcher = GafferScene.PathMatcher() GafferScene.matchingPaths( node["filter"], node["in"], pathMatcher ) context["ui:scene:selectedPaths"] = IECore.StringVectorData( pathMatcher.paths() )
def tearDown( self ) : GafferSceneTest.SceneTestCase.tearDown( self ) GafferScene.deregisterAdaptor( "Test" )
def _run( self, args ) : # Run the gui startup files so the images we grab are representative # of the layouts and configuration of the gui app. self._executeStartupFiles( "gui" ) GafferUI.ScriptWindow.connect( self.root() ) # Load the specified gfr file. script = Gaffer.ScriptNode() if args["script"].value : script["fileName"].setValue( os.path.abspath( args["script"].value ) ) script.load() self.root()["scripts"].addChild( script ) # Choose the widget we'll grab by default. This can be overridden # by the command files below by calling `application.setGrabWidget()`. scriptWindow = GafferUI.ScriptWindow.acquire( script ) self.setGrabWidget( scriptWindow ) # Execute any commands we've been asked to, exposing the application # and script as variables. self.__waitForIdle() d = { "application" : self, "script" : script, } if args["command"].value : exec( args["command"].value, d, d ) if args["commandFile"].value : execfile( args["commandFile"].value, d, d ) # Select any nodes we've been asked to. for name in args["selection"] : script.selection().add( script.descendant( name ) ) # Override the default grab widget if requested by # the editor command line flag. if args["editor"].value : editor = args["editor"].value if "." not in editor : editor = "GafferUI." + editor editorPartition = editor.rpartition( "." ) editor = getattr( __import__( editorPartition[0] ), editorPartition[2] ) editors = scriptWindow.getLayout().editors( editor ) if not editors : IECore.msg( IECore.Msg.Level.Error, "screengrab", "Unable to find an editor of type \"%s\"" % editor ) return 1 if args["panel"].value : self.setGrabWidget( editors[0].parent() ) else : self.setGrabWidget( editors[0] ) editors[0].reveal() # Set up some default framing for the node graphs. self.__waitForIdle() for nodeGraph in scriptWindow.getLayout().editors( GafferUI.NodeGraph ) : if args["nodeGraph"]["frame"] : nodeGraph.frame( [ script.descendant( n ) for n in args["nodeGraph"]["frame"] ] ) else : nodeGraph.frame( script.children( Gaffer.Node ) ) # Set up the NodeEditors as requested. for nodeEditor in scriptWindow.getLayout().editors( GafferUI.NodeEditor ) : for name in args["nodeEditor"]["reveal"] : plugValueWidget = nodeEditor.nodeUI().plugValueWidget( script.descendant( name ) ) plugValueWidget.reveal() if args["nodeEditor"]["grab"].value : grabWidget = nodeEditor.nodeUI().plugValueWidget( script.descendant( args["nodeEditor"]["grab"].value ) ) grabWidget = grabWidget.ancestor( GafferUI.PlugWidget ) or grabWidget grabWidget.reveal() self.setGrabWidget( grabWidget ) # Set up the ScriptEditors as requested. for scriptEditor in scriptWindow.getLayout().editors( GafferUI.ScriptEditor ) : if args["scriptEditor"]["execute"].value : scriptEditor.inputWidget().setText( args["scriptEditor"]["execute"].value ) scriptEditor.inputWidget()._qtWidget().selectAll() scriptEditor.execute() # Set up the Viewers as requested. for viewer in scriptWindow.getLayout().editors( GafferUI.Viewer ) : if isinstance( viewer.view(), GafferSceneUI.SceneView ) : viewer.view()["minimumExpansionDepth"].setValue( args["viewer"]["minimumExpansionDepth"].value ) if args["viewer"]["framedObjects"] : bound = IECore.Box3f() for path in args["viewer"]["framedObjects"] : objectBound = viewer.view()["in"].bound( path ) objectFullTransform = viewer.view()["in"].fullTransform( path ) bound.extendBy( objectBound.transform( objectFullTransform ) ) viewer.view().viewportGadget().frame( bound, args["viewer"]["viewDirection"].value.normalized() ) del viewer # Set up the scene expansion and selection. pathsToExpand = GafferScene.PathMatcher() for path in list( args["scene"]["fullyExpandedPaths"] ) + list( args["scene"]["expandedPaths"] ) : # Add paths and all their ancestors. while path : pathsToExpand.addPath( path ) path = path.rpartition( "/" )[0] fullyExpandedPathsFilter = GafferScene.PathFilter() fullyExpandedPathsFilter["paths"].setValue( IECore.StringVectorData( [ path + "/..." for path in args["scene"]["fullyExpandedPaths"] ] ) ) for node in script.selection() : for scenePlug in [ p for p in node.children( GafferScene.ScenePlug ) if p.direction() == Gaffer.Plug.Direction.Out ] : GafferScene.matchingPaths( fullyExpandedPathsFilter, scenePlug, pathsToExpand ) script.context()["ui:scene:expandedPaths"] = GafferScene.PathMatcherData( pathsToExpand ) script.context()["ui:scene:selectedPaths"] = args["scene"]["selectedPaths"] # Write the image, creating a directory for it if necessary. self.__waitForIdle() imageDir = os.path.dirname( args["image"].value ) if imageDir and not os.path.isdir( imageDir ) : IECore.msg( IECore.Msg.Level.Info, "screengrab", "Creating target directory [ %s ]" % imageDir ) os.makedirs( imageDir ) pixmap = QtGui.QPixmap.grabWindow( self.getGrabWidget()._qtWidget().winId() ) IECore.msg( IECore.Msg.Level.Info, "screengrab", "Writing image [ %s ]" % args["image"].value ) pixmap.save( args["image"].value ) # Remove the script and any reference to the grab widget up so # we can shut down cleanly. self.root()["scripts"].clearChildren() self.setGrabWidget( None ) return 0
def testTransform(self): p = GafferScene.Plane() p["transform"]["translate"].setValue(imath.V3f(2, 0, 0)) o = GafferOSL.OSLObject() o["in"].setInput(p["out"]) # shading network to swap x and y inPoint = GafferOSL.OSLShader() inPoint.loadShader("ObjectProcessing/InPoint") code = GafferOSL.OSLCode() code["parameters"].addChild(Gaffer.V3fPlug("in")) code["out"].addChild( Gaffer.Color3fPlug("transformed", direction=Gaffer.Plug.Direction.Out)) code["out"].addChild( Gaffer.Color3fPlug("transformedBack", direction=Gaffer.Plug.Direction.Out)) code["code"].setValue( 'transformed = transform( "world", point( in ) );\ntransformedBack = transform( "world", "object", point( transformed ) );' ) code["parameters"]["in"].setInput(inPoint["out"]["value"]) outTransformed = GafferOSL.OSLShader() outTransformed.loadShader("ObjectProcessing/OutColor") outTransformed["parameters"]["name"].setValue('transformed') outTransformed["parameters"]["value"].setInput( code["out"]["transformed"]) outTransformedBack = GafferOSL.OSLShader() outTransformedBack.loadShader("ObjectProcessing/OutColor") outTransformedBack["parameters"]["name"].setValue('transformedBack') outTransformedBack["parameters"]["value"].setInput( code["out"]["transformedBack"]) primVarShader = GafferOSL.OSLShader() primVarShader.loadShader("ObjectProcessing/OutObject") primVarShader["parameters"]["in0"].setInput( outTransformed["out"]["primitiveVariable"]) primVarShader["parameters"]["in1"].setInput( outTransformedBack["out"]["primitiveVariable"]) o["shader"].setInput(primVarShader["out"]) filter = GafferScene.PathFilter() filter["paths"].setValue(IECore.StringVectorData(["/plane"])) o["filter"].setInput(filter["out"]) self.assertEqual( o["out"].object("/plane")["transformed"].data, IECore.Color3fVectorData([ imath.Color3f(1.5, -0.5, 0), imath.Color3f(2.5, -0.5, 0), imath.Color3f(1.5, 0.5, 0), imath.Color3f(2.5, 0.5, 0) ])) self.assertEqual( o["out"].object("/plane")["transformedBack"].data, IECore.Color3fVectorData([ imath.Color3f(-0.5, -0.5, 0), imath.Color3f(0.5, -0.5, 0), imath.Color3f(-0.5, 0.5, 0), imath.Color3f(0.5, 0.5, 0) ]))
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 __init__(self, name="SceneSwitch"): Gaffer.Switch.__init__(self, name) self.setup(GafferScene.ScenePlug())
def test(self): l = GafferSceneTest.TestLight() l["parameters"]["intensity"].setValue(imath.Color3f(1)) t = GafferScene.LightTweaks() t["in"].setInput(l["out"]) self.assertSceneValid(t["out"]) self.assertScenesEqual(t["out"], l["out"]) self.assertSceneHashesEqual(t["out"], l["out"]) self.assertEqual( l["out"].attributes("/light")["light"] [0].parameters["intensity"].value, imath.Color3f(1)) f = GafferScene.PathFilter() f["paths"].setValue(IECore.StringVectorData(["/light"])) t["filter"].setInput(f["out"]) self.assertSceneValid(t["out"]) self.assertScenesEqual(t["out"], l["out"]) self.assertSceneHashesEqual(t["out"], l["out"]) intensityTweak = GafferScene.TweakPlug("intensity", imath.Color3f(1, 0, 0)) t["tweaks"].addChild(intensityTweak) self.assertSceneValid(t["out"]) self.assertEqual( t["out"].attributes("/light")["light"] [0].parameters["intensity"].value, imath.Color3f(1, 0, 0)) intensityTweak["value"].setValue(imath.Color3f(100)) self.assertEqual( t["out"].attributes("/light")["light"] [0].parameters["intensity"].value, imath.Color3f(100)) intensityTweak["enabled"].setValue(False) self.assertEqual( t["out"].attributes("/light")["light"] [0].parameters["intensity"].value, imath.Color3f(1)) intensityTweak["enabled"].setValue(True) intensityTweak["mode"].setValue(intensityTweak.Mode.Add) self.assertEqual( t["out"].attributes("/light")["light"] [0].parameters["intensity"].value, imath.Color3f(101)) intensityTweak["mode"].setValue(intensityTweak.Mode.Subtract) intensityTweak["value"].setValue(imath.Color3f(0.1, 0.2, 0.3)) self.assertEqual( t["out"].attributes("/light")["light"] [0].parameters["intensity"].value, imath.Color3f(0.9, 0.8, 0.7)) intensityTweak["mode"].setValue(intensityTweak.Mode.Multiply) l["parameters"]["intensity"].setValue(imath.Color3f(2)) self.assertEqual( t["out"].attributes("/light")["light"] [0].parameters["intensity"].value, imath.Color3f(0.2, 0.4, 0.6)) t["type"].setValue("") self.assertScenesEqual(t["out"], l["out"])
def testStaticHashes( self ) : s = IECoreScene.SceneCache( "/tmp/test.scc", IECore.IndexedIO.OpenMode.Write ) movingGroup = s.createChild( "movingGroup" ) movingGroup.writeTransform( IECore.M44dData( imath.M44d().translate( imath.V3d( 1, 0, 0 ) ) ), 0.0 ) movingGroup.writeTransform( IECore.M44dData( imath.M44d().translate( imath.V3d( 2, 0, 0 ) ) ), 1.0 ) deformingSphere = movingGroup.createChild( "deformingSphere" ) deformingSphere.writeObject( IECoreScene.SpherePrimitive(), 0 ) deformingSphere.writeObject( IECoreScene.SpherePrimitive( 2 ), 1 ) staticGroup = s.createChild( "staticGroup" ) staticGroup.writeTransform( IECore.M44dData( imath.M44d().translate( imath.V3d( 1, 0, 0 ) ) ), 0.0 ) staticSphere = staticGroup.createChild( "staticSphere" ) staticSphere.writeObject( IECoreScene.SpherePrimitive(), 0 ) del s, movingGroup, deformingSphere, staticGroup, staticSphere s = GafferScene.SceneReader() s["fileName"].setValue( "/tmp/test.scc" ) s["refreshCount"].setValue( self.uniqueInt( "/tmp/test.scc" ) ) # account for our changing of file contents between tests t = Gaffer.TimeWarp() t.setup( GafferScene.ScenePlug() ) t["in"].setInput( s["out"] ) t["offset"].setValue( 1 ) self.assertPathHashesNotEqual( s["out"], "/movingGroup", t["out"], "/movingGroup", checks = { "transform", "bound" } ) self.assertPathHashesNotEqual( s["out"], "/movingGroup/deformingSphere", t["out"], "/movingGroup/deformingSphere", checks = { "bound", "object" } ) self.assertPathHashesEqual( s["out"], "/movingGroup", t["out"], "/movingGroup", checks = { "attributes", "object" } ) self.assertPathHashesEqual( s["out"], "/movingGroup/deformingSphere", t["out"], "/movingGroup/deformingSphere", checks = { "attributes" } ) self.assertPathHashesEqual( s["out"], "/staticGroup", t["out"], "/staticGroup", checks = { "object", "transform", "attributes", "bound" } ) self.assertPathHashesEqual( s["out"], "/staticGroup/staticSphere", t["out"], "/staticGroup/staticSphere", checks = { "object", "transform", "attributes", "bound" } )
def testComputeSetInEmptyScene( self ) : # this used to cause a crash: r1 = GafferScene.SceneReader() self.assertEqual( r1["out"].set( "blahblah" ).value.paths(), [] )
def testAlembic( self ) : r = GafferScene.SceneReader() r["fileName"].setValue( os.path.dirname( __file__ ) + "/alembicFiles/cube.abc" ) self.assertSceneValid( r["out"] )
def testEditSubdivisionAttributes(self): script = Gaffer.ScriptNode() script["cube"] = GafferScene.Cube() script["cube"]["dimensions"].setValue(imath.V3f(2)) script["meshType"] = GafferScene.MeshType() script["meshType"]["in"].setInput(script["cube"]["out"]) script["meshType"]["meshType"].setValue("catmullClark") script["attributes"] = GafferArnold.ArnoldAttributes() script["attributes"]["in"].setInput(script["meshType"]["out"]) script["attributes"]["attributes"]["subdivIterations"][ "enabled"].setValue(True) script["outputs"] = GafferScene.Outputs() script["outputs"].addOutput( "beauty", IECoreScene.Output("test", "ieDisplay", "rgba", { "driverType": "ImageDisplayDriver", "handle": "subdivisionTest", })) script["outputs"]["in"].setInput(script["attributes"]["out"]) script["objectToImage"] = GafferImage.ObjectToImage() script["imageStats"] = GafferImage.ImageStats() script["imageStats"]["in"].setInput(script["objectToImage"]["out"]) script["imageStats"]["channels"].setValue( IECore.StringVectorData(["R", "G", "B", "A"])) script["imageStats"]["area"].setValue( imath.Box2i(imath.V2i(0), imath.V2i(640, 480))) script["options"] = GafferScene.StandardOptions() script["options"]["in"].setInput(script["outputs"]["out"]) script["options"]["options"]["filmFit"]["enabled"].setValue(True) script["options"]["options"]["filmFit"]["value"].setValue( IECoreScene.Camera.FilmFit.Fit) script["render"] = self._createInteractiveRender() script["render"]["in"].setInput(script["options"]["out"]) # Render the cube with one level of subdivision. Check we get roughly the # alpha coverage we expect. script["render"]["state"].setValue(script["render"].State.Running) time.sleep(1) script["objectToImage"]["object"].setValue( IECoreImage.ImageDisplayDriver.storedImage("subdivisionTest")) self.assertAlmostEqual(script["imageStats"]["average"][3].getValue(), 0.381, delta=0.001) # Now up the number of subdivision levels. The alpha coverage should # increase as the shape tends towards the limit surface. script["attributes"]["attributes"]["subdivIterations"][ "value"].setValue(4) time.sleep(1) script["objectToImage"]["object"].setValue( IECoreImage.ImageDisplayDriver.storedImage("subdivisionTest")) self.assertAlmostEqual(script["imageStats"]["average"][3].getValue(), 0.424, delta=0.001)
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.assertTrue(tool.selection().transformPlug is None) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), GafferScene.PathMatcher(["/group/plane"])) self.assertEqual(tool.selection().path, "/group/plane") self.assertEqual(tool.selection().context, view.getContext()) self.assertTrue(tool.selection().upstreamScene.isSame( script["plane"]["out"])) self.assertEqual(tool.selection().upstreamPath, "/plane") self.assertTrue(tool.selection().transformPlug.isSame( script["plane"]["transform"])) self.assertEqual(tool.selection().transformSpace, IECore.M44f()) GafferSceneUI.ContextAlgo.setSelectedPaths( view.getContext(), GafferScene.PathMatcher(["/group"])) self.assertEqual(tool.selection().path, "/group") self.assertEqual(tool.selection().context, view.getContext()) self.assertTrue(tool.selection().upstreamScene.isSame( script["group"]["out"])) self.assertEqual(tool.selection().upstreamPath, "/group") self.assertTrue(tool.selection().transformPlug.isSame( script["group"]["transform"])) self.assertEqual(tool.selection().transformSpace, IECore.M44f()) script["transformFilter"]["paths"].setValue( IECore.StringVectorData(["/group"])) self.assertTrue(tool.selection().transformPlug.isSame( script["transform"]["transform"])) script["transformFilter"]["enabled"].setValue(False) self.assertTrue(tool.selection().transformPlug.isSame( script["group"]["transform"])) script["transformFilter"]["enabled"].setValue(True) self.assertEqual(tool.selection().path, "/group") self.assertEqual(tool.selection().context, view.getContext()) self.assertTrue(tool.selection().upstreamScene.isSame( script["transform"]["out"])) self.assertEqual(tool.selection().upstreamPath, "/group") self.assertTrue(tool.selection().transformPlug.isSame( script["transform"]["transform"])) self.assertEqual(tool.selection().transformSpace, IECore.M44f()) script["transform"]["enabled"].setValue(False) self.assertTrue(tool.selection().transformPlug.isSame( script["group"]["transform"]))
def testWedge( self ) : s = Gaffer.ScriptNode() s["sphere"] = GafferScene.Sphere() s["sphere"]["sets"].setValue( "${wedge:value}" ) s["filter"] = GafferScene.SetFilter() s["filter"]["set"].setValue( "hidden" ) s["attributes"] = GafferScene.StandardAttributes() s["attributes"]["attributes"]["visibility"]["enabled"].setValue( True ) s["attributes"]["attributes"]["visibility"]["value"].setValue( False ) s["attributes"]["filter"].setInput( s["filter"]["out"] ) s["attributes"]["in"].setInput( s["sphere"]["out"] ) s["outputs"] = GafferScene.Outputs() s["outputs"].addOutput( "beauty", IECore.Display( self.temporaryDirectory() + "/${wedge:value}.tif", "tiff", "rgba", { } ) ) s["outputs"]["in"].setInput( s["attributes"]["out"] ) s["render"] = GafferRenderMan.RenderManRender() s["render"]["ribFileName"].setValue( self.temporaryDirectory() + "/test.rib" ) s["render"]["in"].setInput( s["outputs"]["out"] ) s["wedge"] = GafferDispatch.Wedge() s["wedge"]["mode"].setValue( int( s["wedge"].Mode.StringList ) ) s["wedge"]["strings"].setValue( IECore.StringVectorData( [ "visible", "hidden" ] ) ) s["wedge"]["preTasks"][0].setInput( s["render"]["task"] ) s["fileName"].setValue( self.temporaryDirectory() + "/test.gfr" ) s.save() dispatcher = GafferDispatch.LocalDispatcher() dispatcher["jobsDirectory"].setValue( self.temporaryDirectory() + "/testJobDirectory" ) dispatcher["framesMode"].setValue( GafferDispatch.Dispatcher.FramesMode.CurrentFrame ) dispatcher["executeInBackground"].setValue( False ) dispatcher.dispatch( [ s["wedge"] ] ) hidden = GafferImage.ImageReader() hidden["fileName"].setValue( self.temporaryDirectory() + "/hidden.tif" ) visible = GafferImage.ImageReader() visible["fileName"].setValue( self.temporaryDirectory() + "/visible.tif" ) hiddenStats = GafferImage.ImageStats() hiddenStats["in"].setInput( hidden["out"] ) hiddenStats["regionOfInterest"].setValue( hidden["out"]["format"].getValue().getDisplayWindow() ) visibleStats = GafferImage.ImageStats() visibleStats["in"].setInput( visible["out"] ) visibleStats["regionOfInterest"].setValue( visible["out"]["format"].getValue().getDisplayWindow() ) self.assertLess( hiddenStats["average"].getValue()[0], 0.05 ) self.assertGreater( visibleStats["average"].getValue()[0], .35 )
__cameraSummary, "namesAndLabels": ( ("render:camera", "Camera"), ("render:resolution", "Resolution"), ), }, { "label": "Motion Blur", "summary": __motionBlurSummary, "namesAndLabels": ( ("render:cameraBlur", "Camera"), ("render:transformBlur", "Transform"), ("render:deformationBlur", "Deformation"), ("render:shutter", "Shutter"), ), }, ), ) GafferUI.PlugValueWidget.registerCreator( GafferScene.StandardOptions.staticTypeId(), "options.renderCamera.value", lambda plug: GafferUI.PathPlugValueWidget( plug, path=GafferScene.ScenePath(plug.node()["in"], plug.node().scriptNode().context(), "/"), ), )
def testConstruct(self): p = GafferScene.Camera() self.assertEqual(p.getName(), "Camera") self.assertEqual(p["name"].getValue(), "camera")
def __init__(self, name="ArnoldTextureBake"): GafferDispatch.TaskNode.__init__(self, name) self["in"] = GafferScene.ScenePlug() self["filter"] = GafferScene.FilterPlug() self["bakeDirectory"] = Gaffer.StringPlug("bakeDirectory", defaultValue="") self["defaultFileName"] = Gaffer.StringPlug( "defaultFileName", defaultValue="${bakeDirectory}/<AOV>/<AOV>.<UDIM>.exr") self["defaultResolution"] = Gaffer.IntPlug("defaultResolution", defaultValue=512) self["uvSet"] = Gaffer.StringPlug("uvSet", defaultValue='uv') self["normalOffset"] = Gaffer.FloatPlug("offset", defaultValue=0.1) self["aovs"] = Gaffer.StringPlug("aovs", defaultValue='beauty:RGBA') self["tasks"] = Gaffer.IntPlug("tasks", defaultValue=1) self["cleanupIntermediateFiles"] = Gaffer.BoolPlug( "cleanupIntermediateFiles", defaultValue=True) self["applyMedianFilter"] = Gaffer.BoolPlug("applyMedianFilter", Gaffer.Plug.Direction.In, False) self["medianRadius"] = Gaffer.IntPlug("medianRadius", Gaffer.Plug.Direction.In, 1) # Set up connection to preTasks beforehand self["__PreTaskList"] = GafferDispatch.TaskList() self["__PreTaskList"]["preTasks"].setInput(self["preTasks"]) self["__CleanPreTasks"] = Gaffer.DeleteContextVariables() self["__CleanPreTasks"].setup(GafferDispatch.TaskNode.TaskPlug()) self["__CleanPreTasks"]["in"].setInput(self["__PreTaskList"]["task"]) self["__CleanPreTasks"]["variables"].setValue( "BAKE_WEDGE:index BAKE_WEDGE:value_unused") # First, setup python commands which will dispatch a chunk of a render or image tasks as # immediate execution once they reach the farm - this allows us to run multiple tasks in # one farm process. self["__RenderDispatcher"] = GafferDispatch.PythonCommand() self["__RenderDispatcher"]["preTasks"][0].setInput( self["__CleanPreTasks"]["out"]) self["__RenderDispatcher"]["command"].setValue( inspect.cleandoc(""" import GafferDispatch # We need to access frame and "BAKE_WEDGE:index" so that the hash of render varies with the wedge index, # so we might as well print what we're doing IECore.msg( IECore.MessageHandler.Level.Info, "Bake Process", "Dispatching render task index %i for frame %i" % ( context["BAKE_WEDGE:index"], context.getFrame() ) ) d = GafferDispatch.LocalDispatcher() d.dispatch( [ self.parent()["__bakeDirectoryContext"] ] ) """)) self["__ImageDispatcher"] = GafferDispatch.PythonCommand() self["__ImageDispatcher"]["preTasks"][0].setInput( self["__RenderDispatcher"]["task"]) self["__ImageDispatcher"]["command"].setValue( inspect.cleandoc(""" import GafferDispatch # We need to access frame and "BAKE_WEDGE:index" so that the hash of render varies with the wedge index, # so we might as well print what we're doing IECore.msg( IECore.MessageHandler.Level.Info, "Bake Process", "Dispatching image task index %i for frame %i" % ( context["BAKE_WEDGE:index"], context.getFrame() ) ) d = GafferDispatch.LocalDispatcher() d.dispatch( [ self.parent()["__CleanUpSwitch"] ] ) """)) # Connect through the dispatch settings to the render dispatcher # ( The image dispatcher runs much quicker, and should be OK using default settings ) self["__RenderDispatcher"]["dispatcher"].setInput(self["dispatcher"]) # Set up variables so the dispatcher knows that the render and image dispatches depend on # the file paths ( in case they are varying in a wedge ) for redispatch in [ self["__RenderDispatcher"], self["__ImageDispatcher"] ]: redispatch["variables"].addMember("bakeDirectory", "", "bakeDirectoryVar") redispatch["variables"].addMember("defaultFileName", "", "defaultFileNameVar") # Connect the variables via an expression so that get expanded ( this also means that # if you put #### in a filename you will get per frame tasks, because the hash will depend # on frame number ) self["__DispatchVariableExpression"] = Gaffer.Expression() self["__DispatchVariableExpression"].setExpression( inspect.cleandoc(""" parent["__RenderDispatcher"]["variables"]["bakeDirectoryVar"]["value"] = parent["bakeDirectory"] parent["__RenderDispatcher"]["variables"]["defaultFileNameVar"]["value"] = parent["defaultFileName"] parent["__ImageDispatcher"]["variables"]["bakeDirectoryVar"]["value"] = parent["bakeDirectory"] parent["__ImageDispatcher"]["variables"]["defaultFileNameVar"]["value"] = parent["defaultFileName"] """), "python") # Wedge based on tasks into the overall number of tasks to run. Note that we don't know how # much work each task will do until we actually run the render tasks ( this is when scene # expansion happens ). Because we must group all tasks that write to the same file into the # same task batch, if tasks is a large number, some tasks batches could end up empty self["__MainWedge"] = GafferDispatch.Wedge() self["__MainWedge"]["preTasks"][0].setInput( self["__ImageDispatcher"]["task"]) self["__MainWedge"]["variable"].setValue("BAKE_WEDGE:value_unused") self["__MainWedge"]["indexVariable"].setValue("BAKE_WEDGE:index") self["__MainWedge"]["mode"].setValue(1) self["__MainWedge"]["intMin"].setValue(1) self["__MainWedge"]["intMax"].setInput(self["tasks"]) self["task"].setInput(self["__MainWedge"]["task"]) self["task"].setFlags(Gaffer.Plug.Flags.Serialisable, False) # Now set up the render tasks. This involves doing the actual rendering, and triggering the # output of the file list index file. # First get rid of options from the upstream scene that could mess up the bake self["__OptionOverrides"] = GafferScene.StandardOptions() self["__OptionOverrides"]["in"].setInput(self["in"]) self["__OptionOverrides"]["options"]["pixelAspectRatio"][ "enabled"].setValue(True) self["__OptionOverrides"]["options"]["resolutionMultiplier"][ "enabled"].setValue(True) self["__OptionOverrides"]["options"]["overscan"]["enabled"].setValue( True) self["__OptionOverrides"]["options"]["renderCropWindow"][ "enabled"].setValue(True) self["__OptionOverrides"]["options"]["cameraBlur"]["enabled"].setValue( True) self["__OptionOverrides"]["options"]["transformBlur"][ "enabled"].setValue(True) self["__OptionOverrides"]["options"]["deformationBlur"][ "enabled"].setValue(True) self["__CameraSetup"] = self.__CameraSetup() self["__CameraSetup"]["in"].setInput(self["__OptionOverrides"]["out"]) self["__CameraSetup"]["filter"].setInput(self["filter"]) self["__CameraSetup"]["defaultFileName"].setInput( self["defaultFileName"]) self["__CameraSetup"]["defaultResolution"].setInput( self["defaultResolution"]) self["__CameraSetup"]["uvSet"].setInput(self["uvSet"]) self["__CameraSetup"]["aovs"].setInput(self["aovs"]) self["__CameraSetup"]["normalOffset"].setInput(self["normalOffset"]) self["__CameraSetup"]["tasks"].setInput(self["tasks"]) self["__Expression"] = Gaffer.Expression() self["__Expression"].setExpression( 'parent["__CameraSetup"]["taskIndex"] = context.get( "BAKE_WEDGE:index", 0 )', "python") self["__indexFilePath"] = Gaffer.StringPlug() self["__indexFilePath"].setFlags(Gaffer.Plug.Flags.Serialisable, False) self["__IndexFileExpression"] = Gaffer.Expression() self["__IndexFileExpression"].setExpression( inspect.cleandoc(""" import os parent["__indexFilePath"] = os.path.join( parent["bakeDirectory"], "BAKE_FILE_INDEX_" + str( context.get("BAKE_WEDGE:index", 0 ) ) + ".####.txt" ) """), "python") self["__outputIndexCommand"] = Gaffer.PythonCommand() self["__outputIndexCommand"]["variables"].addMember( "bakeDirectory", Gaffer.StringPlug()) self["__outputIndexCommand"]["variables"][0]["value"].setInput( self["bakeDirectory"]) self["__outputIndexCommand"]["variables"].addMember( "indexFilePath", Gaffer.StringPlug()) self["__outputIndexCommand"]["variables"][1]["value"].setInput( self["__indexFilePath"]) self["__outputIndexCommand"]["variables"].addMember( "fileList", Gaffer.StringVectorDataPlug( defaultValue=IECore.StringVectorData())) self["__outputIndexCommand"]["variables"][2]["value"].setInput( self["__CameraSetup"]["renderFileList"]) self["__outputIndexCommand"]["command"].setValue( inspect.cleandoc(""" import os import distutils.dir_util # Ensure path exists distutils.dir_util.mkpath( variables["bakeDirectory"] ) f = open( variables["indexFilePath"], "w" ) f.writelines( [ i + "\\n" for i in sorted( variables["fileList"] ) ] ) f.close() IECore.msg( IECore.MessageHandler.Level.Info, "Bake Process", "Wrote list of bake files for this chunk to " + variables["indexFilePath"] ) """)) self["__arnoldRender"] = GafferArnold.ArnoldRender() self["__arnoldRender"]["preTasks"][0].setInput( self["__outputIndexCommand"]["task"]) self["__arnoldRender"]["dispatcher"]["immediate"].setValue(True) self["__arnoldRender"]["in"].setInput(self["__CameraSetup"]["out"]) self["__bakeDirectoryContext"] = GafferDispatch.TaskContextVariables() self["__bakeDirectoryContext"]["variables"].addMember( "bakeDirectory", Gaffer.StringPlug()) self["__bakeDirectoryContext"]["variables"][0]["value"].setInput( self["bakeDirectory"]) self["__bakeDirectoryContext"]["preTasks"][0].setInput( self["__arnoldRender"]["task"]) # Now set up the image tasks. This involves merging all layers for a UDIM, filling in the # background, writing out this image, converting it to tx, and optionally deleting all the exrs self["__imageList"] = Gaffer.CompoundObjectPlug( "__imageList", defaultValue=IECore.CompoundObject()) self["__imageList"].setFlags(Gaffer.Plug.Flags.Serialisable, False) self["__ImageReader"] = GafferImage.ImageReader() self["__CurInputFileExpression"] = Gaffer.Expression() self["__CurInputFileExpression"].setExpression( inspect.cleandoc(""" l = parent["__imageList"] outFile = context["wedge:outFile"] loopIndex = context[ "loop:index" ] parent["__ImageReader"]["fileName"] = l[outFile][ loopIndex ] """), "python") # Find the max size of any input file self["__SizeLoop"] = Gaffer.LoopComputeNode() self["__SizeLoop"].setup(Gaffer.IntPlug()) self["__SizeMaxExpression"] = Gaffer.Expression() self["__SizeMaxExpression"].setExpression( inspect.cleandoc(""" f = parent["__ImageReader"]["out"]["format"] parent["__SizeLoop"]["next"] = max( f.width(), parent["__SizeLoop"]["previous"] ) """), "python") # Loop over all input files for this output file, and merge them all together self["__ImageLoop"] = Gaffer.LoopComputeNode() self["__ImageLoop"].setup(GafferImage.ImagePlug()) self["__NumInputsForCurOutputExpression"] = Gaffer.Expression() self["__NumInputsForCurOutputExpression"].setExpression( inspect.cleandoc(""" l = parent["__imageList"] outFile = context["wedge:outFile"] numInputs = len( l[outFile] ) parent["__ImageLoop"]["iterations"] = numInputs parent["__SizeLoop"]["iterations"] = numInputs """), "python") self["__Resize"] = GafferImage.Resize() self["__Resize"]["format"]["displayWindow"]["min"].setValue( imath.V2i(0, 0)) self["__Resize"]['format']["displayWindow"]["max"]["x"].setInput( self["__SizeLoop"]["out"]) self["__Resize"]['format']["displayWindow"]["max"]["y"].setInput( self["__SizeLoop"]["out"]) self["__Resize"]['in'].setInput(self["__ImageReader"]["out"]) self["__Merge"] = GafferImage.Merge() self["__Merge"]["in"][0].setInput(self["__Resize"]["out"]) self["__Merge"]["in"][1].setInput(self["__ImageLoop"]["previous"]) self["__Merge"]["operation"].setValue(GafferImage.Merge.Operation.Add) self["__ImageLoop"]["next"].setInput(self["__Merge"]["out"]) # Write out the combined image, so we can immediately read it back in # This is just because we're doing enough image processing that we # could saturate the cache, and Gaffer wouldn't know that this is # the important result to keep self["__ImageIntermediateWriter"] = GafferImage.ImageWriter() self["__ImageIntermediateWriter"]["in"].setInput( self["__ImageLoop"]["out"]) self["__ImageIntermediateReader"] = GafferImage.ImageReader() # Now that we've merged everything together, we can use a BleedFill to fill in the background, # so that texture filtering across the edges will pull in colors that are at least reasonable. self["__BleedFill"] = GafferImage.BleedFill() self["__BleedFill"]["in"].setInput( self["__ImageIntermediateReader"]["out"]) self["__Median"] = GafferImage.Median() self["__Median"]["in"].setInput(self["__BleedFill"]["out"]) self["__Median"]["enabled"].setInput(self["applyMedianFilter"]) self["__Median"]["radius"]["x"].setInput(self["medianRadius"]) self["__Median"]["radius"]["y"].setInput(self["medianRadius"]) # Write out the result self["__ImageWriter"] = GafferImage.ImageWriter() self["__ImageWriter"]["in"].setInput(self["__Median"]["out"]) self["__ImageWriter"]["preTasks"][0].setInput( self["__ImageIntermediateWriter"]["task"]) # Convert result to texture self["__ConvertCommand"] = GafferDispatch.SystemCommand() self["__ConvertCommand"]["substitutions"].addMember( "inFile", IECore.StringData()) self["__ConvertCommand"]["substitutions"].addMember( "outFile", IECore.StringData()) self["__ConvertCommand"]["preTasks"][0].setInput( self["__ImageWriter"]["task"]) self["__ConvertCommand"]["command"].setValue( 'maketx --wrap clamp {inFile} -o {outFile}') self["__CommandSetupExpression"] = Gaffer.Expression() self["__CommandSetupExpression"].setExpression( inspect.cleandoc(""" outFileBase = context["wedge:outFile"] intermediateExr = outFileBase + ".intermediate.exr" parent["__ImageIntermediateWriter"]["fileName"] = intermediateExr parent["__ImageIntermediateReader"]["fileName"] = intermediateExr tmpExr = outFileBase + ".tmp.exr" parent["__ImageWriter"]["fileName"] = tmpExr parent["__ConvertCommand"]["substitutions"]["member1"]["value"] = tmpExr parent["__ConvertCommand"]["substitutions"]["member2"]["value"] = outFileBase + ".tx" """), "python") self["__ImageWedge"] = GafferDispatch.Wedge() self["__ImageWedge"]["preTasks"][0].setInput( self["__ConvertCommand"]["task"]) self["__ImageWedge"]["variable"].setValue('wedge:outFile') self["__ImageWedge"]["indexVariable"].setValue('wedge:outFileIndex') self["__ImageWedge"]["mode"].setValue(int( Gaffer.Wedge.Mode.StringList)) self["__CleanUpCommand"] = GafferDispatch.PythonCommand() self["__CleanUpCommand"]["preTasks"][0].setInput( self["__ImageWedge"]["task"]) self["__CleanUpCommand"]["variables"].addMember( "filesToDelete", Gaffer.StringVectorDataPlug( defaultValue=IECore.StringVectorData())) self["__CleanUpCommand"]["command"].setValue( inspect.cleandoc(""" import os for tmpFile in variables["filesToDelete"]: os.remove( tmpFile ) """)) self["__CleanUpExpression"] = Gaffer.Expression() self["__CleanUpExpression"].setExpression( inspect.cleandoc(""" imageList = parent["__imageList"] toDelete = [] for outFileBase, inputExrs in imageList.items(): tmpExr = outFileBase + ".tmp.exr" intermediateExr = outFileBase + ".intermediate.exr" toDelete.extend( inputExrs ) toDelete.append( tmpExr ) toDelete.append( intermediateExr ) toDelete.append( parent["__indexFilePath"] ) parent["__CleanUpCommand"]["variables"]["member1"]["value"] = IECore.StringVectorData( toDelete ) """), "python") self["__CleanUpSwitch"] = GafferDispatch.TaskSwitch() self["__CleanUpSwitch"]["preTasks"][0].setInput( self["__ImageWedge"]["task"]) self["__CleanUpSwitch"]["preTasks"][1].setInput( self["__CleanUpCommand"]["task"]) self["__CleanUpSwitch"]["index"].setInput( self["cleanupIntermediateFiles"]) # Set up the list of input image files to process, and the corresponding list of # output files to wedge over self["__ImageSetupExpression"] = Gaffer.Expression() self["__ImageSetupExpression"].setExpression( inspect.cleandoc(""" f = open( parent["__indexFilePath"], "r" ) fileList = f.read().splitlines() fileDict = {} for i in fileList: rootName = i.rsplit( ".exr", 1 )[0] if rootName in fileDict: fileDict[ rootName ].append( i ) else: fileDict[ rootName ] = IECore.StringVectorData( [i] ) parent["__imageList"] = IECore.CompoundObject( fileDict ) parent["__ImageWedge"]["strings"] = IECore.StringVectorData( fileDict.keys() ) """), "python")
def testVisible( self ) : sphere = GafferScene.Sphere() group = GafferScene.Group() group["in"][0].setInput( sphere["out"] ) group2 = GafferScene.Group() group2["in"][0].setInput( group["out"] ) visibleFilter = GafferScene.PathFilter() attributes1 = GafferScene.StandardAttributes() attributes1["attributes"]["visibility"]["enabled"].setValue( True ) attributes1["attributes"]["visibility"]["value"].setValue( True ) attributes1["in"].setInput( group2["out"] ) attributes1["filter"].setInput( visibleFilter["out"] ) invisibleFilter = GafferScene.PathFilter() attributes2 = GafferScene.StandardAttributes() attributes2["attributes"]["visibility"]["enabled"].setValue( True ) attributes2["attributes"]["visibility"]["value"].setValue( False ) attributes2["in"].setInput( attributes1["out"] ) attributes2["filter"].setInput( invisibleFilter["out"] ) self.assertTrue( GafferScene.visible( attributes2["out"], "/group/group/sphere" ) ) self.assertTrue( GafferScene.visible( attributes2["out"], "/group/group" ) ) self.assertTrue( GafferScene.visible( attributes2["out"], "/group" ) ) self.assertTrue( GafferScene.visible( attributes2["out"], "/" ) ) visibleFilter["paths"].setValue( IECore.StringVectorData( [ "/group" ] ) ) self.assertTrue( GafferScene.visible( attributes2["out"], "/group/group/sphere" ) ) self.assertTrue( GafferScene.visible( attributes2["out"], "/group/group" ) ) self.assertTrue( GafferScene.visible( attributes2["out"], "/group" ) ) self.assertTrue( GafferScene.visible( attributes2["out"], "/" ) ) invisibleFilter["paths"].setValue( IECore.StringVectorData( [ "/group/group" ] ) ) self.assertFalse( GafferScene.visible( attributes2["out"], "/group/group/sphere" ) ) self.assertFalse( GafferScene.visible( attributes2["out"], "/group/group" ) ) self.assertTrue( GafferScene.visible( attributes2["out"], "/group" ) ) self.assertTrue( GafferScene.visible( attributes2["out"], "/" ) ) visibleFilter["paths"].setValue( IECore.StringVectorData( [ "/group/group/sphere" ] ) ) self.assertFalse( GafferScene.visible( attributes2["out"], "/group/group/sphere" ) ) self.assertFalse( GafferScene.visible( attributes2["out"], "/group/group" ) ) self.assertTrue( GafferScene.visible( attributes2["out"], "/group" ) ) self.assertTrue( GafferScene.visible( attributes2["out"], "/" ) )
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"]) 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"]) 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(), [])