def testObjectTweaks(self): camera1 = GafferScene.Camera("Camera1") camera1["name"].setValue("camera1") camera1Filter = GafferScene.PathFilter() camera1Filter["paths"].setValue(IECore.StringVectorData(["/camera1"])) camera1Tweaks = GafferScene.CameraTweaks("Camera1Tweaks") camera1Tweaks["in"].setInput(camera1["out"]) camera1Tweaks["filter"].setInput(camera1Filter["out"]) unfilteredTweaks = GafferScene.CameraTweaks("UnfilteredTweaks") unfilteredTweaks["in"].setInput(camera1Tweaks["out"]) camera2 = GafferScene.Camera("Camera2") camera2["name"].setValue("camera2") group = GafferScene.Group() group["in"][0].setInput(unfilteredTweaks["out"]) group["in"][1].setInput(camera2["out"]) camera2Filter = GafferScene.PathFilter() camera2Filter["paths"].setValue( IECore.StringVectorData(["/group/camera2"])) camera2Tweaks = GafferScene.CameraTweaks("Camera2Tweaks") camera2Tweaks["in"].setInput(group["out"]) camera2Tweaks["filter"].setInput(camera2Filter["out"]) self.assertEqual( GafferScene.SceneAlgo.objectTweaks(camera2Tweaks["out"], "/"), None) self.assertEqual( GafferScene.SceneAlgo.objectTweaks(camera2Tweaks["out"], "/group"), None) self.assertEqual( GafferScene.SceneAlgo.objectTweaks(camera2Tweaks["out"], "/group/camera1"), camera1Tweaks) self.assertEqual( GafferScene.SceneAlgo.objectTweaks(camera2Tweaks["out"], "/group/camera2"), camera2Tweaks)
def testObjectTweaksWithSetFilter(self): camera = GafferScene.Camera() camera["sets"].setValue("A") setFilter = GafferScene.SetFilter() setFilter["set"].setValue("A") cameraTweaks = GafferScene.CameraTweaks() cameraTweaks["in"].setInput(camera["out"]) cameraTweaks["filter"].setInput(setFilter["out"]) self.assertEqual( GafferScene.SceneAlgo.objectTweaks(cameraTweaks["out"], "/camera"), cameraTweaks)
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"]["children"][0].setInput(self["__group"]["out"]) self["__collectSceneRootsExpression"] = Gaffer.Expression() self["__collectSceneRootsExpression"].setExpression( inspect.cleandoc(""" info = parent["__chunkedBakeInfo"] parent["__collectScenes"]["rootNames"] = IECore.StringVectorData( info.keys() ) """), "python") self["__cameraSetupExpression"] = Gaffer.Expression() self["__cameraSetupExpression"].setExpression( inspect.cleandoc(""" cameraName = context["collect:cameraName"] info = parent["__chunkedBakeInfo"] i = info[cameraName] udimOffset = i["udim"].value - 1001 parent["__cameraTweaks"]["tweaks"]["resolution"]["value"] = imath.V2i( i["resolution"].value ) parent["__cameraTweaks"]["tweaks"]["u_offset"]["value"] = -( udimOffset % 10 ) parent["__cameraTweaks"]["tweaks"]["v_offset"]["value"] = -( udimOffset / 10 ) parent["__cameraTweaks"]["tweaks"]["mesh"]["value"] = i["mesh"].value parent["__cameraTweaks"]["tweaks"]["uv_set"]["value"] = parent["uvSet"] if parent["uvSet"] != "uv" else "" """), "python") self["out"].setFlags(Gaffer.Plug.Flags.Serialisable, False) self["out"].setInput(self["__parent"]["out"])
def __init__( self, name = "__CameraSetup" ) : GafferScene.FilteredSceneProcessor.__init__( self, name ) # Public plugs self["cameraGroup"] = Gaffer.StringPlug( "cameraGroup", Gaffer.Plug.Direction.In, "__TEXTUREBAKE_CAMERAS" ) self["bakeDirectory"] = Gaffer.StringPlug( "bakeDirectory", Gaffer.Plug.Direction.In, "" ) self["defaultFileName"] = Gaffer.StringPlug( "defaultFileName", Gaffer.Plug.Direction.In, "${bakeDirectory}/<AOV>/<AOV>.<UDIM>.exr" ) self["defaultResolution"] = Gaffer.IntPlug( "defaultResolution", Gaffer.Plug.Direction.In, 512 ) self["uvSet"] = Gaffer.StringPlug( "uvSet", Gaffer.Plug.Direction.In, "uv" ) self["udims"] = Gaffer.StringPlug( "udims", Gaffer.Plug.Direction.In, "" ) self["normalOffset"] = Gaffer.FloatPlug( "normalOffset", Gaffer.Plug.Direction.In, 0.1 ) self["aovs"] = Gaffer.StringPlug( "aovs", Gaffer.Plug.Direction.In, "beauty:rgba" ) self["tasks"] = Gaffer.IntPlug( "tasks", Gaffer.Plug.Direction.In, 1 ) self["taskIndex"] = Gaffer.IntPlug( "taskIndex", Gaffer.Plug.Direction.In, 0 ) # Output self["renderFileList"] = Gaffer.StringVectorDataPlug( "renderFileList", Gaffer.Plug.Direction.Out, defaultValue = IECore.StringVectorData() ) self["renderFileList"].setFlags( Gaffer.Plug.Flags.Serialisable, False ) # Private internal network self["__udimQuery"] = GafferScene.UDIMQuery() self["__udimQuery"]["in"].setInput( self["in"] ) self["__udimQuery"]["uvSet"].setInput( self["uvSet"] ) self["__udimQuery"]["attributes"].setValue( "bake:resolution bake:fileName" ) self["__udimQuery"]["filter"].setInput( self["filter"] ) self["__chunkedBakeInfo"] = Gaffer.CompoundObjectPlug( "__chunkedBakeInfo", Gaffer.Plug.Direction.In, IECore.CompoundObject() ) self["__chunkedBakeInfo"].setFlags( Gaffer.Plug.Flags.Serialisable, False ) self["__chunkExpression"] = Gaffer.Expression() self["__chunkExpression"].setExpression( inspect.cleandoc( """ import collections import re rawInfo = parent["__udimQuery"]["out"] defaultFileName = parent["defaultFileName"] defaultResolution = parent["defaultResolution"] selectUdimsStr = parent["udims"] # FrameList really ought to take care of this check, instead of just doing # something obviously wrong if re.match( ".*[0-9] +[0-9].*", selectUdimsStr ): raise RuntimeError( "ArnoldTextureBake : Udim list must be comma separated." ) selectUdims = set( IECore.FrameList.parse( selectUdimsStr ).asList() ) allMeshes = collections.defaultdict( lambda : [] ) for udim, meshes in rawInfo.items(): if selectUdims and not int( udim ) in selectUdims: continue for mesh, extraAttributes in meshes.items(): resolution = defaultResolution if "bake:resolution" in extraAttributes: resolution = extraAttributes["bake:resolution"].value fileName = defaultFileName if "bake:fileName" in extraAttributes: fileName = extraAttributes["bake:fileName"].value allMeshes[ (fileName, udim) ].append( { "mesh" : mesh, "resolution" : resolution } ) fileList = sorted( allMeshes.keys() ) info = IECore.CompoundObject() numTasks = min( parent["tasks"], len( fileList ) ) taskIndex = parent["taskIndex"] if taskIndex < numTasks: chunkStart = ( taskIndex * len( fileList ) ) // numTasks chunkEnd = ( ( taskIndex + 1 ) * len( fileList ) ) // numTasks dupeCount = 0 prevFileName = "" for fileNameTemplate, udim in fileList[chunkStart:chunkEnd]: for meshData in allMeshes[(fileNameTemplate, udim)]: o = IECore.CompoundObject() o["mesh"] = IECore.StringData( meshData["mesh"] ) o["udim"] = IECore.IntData( int( udim ) ) o["resolution"] = IECore.IntData( meshData["resolution"] ) udimStr = str( udim ) fileName = fileNameTemplate.replace( "<UDIM>", udimStr ) if fileName == prevFileName: dupeCount += 1 fileName = fileName + ".layer" + str( dupeCount ) else: prevFileName = fileName dupeCount = 0 o["fileName"] = IECore.StringData( fileName ) name = o["mesh"].value.replace( "/", "_" ) + "." + udimStr info[ name ] = o parent["__chunkedBakeInfo"] = info fileList = [] for name, i in info.items(): fileName = i["fileName"].value for nameAndAov in parent["aovs"].strip( " " ).split( " " ): fileList.append( i["fileName"].value.replace( "<AOV>", nameAndAov.split(":")[0] ) ) parent["renderFileList"] = IECore.StringVectorData( fileList ) """ ), "python" ) self["__parent"] = GafferScene.Parent() self["__parent"]["parent"].setValue( "/" ) for c in ['bound', 'transform', 'attributes', 'object', 'childNames', 'setNames', 'set']: self["__parent"]["in"][c].setInput( self["in"][c] ) self["__outputExpression"] = Gaffer.Expression() self["__outputExpression"].setExpression( inspect.cleandoc( """ import IECoreScene # Transfer all input globals except for outputs inGlobals = parent["in"]["globals"] outGlobals = IECore.CompoundObject() for key, value in inGlobals.items(): if not key.startswith( "output:" ): outGlobals[key] = value # Make our own outputs info = parent["__chunkedBakeInfo"] for cameraName, i in info.items(): params = IECore.CompoundData() fileName = i["fileName"].value params["camera"] = IECore.StringData( "/" + parent["cameraGroup"] + "/" + cameraName ) for nameAndAov in parent["aovs"].strip( " " ).split( " " ): tokens = nameAndAov.split( ":" ) if len( tokens ) != 2: raise RuntimeError( "Invalid bake aov specification: %s It should contain a : between name and data." ) ( aovName, aov ) = tokens aovFileName = fileName.replace( "<AOV>", aovName ) outGlobals["output:" + cameraName + "." + aov] = IECoreScene.Output( aovFileName, "exr", aov + " RGBA", params ) parent["__parent"]["in"]["globals"] = outGlobals """ ), "python" ) self["__camera"] = GafferScene.Camera() self["__camera"]["projection"].setValue( "orthographic" ) self["__cameraTweaks"] = GafferScene.CameraTweaks() self["__cameraTweaks"]["in"].setInput( self["__camera"]["out"] ) self["__cameraTweaks"]["tweaks"]["projection"] = GafferScene.TweakPlug( "projection", "uv_camera" ) self["__cameraTweaks"]["tweaks"]["resolution"] = GafferScene.TweakPlug( "resolution", imath.V2i( 0 ) ) self["__cameraTweaks"]["tweaks"]["u_offset"] = GafferScene.TweakPlug( "u_offset", 0.0 ) self["__cameraTweaks"]["tweaks"]["v_offset"] = GafferScene.TweakPlug( "v_offset", 0.0 ) self["__cameraTweaks"]["tweaks"]["mesh"] = GafferScene.TweakPlug( "mesh", "" ) self["__cameraTweaks"]["tweaks"]["uv_set"] = GafferScene.TweakPlug( "uv_set", "" ) self["__cameraTweaks"]["tweaks"]["extend_edges"] = GafferScene.TweakPlug( "extend_edges", False ) self["__cameraTweaks"]["tweaks"]["offset"] = GafferScene.TweakPlug( "offset", 0.1 ) self["__cameraTweaks"]["tweaks"]["offset"]["value"].setInput( self["normalOffset"] ) self["__cameraTweaksFilter"] = GafferScene.PathFilter() self["__cameraTweaksFilter"]["paths"].setValue( IECore.StringVectorData( [ '/camera' ] ) ) self["__cameraTweaks"]["filter"].setInput( self["__cameraTweaksFilter"]["out"] ) self["__collectScenes"] = GafferScene.CollectScenes() self["__collectScenes"]["sourceRoot"].setValue( "/camera" ) self["__collectScenes"]["rootNameVariable"].setValue( "collect:cameraName" ) self["__collectScenes"]["in"].setInput( self["__cameraTweaks"]["out"] ) self["__group"] = GafferScene.Group() self["__group"]["in"][0].setInput( self["__collectScenes"]["out"] ) self["__group"]["name"].setInput( self["cameraGroup"] ) self["__parent"]["children"][0].setInput( self["__group"]["out"] ) self["__collectSceneRootsExpression"] = Gaffer.Expression() self["__collectSceneRootsExpression"].setExpression( inspect.cleandoc( """ info = parent["__chunkedBakeInfo"] parent["__collectScenes"]["rootNames"] = IECore.StringVectorData( info.keys() ) """ ), "python" ) self["__cameraSetupExpression"] = Gaffer.Expression() self["__cameraSetupExpression"].setExpression( inspect.cleandoc( """ cameraName = context["collect:cameraName"] info = parent["__chunkedBakeInfo"] i = info[cameraName] udimOffset = i["udim"].value - 1001 parent["__cameraTweaks"]["tweaks"]["resolution"]["value"] = imath.V2i( i["resolution"].value ) parent["__cameraTweaks"]["tweaks"]["u_offset"]["value"] = -( udimOffset % 10 ) parent["__cameraTweaks"]["tweaks"]["v_offset"]["value"] = -( udimOffset // 10 ) parent["__cameraTweaks"]["tweaks"]["mesh"]["value"] = i["mesh"].value parent["__cameraTweaks"]["tweaks"]["uv_set"]["value"] = parent["uvSet"] if parent["uvSet"] != "uv" else "" """ ), "python" ) self["out"].setFlags( Gaffer.Plug.Flags.Serialisable, False ) self["out"].setInput( self["__parent"]["out"] )
script["Camera"]["renderSettingOverrides"]["resolution"]["value"].setValue( imath.V2i(5120, 2160)) script["Camera"]["renderSettingOverrides"]["resolution"]["enabled"].setValue( True) __nodeEditorWindow.parent().close() __delay(0.5) __nodeEditorWindow = GafferUI.NodeEditor.acquire(script["Camera"], floating=True) GafferUI.PlugValueWidget.acquire(script["Camera"]["renderSettingOverrides"]) __nodeEditorWindow._qtWidget().setFocus() __nodeEditorWindow.parent()._qtWidget().resize(486, 425) GafferUI.WidgetAlgo.grab(widget=__nodeEditorWindow, imagePath="images/taskCameraRenderOverridePlugs.png") # Task: a CameraTweaks node with 2 tweaks in the Node Editor script["CameraTweaks"] = GafferScene.CameraTweaks() script["CameraTweaks"]["tweaks"].addChild( GafferScene.TweakPlug( "tweak_focalLength", flags=Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, )) script["CameraTweaks"]["tweaks"]["tweak_focalLength"].addChild( Gaffer.FloatPlug( "value", defaultValue=35.0, flags=Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, )) script["CameraTweaks"]["tweaks"].addChild( GafferScene.TweakPlug( "tweak_resolution", flags=Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic,
def testTweaks(self): c = GafferScene.Camera() tweaks = GafferScene.CameraTweaks() tweaks["in"].setInput(c["out"]) f = GafferScene.PathFilter() f["paths"].setValue(IECore.StringVectorData(["/camera"])) tweaks["filter"].setInput(f["out"]) self.assertEqual(c["out"].object("/camera"), tweaks["out"].object("/camera")) random.seed(42) for i in range(20): tweaks["tweaks"].clearChildren() c["projection"].setValue("perspective") c["perspectiveMode"].setValue( GafferScene.Camera.PerspectiveMode.ApertureFocalLength) c["aperture"].setValue( imath.V2f(random.uniform(1, 20), random.uniform(1, 20))) c["apertureOffset"].setValue( imath.V2f(random.uniform(-10, 10), random.uniform(-10, 10))) c["focalLength"].setValue(random.uniform(0.5, 50)) c["clippingPlanes"].setValue( imath.V2f(random.uniform(0.5, 100)) + imath.V2f(0, random.uniform(0.5, 100))) c["fStop"].setValue(random.uniform(0, 16)) c["focalLengthWorldScale"].setValue(random.uniform(0.01, 10)) c["focusDistance"].setValue(random.uniform(0.01, 100)) c["renderSettingOverrides"]["filmFit"]["enabled"].setValue(True) c["renderSettingOverrides"]["filmFit"]["value"].setValue( random.choice(IECoreScene.Camera.FilmFit.names.values())) c["renderSettingOverrides"]["shutter"]["enabled"].setValue(True) c["renderSettingOverrides"]["shutter"]["value"].setValue( imath.V2f(random.uniform(-0.5, 0), random.uniform(0, 0.5))) c["renderSettingOverrides"]["pixelAspectRatio"][ "enabled"].setValue(True) c["renderSettingOverrides"]["pixelAspectRatio"]["value"].setValue( random.uniform(0.1, 10)) self.assertEqual(c["out"].object("/camera"), tweaks["out"].object("/camera")) for mode in GafferScene.TweakPlug.Mode.names.values(): #for mode in [ GafferScene.TweakPlug.Mode.Replace ]: for name, value in [ ("projection", "orthographic"), ("aperture", imath.V2f(10, 20)), ("apertureOffset", imath.V2f(5, -7)), ("focalLength", 4.2), ("clippingPlanes", imath.V2f(5, 7)), ("fStop", 1.2), ("focalLengthWorldScale", 0.12), ("focusDistance", 3.2), ("filmFit", 1), ("shutter", imath.V2f(0.1, 0.2)), ("pixelAspectRatio", 0.11), ("fieldOfView", 5.7), ("apertureAspectRatio", 0.15), ]: if type(value) in [str] and mode in [ GafferScene.TweakPlug.Mode.Add, GafferScene.TweakPlug.Mode.Subtract, GafferScene.TweakPlug.Mode.Multiply ]: continue tweaks["tweaks"].clearChildren() tweaks["tweaks"].addChild( GafferScene.TweakPlug(name, value)) tweaks["tweaks"]["tweak"]["mode"].setValue(mode) if name == "fieldOfView": orig = c["out"].object( "/camera").calculateFieldOfView()[0] elif name == "apertureAspectRatio": origWindow = c["out"].object("/camera").frustum( IECoreScene.Camera.FilmFit.Distort).size() orig = origWindow[0] / origWindow[1] else: orig = c["out"].object( "/camera").parameters()[name].value if mode == GafferScene.TweakPlug.Mode.Remove: if not name in ["fieldOfView", "apertureAspectRatio"]: self.assertFalse(name in tweaks["out"].object( "/camera").parameters()) continue elif mode == GafferScene.TweakPlug.Mode.Replace: ref = value elif mode == GafferScene.TweakPlug.Mode.Add: ref = orig + value elif mode == GafferScene.TweakPlug.Mode.Multiply: ref = orig * value elif mode == GafferScene.TweakPlug.Mode.Subtract: ref = orig - value if name == "fieldOfView": modified = tweaks["out"].object( "/camera").calculateFieldOfView()[0] ref = max(0, min(179.99, ref)) elif name == "apertureAspectRatio": modWindow = tweaks["out"].object("/camera").frustum( IECoreScene.Camera.FilmFit.Distort).size() modified = modWindow[0] / modWindow[1] ref = max(0.0000001, ref) else: modified = tweaks["out"].object( "/camera").parameters()[name].value if type(value) == imath.V2f: self.assertAlmostEqual(modified[0], ref[0], places=4) self.assertAlmostEqual(modified[1], ref[1], places=4) else: self.assertAlmostEqual(modified, ref, places=4)