def __writeScene( self, script, args ) : import GafferScene import GafferSceneTest scene = script.descendant( args["scene"].value ) if isinstance( scene, Gaffer.Node ) : scene = next( ( x for x in scene.children( GafferScene.ScenePlug ) ), None ) if scene is None : IECore.msg( IECore.Msg.Level.Error, "stats", "Scene \"%s\" does not exist" % args["scene"].value ) return if args["preCache"].value : GafferSceneTest.traverseScene( scene ) memory = _Memory.maxRSS() with _Timer() as sceneTimer : with self.__performanceMonitor or _NullContextManager(), self.__contextMonitor or _NullContextManager() : with Gaffer.Context( script.context() ) as context : for frame in self.__frames( script, args ) : context.setFrame( frame ) GafferSceneTest.traverseScene( scene ) self.__timers["Scene generation"] = sceneTimer self.__memory["Scene generation"] = _Memory.maxRSS() - memory
def __writeScene(self, script, args): import GafferScene import GafferSceneTest scene = script.descendant(args["scene"].value) if isinstance(scene, Gaffer.Node): scene = next((x for x in scene.children(GafferScene.ScenePlug)), None) if scene is None: IECore.msg(IECore.Msg.Level.Error, "stats", "Scene \"%s\" does not exist" % args["scene"].value) return if args["preCache"].value: GafferSceneTest.traverseScene(scene) memory = _Memory.maxRSS() with _Timer() as sceneTimer: with self.__performanceMonitor or _NullContextManager( ), self.__contextMonitor or _NullContextManager(): GafferSceneTest.traverseScene(scene) self.__timers["Scene generation"] = sceneTimer self.__memory["Scene generation"] = _Memory.maxRSS() - memory
def computeScene(): with self.__context(script, args) as context: for frame in frames: context.setFrame(frame) if isinstance(scene, GafferDispatch.TaskNode.TaskPlug): if args["location"].value: IECore.msg( IECore.Msg.Level.Warning, "stats", "`-location` argument is not compatible with TaskPlugs" ) context[ "scene:render:sceneTranslationOnly"] = IECore.BoolData( True) scene.execute() else: if args["sets"]: GafferScene.SceneAlgo.sets(scene, args["sets"]) else: if args["location"].value: scene.transform(args["location"].value) scene.bound(args["location"].value) scene.attributes(args["location"].value) scene.object(args["location"].value) else: GafferSceneTest.traverseScene(scene)
def testNameClashesWithThreading(self): sphere = IECoreScene.SpherePrimitive() input1 = GafferSceneTest.CompoundObjectSource() input1["in"].setValue( IECore.CompoundObject({ "bound": IECore.Box3fData(sphere.bound()), "children": { "myLovelyObject1": { "bound": IECore.Box3fData(sphere.bound()), "object": sphere, }, }, }), ) plane = IECoreScene.MeshPrimitive.createPlane( imath.Box2f(imath.V2f(-1), imath.V2f(1))) input2 = GafferSceneTest.CompoundObjectSource() input2["in"].setValue( IECore.CompoundObject({ "bound": IECore.Box3fData(plane.bound()), "children": { "myLovelyObject1": { "bound": IECore.Box3fData(plane.bound()), "object": plane, }, }, }), ) group = GafferScene.Group() group["name"].setValue("topLevel") group["in"][0].setInput(input1["out"]) group["in"][1].setInput(input2["out"]) GafferSceneTest.traverseScene(group["out"])
def computeScene() : with self.__context( script, args ) as context : for frame in self.__frames( script, args ) : context.setFrame( frame ) if args["sets"] : GafferScene.SceneAlgo.sets( scene, args["sets"] ) else : GafferSceneTest.traverseScene( scene )
def computeScene(): with self.__context(script, args) as context: for frame in self.__frames(script, args): context.setFrame(frame) if args["sets"]: GafferScene.SceneAlgo.sets(scene, args["sets"]) else: GafferSceneTest.traverseScene(scene)
def testThreading(self): sphere = IECore.SpherePrimitive() instanceInput = GafferSceneTest.CompoundObjectSource() instanceInput["in"].setValue( IECore.CompoundObject({ "bound": IECore.Box3fData(IECore.Box3f(IECore.V3f(-2), IECore.V3f(2))), "children": { "sphere": { "object": sphere, "bound": IECore.Box3fData(sphere.bound()), "transform": IECore.M44fData(IECore.M44f.createScaled( IECore.V3f(2))), }, } })) seeds = IECore.PointsPrimitive( IECore.V3fVectorData([ IECore.V3f(1, 0, 0), IECore.V3f(1, 1, 0), IECore.V3f(0, 1, 0), IECore.V3f(0, 0, 0) ])) seedsInput = GafferSceneTest.CompoundObjectSource() seedsInput["in"].setValue( IECore.CompoundObject( { "bound": IECore.Box3fData( IECore.Box3f(IECore.V3f(1, 0, 0), IECore.V3f(2, 1, 0))), "children": { "seeds": { "bound": IECore.Box3fData(seeds.bound()), "transform": IECore.M44fData( IECore.M44f.createTranslated( IECore.V3f(1, 0, 0))), "object": seeds, }, }, }, )) instancer = GafferScene.Instancer() instancer["in"].setInput(seedsInput["out"]) instancer["instance"].setInput(instanceInput["out"]) instancer["parent"].setValue("/seeds") instancer["name"].setValue("instances") GafferSceneTest.traverseScene(instancer["out"])
def testPerformance(self): sphere = GafferScene.Sphere() duplicate = GafferScene.Duplicate() duplicate["in"].setInput(sphere["out"]) duplicate["target"].setValue("/sphere") duplicate["transform"]["translate"]["x"].setValue(2) duplicate["copies"].setValue(100000) with GafferTest.TestRunner.PerformanceScope(): GafferSceneTest.traverseScene(duplicate["out"])
def computeScene() : with self.__context( script, args ) as context : for frame in self.__frames( script, args ) : context.setFrame( frame ) if isinstance( scene, GafferDispatch.TaskNode.TaskPlug ) : context["scene:render:sceneTranslationOnly"] = IECore.BoolData( True ) scene.execute() else : if args["sets"] : GafferScene.SceneAlgo.sets( scene, args["sets"] ) else : GafferSceneTest.traverseScene( scene )
def testThreading(self): sphere = IECore.SpherePrimitive() instanceInput = GafferSceneTest.CompoundObjectSource() instanceInput["in"].setValue( IECore.CompoundObject( { "bound": IECore.Box3fData(IECore.Box3f(IECore.V3f(-2), IECore.V3f(2))), "children": { "sphere": { "object": sphere, "bound": IECore.Box3fData(sphere.bound()), "transform": IECore.M44fData(IECore.M44f.createScaled(IECore.V3f(2))), } }, } ) ) seeds = IECore.PointsPrimitive( IECore.V3fVectorData([IECore.V3f(1, 0, 0), IECore.V3f(1, 1, 0), IECore.V3f(0, 1, 0), IECore.V3f(0, 0, 0)]) ) seedsInput = GafferSceneTest.CompoundObjectSource() seedsInput["in"].setValue( IECore.CompoundObject( { "bound": IECore.Box3fData(IECore.Box3f(IECore.V3f(1, 0, 0), IECore.V3f(2, 1, 0))), "children": { "seeds": { "bound": IECore.Box3fData(seeds.bound()), "transform": IECore.M44fData(IECore.M44f.createTranslated(IECore.V3f(1, 0, 0))), "object": seeds, } }, } ) ) instancer = GafferScene.Instancer() instancer["in"].setInput(seedsInput["out"]) instancer["instance"].setInput(instanceInput["out"]) instancer["parent"].setValue("/seeds") instancer["name"].setValue("instances") GafferSceneTest.traverseScene(instancer["out"])
def __printScene(self, script, args): import GafferScene import GafferSceneTest scene = script.descendant(args["scene"].value) if isinstance(scene, Gaffer.Node): scene = next((x for x in scene.children(GafferScene.ScenePlug)), None) if scene is None: IECore.msg(IECore.Msg.Level.Error, "stats", 'Scene "%s" does not exist' % args["scene"].value) return memory = _Memory.maxRSS() with _Timer() as sceneTimer: with self.__performanceMonitor or _NullContextManager(): GafferSceneTest.traverseScene(scene) self.__timers["Scene generation"] = sceneTimer self.__memory["Scene generation"] = _Memory.maxRSS() - memory
def testExtraAttributesOnlyEvaluatedForFilteredLocations( self ) : script = Gaffer.ScriptNode() script["grid"] = GafferScene.Grid() script["filter"] = GafferScene.PathFilter() script["filter"]["paths"].setValue( IECore.StringVectorData( [ "/grid" ] ) ) script["customAttributes"] = GafferScene.CustomAttributes() script["customAttributes"]["in"].setInput( script["grid"]["out"] ) script["customAttributes"]["filter"].setInput( script["filter"]["out"] ) script["expression"] = Gaffer.Expression() script["expression"].setExpression( """parent["customAttributes"]["extraAttributes"] = IECore.CompoundData( { "a" : IECore.StringData( str( context.get( "scene:path" ) ) ) } )""" ) with Gaffer.ContextMonitor( script["expression"] ) as monitor : GafferSceneTest.traverseScene( script["customAttributes"]["out"] ) self.assertEqual( monitor.combinedStatistics().numUniqueValues( "scene:path" ), 1 )
def testAlembicThreading( self ) : mesh = IECoreScene.MeshPrimitive.createPlane( imath.Box2f( imath.V2f( -1 ), imath.V2f( 1 ) ) ) fileName = self.temporaryDirectory() + "/test.abc" root = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Write ) root.writeBound( imath.Box3d( mesh.bound() ), 0 ) for i in range( 0, 1000 ) : child = root.createChild( str( i ) ) child.writeObject( mesh, 0 ) child.writeBound( imath.Box3d( mesh.bound() ), 0 ) del root, child sceneReader = GafferScene.SceneReader() sceneReader["fileName"].setValue( fileName ) for i in range( 0, 20 ) : sceneReader["refreshCount"].setValue( sceneReader["refreshCount"].getValue() + 1 ) GafferSceneTest.traverseScene( sceneReader["out"] )
def testNameClashesWithThreading( self ) : sphere = IECoreScene.SpherePrimitive() input1 = GafferSceneTest.CompoundObjectSource() input1["in"].setValue( IECore.CompoundObject( { "bound" : IECore.Box3fData( sphere.bound() ), "children" : { "myLovelyObject1" : { "bound" : IECore.Box3fData( sphere.bound() ), "object" : sphere, }, }, } ), ) plane = IECoreScene.MeshPrimitive.createPlane( imath.Box2f( imath.V2f( -1 ), imath.V2f( 1 ) ) ) input2 = GafferSceneTest.CompoundObjectSource() input2["in"].setValue( IECore.CompoundObject( { "bound" : IECore.Box3fData( plane.bound() ), "children" : { "myLovelyObject1" : { "bound" : IECore.Box3fData( plane.bound() ), "object" : plane, }, }, } ), ) group = GafferScene.Group() group["name"].setValue( "topLevel" ) group["in"][0].setInput( input1["out"] ) group["in"][1].setInput( input2["out"] ) GafferSceneTest.traverseScene( group["out"] )
def traverser(): try: GafferSceneTest.traverseScene(g["out"]) except Exception as e: exceptions.append(e)
def testBadCachePolicyHang(self): # Using the legacy cache policy for OSLImage.shadingPlug creates a hang due to tbb task stealing, # though it's a bit hard to actually demonstrate constant = GafferImage.Constant() constant["format"].setValue(GafferImage.Format(128, 128, 1.000)) # Need a slow to compute OSL code in order to trigger hang mandelbrotCode = self.mandelbrotNode() # In order to trigger the hang, we need to mix threads which are stuck waiting for an expression which # uses the Standard policy with threads that are actually finishing, so that tbb tries to start up new # threads while we're waiting for the expression result. To do this, we use the "var" context variable # to create two versions of this OSLCode mandelbrotCode["varExpression"] = Gaffer.Expression() mandelbrotCode["varExpression"].setExpression( 'parent.parameters.iterations = 100000 + context( "var", 0 );', "OSL") oslImage = GafferOSL.OSLImage() oslImage["channels"].addChild( Gaffer.NameValuePlug( "", Gaffer.Color3fPlug( "value", defaultValue=imath.Color3f(1, 1, 1), flags=Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ), True, "channel", Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic)) oslImage["in"].setInput(constant["out"]) oslImage["channels"]["channel"]["value"][0].setInput( mandelbrotCode["out"]["outFloat"]) oslImage["channels"]["channel"]["value"][1].setInput( mandelbrotCode["out"]["outFloat"]) oslImage["channels"]["channel"]["value"][2].setInput( mandelbrotCode["out"]["outFloat"]) # This imageStats is use to create non-blocking slow calculations imageStats = GafferImage.ImageStats() imageStats["in"].setInput(oslImage["out"]) imageStats["area"].setValue( imath.Box2i(imath.V2i(0, 0), imath.V2i(64, 64))) # This box does the non-blocking slow calculation, followed by a blocking slow calculation. # This ensures that tasks which do just the non-block calculation will start finishing while # the blocking slow calculation is still running, allowing tbb to try running more threads # on the blocking calcluation, realizing they can't run, and stealing tasks onto those threads # which can hit the Standard policy lock on the expression upstream and deadlock, unless the # OSLImage isolates its threads correctly expressionBox = Gaffer.Box() expressionBox.addChild( Gaffer.FloatVectorDataPlug("inChannelData", defaultValue=IECore.FloatVectorData( []))) expressionBox.addChild(Gaffer.FloatPlug("inStat")) expressionBox.addChild( Gaffer.FloatPlug("out", direction=Gaffer.Plug.Direction.Out)) expressionBox["inChannelData"].setInput(oslImage["out"]["channelData"]) expressionBox["inStat"].setInput(imageStats["average"]["r"]) expressionBox["contextVariables"] = Gaffer.ContextVariables() expressionBox["contextVariables"].setup( Gaffer.FloatVectorDataPlug("in", defaultValue=IECore.FloatVectorData( []))) expressionBox["contextVariables"]["variables"].addChild( Gaffer.NameValuePlug("image:tileOrigin", Gaffer.V2iPlug("value"), True, "member1")) expressionBox["contextVariables"]["variables"].addChild( Gaffer.NameValuePlug("image:channelName", Gaffer.StringPlug("value", defaultValue='R'), True, "member2")) expressionBox["contextVariables"]["variables"].addChild( Gaffer.NameValuePlug("var", Gaffer.IntPlug("value", defaultValue=1), True, "member3")) expressionBox["contextVariables"]["in"].setInput( expressionBox["inChannelData"]) expressionBox["expression"] = Gaffer.Expression() expressionBox["expression"].setExpression( inspect.cleandoc(""" d = parent["contextVariables"]["out"] parent["out"] = d[0] + parent["inStat"] """)) # Create a switch to mix which tasks perform the non-blocking or blocking calculation - we need a mixture # to trigger the hang switch = Gaffer.Switch() switch.setup(Gaffer.IntPlug( "in", defaultValue=0, )) switch["in"][0].setInput(expressionBox["out"]) switch["in"][1].setInput(imageStats["average"]["r"]) switch["switchExpression"] = Gaffer.Expression() switch["switchExpression"].setExpression( 'parent.index = ( stoi( context( "testContext", "0" ) ) % 10 ) > 5;', "OSL") # In order to evaluate this expression a bunch of times at once with different values of "testContext", # we set up a simple scene that can be evaluated with GafferSceneTest.traversScene. # In theory, we could use a simple function that used a parallel_for to evaluate switch["out"], but for # some reason we don't entirely understand, this does not trigger the hang import GafferSceneTest import GafferScene sphere = GafferScene.Sphere() pathFilter = GafferScene.PathFilter() pathFilter["paths"].setValue(IECore.StringVectorData(['/sphere'])) customAttributes = GafferScene.CustomAttributes() customAttributes["attributes"].addChild( Gaffer.NameValuePlug("foo", Gaffer.FloatPlug("value"), True, "member1")) customAttributes["attributes"]["member1"]["value"].setInput( switch["out"]) customAttributes["in"].setInput(sphere["out"]) customAttributes["filter"].setInput(pathFilter["out"]) collectScenes = GafferScene.CollectScenes() collectScenes["in"].setInput(customAttributes["out"]) collectScenes["rootNames"].setValue( IECore.StringVectorData([str(i) for i in range(1000)])) collectScenes["rootNameVariable"].setValue('testContext') # When OSLImage.shadingPlug is not correctly isolated, and grain size on ShadingEngine is smaller than the # image tile size, this fails about 50% of the time. Running it 5 times makes the failure pretty consistent. for i in range(5): Gaffer.ValuePlug.clearCache() Gaffer.ValuePlug.clearHashCache() GafferSceneTest.traverseScene(collectScenes["out"])
def traverser() : try : GafferSceneTest.traverseScene( g["out"] ) except Exception, e : exceptions.append( e )
def traverser(): try: GafferSceneTest.traverseScene(g["out"], Gaffer.Context()) except Exception, e: exceptions.append(e)