Community
Maya Shading, Lighting and Rendering
Welcome to Autodesk’s Maya Forums. Share your knowledge, ask questions, and explore popular Maya materials topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Get original value of attribute overridden by render setup layer

5 REPLIES 5
SOLVED
Reply
Message 1 of 6
Anonymous
1290 Views, 5 Replies

Get original value of attribute overridden by render setup layer

If an attribute in maya is being overridden by a render setup layer, is there a way to get the base, non-overridden value of that attribute without switching to the default render layer? So, for example, if the start frame in the render globals is set to 0, but my current render setup layer is applying an absolute override setting it to 100, is there a way to access the original value without changing the current layer in maya?

 

Ultimately I want to be able to query the value of an attribute in a layer that is not the current layer (for the purposes of sending tasks to a render farm). I don't want to change the active layer in maya as that can be slow with a lot of layers, and I want to avoid making changes to the scene if possible. I've been using the render setup python api to query overrides, but I've not yet found a way to find the original value if the currently active layer is overriding the value I'm trying to query in a different layer.

 

This is the code I'm using to get the value currently:

def getAttrForSetupLayer(node, attr, setupLayer):        
  import maya.app.renderSetup.model.renderSetup as renderSetup
  import maya.cmds as cmds
  renderSetupHandler = renderSetup.instance()

# get the current value of the attribute
result = cmds.getAttr("{0}.{1}".format(node, attr)) # apply overrides if cmds.objExists(setupLayer) and cmds.nodeType(setupLayer) == "renderSetupLayer": try: currentLayerObject = renderSetupHandler.getRenderLayer(setupLayer) except Exception as err: log.error("could not get current layer object for {0}: {1}".format(setupLayer, err)) currentLayerObject = None if currentLayerObject is not None: layerCollections = currentLayerObject.getCollections() for coll in layerCollections: collectionOverrides = coll.getOverrides() for override in collectionOverrides: # not all override types have targetNodeName, so catch exceptions try: targetNode = override.targetNodeName() targetAttr = override.attributeName() except: continue if targetNode == node and targetAttr == attr: if override.typeName() == "relUniqueOverride": mult = override.getMultiply() offset = override.getOffset() result = result*mult+offset else: try: result = override.getAttrValue() except Exception as err: log.error("could not get override for {0}.{1} on layer {2}: {3}".format(node, attr, setupLayer, err))

However, this only works if there is no override on the attribute in the current layer. If the override in the current layer is a relative attribute, I can work back and get the original value, but if it's absolute I can't find a way to do it, and having to 'work back' doesn't seem like an ideal solution anyway.

 

I'm still learning the ropes of the render setup api - I hope someone can point me in the right direction!

 

Thanks!

5 REPLIES 5
Message 2 of 6
cheng_xi_li
in reply to: Anonymous

Hi,

 

You could find the node connected to the attrValue of the override node.

 

There is an original attribute stores original value in that node.

 

e.g.

import maya.app.renderSetup.model.collection as collection
import maya.app.renderSetup.model.renderLayer as renderLayer
import maya.app.renderSetup.model.renderSetup as renderSetup
import maya.cmds as cmds
import maya.api.OpenMaya as om
rs = renderSetup.instance()  

layers = rs.getRenderLayers()

for layer in layers:
    collections  = layer.getCollections()
    for collection in collections:
        name = collection.name()
        overrides = collection.getOverrides()
        for override in overrides:
            obj = override.thisMObject()
            fn = om.MFnDependencyNode(obj)
            plug = fn.findPlug('attrValue', True)
            overridden = override.getOverridden()
            mobj = overridden[0][0]
            pname = overridden[0][1]
            mfn = om.MFnDependencyNode(mobj)
            connectedToPlugs = plug.connectedTo(False,True)
            for c in connectedToPlugs:
                node = c.node()
                fnAttr = om.MFnDependencyNode(node)
                originalPlug = fnAttr.findPlug('original', True)
                valuePlug = fnAttr.findPlug('value', True)
                print mfn.name()+"."+pname,'original',originalPlug.asDouble(),'new',valuePlug.asDouble()
            

 

Result

 

 

pSphere1.translateX original 1.0 new 3.0

Hope it helps.

 

Yours,

Li 

 

Message 3 of 6
Anonymous
in reply to: cheng_xi_li

That works great for absolute overrides, thanks! It doesn't work for relative overrides though (fails finding the attrValue plug) - what plug would I need to query in this case?

Message 4 of 6
Anonymous
in reply to: cheng_xi_li

There also seem to be other situations where this doesn't work, for instance with an absolute override on defaultRenderGlobals.endFrame it fails on this line: originalPlug = fnAttr.findPlug('original', True)

Message 5 of 6
cheng_xi_li
in reply to: Anonymous

Hi,

 

Relative override nodes and apply nodes are having different attributes, you'll need to use them instead.

 

There is a unitConversion node between endFrame override node and apply override node. So, we'll need to use MItDependencyGraph to get the apply override node here. I did some hack here by checking apiType. Because renderSetup is a plugin, so it should have kPluginDependNode apiType. Once we find it, we could get values from it.

 

import maya.app.renderSetup.model.collection as collection
import maya.app.renderSetup.model.renderLayer as renderLayer
import maya.app.renderSetup.model.renderSetup as renderSetup
import maya.cmds as cmds
import maya.api.OpenMaya as om
rs = renderSetup.instance()  

layers = rs.getRenderLayers()

def getOriginalValue(typeName, overridden, connectedToPlugs, isRel):
    mobj = overridden[0][0]
    pname = overridden[0][1]
    mfn = om.MFnDependencyNode(mobj)
    for c in connectedToPlugs:
        node = c.node()
        #There is a time conversion between overridden node and apply override node. We'll use MItDependencyGraph to find it. I assume there are only no custom plugins between them.
        if node.apiTypeStr != 'kPluginDependNode':
           dgIt = om.MItDependencyGraph(mobj, om.MFn.kPluginDependNode, om.MItDependencyGraph.kUpstream, om.MItDependencyGraph.kBreadthFirst, om.MItDependencyGraph.kNodeLevel)
           node = dgIt.currentNode()
        fnAttr = om.MFnDependencyNode(node)
        originalPlug = fnAttr.findPlug('original', True)
        originalValue = originalPlug.asDouble()
        newValue = 0.0
        if not isRel:
            valuePlug = fnAttr.findPlug('value', True)
            newValue = valuePlug.asDouble()
        else:
            multiplyPlug = fnAttr.findPlug('multiply', True)
            offsetPlug = fnAttr.findPlug('offset', True)
            newValue = originalValue * multiplyPlug.asDouble() + offsetPlug.asDouble()
        print typeName,mfn.name()+"."+pname,'original',originalValue,'new',newValue
    

for layer in layers:
    collections  = layer.getCollections()
    for collection in collections:
        name = collection.name()
        overrides = collection.getOverrides()
        for override in overrides:
            obj = override.thisMObject()
            fn = om.MFnDependencyNode(obj)
            typeName =  fn.typeName
            overridden = override.getOverridden()           
            targetPlug = 'attrValue' 
            isRel = False
            if typeName[0:3] == 'rel':
                targetPlug = 'offset'
                isRel = True
            plug = fn.findPlug(targetPlug, True)   
            connectedToPlugs = plug.connectedTo(False,True)     
            getOriginalValue(typeName, overridden, connectedToPlugs, isRel)

Result:

absUniqueOverride defaultRenderGlobals.endFrame original 100.0 new 200.0
relOverride pSphere1.translateX original 4.0 new 6.0

Hope it helps.

 

Yours,

Li

 

Message 6 of 6
Anonymous
in reply to: cheng_xi_li

Thanks very much! I just had one issue that I managed to resolve: if there is an override on both the start and frames, the dg iterator will fail to find the correct node (it returns the same plug for both attributes), so I changed it to:

dgIt = om.MItDependencyGraph(mfn.findPlug(pname, True), om.MFn.kPluginDependNode, om.MItDependencyGraph.kUpstream, om.MItDependencyGraph.kBreadthFirst, om.MItDependencyGraph.kNodeLevel)

With this change I'm able to extract the values I need. Thanks!

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report