Search code examples
pythonmaya

Get Resolution for each Render Layer


I want to get the Rendering Resolution for each Renderlayer in my Maya Project. I am using Maya 2016 with SP 5.

I know that you can get the Resolution of the current selected Renderlayer with the following commands:

width = maya.cmds.getAttr("defaultResolution.width")
height = maya.cmds.getAttr("defaultResolution.height")

Now, I want the resolutions for all Renderlayers. You would think it's as simple as writing a loop, a recursive function or working with the event "renderLayerManagerChange" or the condition "isCurrentRenderLayerChanging" would work, but it doesn't. Or alternatively, I can't find out how.

Lets assume I have 2 Renderlayers. "defaultRenderLayer" has the default resolution 960x540, The layer "layer1" has overrides for its resolution settings, and thus has the resolution 1920x1080.

This is what I get with a for loop:

renderlayers = cmds.ls(type="renderLayer")
        for layer in renderlayers:
            print layer
            #select the render layer
            cmds.editRenderLayerGlobals(crl=layer)
            #get resolution values
            w = cmds.getAttr("defaultResolution.width")
            h = cmds.getAttr("defaultResolution.height")
            print str(w),"x",str(h)

Output (depends on which Renderlayer I already have selected manually through the Maya UI):

defaultRenderLayer
1920 x 1080
layer1
1920 x 1080

It's the same deal with a recursive function, so I will skip this part.

Now, working with the events/conditions seems more promising. I assume that selecting the RenderLayer takes up some time, which means that the for-loop/recursive function is simply too quick or something.

Here is an example with the suggested Condition from the docs:

def updateClicked(self):
        print "update"

        self.layerchanged_event = cmds.scriptJob(ct=["isCurrentRenderLayerChanging", self.onLayerChange])
        self.renderlayers = cmds.ls(type="renderLayer")
        self.index = 0
        self.updating = True
        cmds.editRenderLayerGlobals(crl=self.renderlayers[0])

    def onLayerChange(self):
        if self.updating == True:
            currentlayer = cmds.editRenderLayerGlobals(q=True,crl=True)
            print currentlayer
            w = cmds.getAttr("defaultResolution.width")
            h = cmds.getAttr("defaultResolution.height")
            print str(w),"x",str(h)
            next = self.index+1
            if next == len(self.renderlayers):
                print "done"
                self.updating = False
            else:
                cmds.editRenderLayerGlobals(crl=self.renderlayers[next])

The Output I get from this:

update
defaultRenderLayer
1920 x 1080

For this example I had the "layer1" Layer selected. As you can see, the wrong resolution gets returned despite correctly showing that the current Render Layer is "defaultRenderLayer", and the "layer1" doesn't even get selected at all.

I've also tried to call cmds.refresh() every time I select a Render Layer, but to no avail. Calling the mel command layerEditorLayerButtonSelect 0 layer1 (or any other layer in fact) just gives me an error layerEditor.mel line 5366: Invalid layer type: Render

No matter what I try, I can't seem to get a list of resolutions for each Renderlayer. But why? What else could I try?


Solution

  • you could try evalDeferred() command.

    def test():
        renderlayers = cmds.ls(type="renderLayer")
        for layer in renderlayers:
            print layer
            #select the render layer
            cmds.editRenderLayerGlobals(crl=layer)
            #get resolution values
            w = cmds.getAttr("defaultResolution.width")
            h = cmds.getAttr("defaultResolution.height")
            print str(w),"x",str(h)
    cmds.evalDeferred('test()')