Maya/Python - Figuring out if an attribute is hidden or not

Hey all,

I finally dove in to learn scripting, and although I`m understanding some things while following along Eat3d’s Intro to maya scripting tutorial, I’m struggling with using the command reference to do things that aren’t in the tutorial.

The tutorial shows you how to zero out rotation on controls, and avoid the locked ones so it doesn’t crash. I was able to add in the translate as well, but my problem has come to when the controls have hidden attributes. It says the control doesnt have that attribute. Makes sense. So, onto my question.

I’ve added an if statement to look for if the attribute is hidden, but it’s coming back as attribute name not recognized. Not sure why. I don’t get the “choice” thing in the attributeQuery. What am I suppose to put there? Here’s my code. If I take out the if statement about the hidden, it all works, if none of the controls have a hidden attr.

import maya.cmds as cmds

myControls = cmds.ls(“AN_*”)
attributes = [“rotate”, “translate”]
axes = [“X”, “Y”, “Z”]

for myControl in myControls:

for attribute in attributes:
    for axis in axes:
                    
        myAttrName = myControl + "." + attribute + axis
        
        if not cmds.attributeQuery(myAttrName, typ="choice", h=True):
            
            if not cmds.getAttr(myAttrName, lock=True):
                print myAttrName
                cmds.setAttr(myAttrName, 0)

Any insight? Thanks guys.

(not sure how to add indentation in the forum. Forum seems to automatically get rid of it)

No idea about that command but you should be able to just query if the attribute is keyable to determine if its hidden or not as Maya moves stuff thats hidden to non-keyable. Also watch out for how your listing objects, there are chances you can get shapes when all you want is the transform. Easy fix just add type=“transform”. Use the code tags to paste code in.

Use the CODE tag not the QUOTE tag when sharing code. It will preserve indentation.

First off, you don’t need to use attributeQuery for this. Hidden doesn’t mean “visible in the channel box”, it means that the attribute is hidden from most UIs, and as far as I know can only be set when creating an attribute.

Attributes can be visible in the channelBox under two conditions:

  • The attribute is set to keyable (always visible in the channelBox)
  • A non-keyable attribute has been set to display using setAttr -channelBox

So if you’re trying to check whether an attribute is visible in the channel box, you have to test both of those conditions (you can’t just test cb=True because when an attribute is keyable, cb=True will return False):

if cmds.getAttr(attr, k=True) or cmds.getAttr(attr, cb=True):
    # Visible in the channelBox

Yep, I agree with capper. I’ve always used getAttr to check the majority of attribute stuff because attributeQuery always seemed to return nonsense. If it’s creation values it returns then that might finally make (marginally) more sense! :stuck_out_tongue:

To expand on capper’s point that non-keyable attributes can be visible; if you really do want to test for visibility then also check the channelBox flag.


def isAttrVisible(attrName):
    return cmds.getAttr(attrName, cb=True) or cmds.getAttr(attrName, k=True)

If either of those is True then it should be visible in the channel box.

Haha whoops Warheart, I edited the hell out of my post.

Maybe I just don’t know what attributeQuery is doing, but it’s results are weird:

node = cmds.createNode('transform')
cmds.addAttr(node, ln='myAttr', k=True)
print cmds.attributeQuery('myAttr', n=node, k=True)
cmds.setAttr('%s.myAttr' % node, k=False)
print cmds.attributeQuery('myAttr', n=node, k=True)
cmds.setAttr('%s.myAttr' % node, k=True)
print cmds.attributeQuery('myAttr', n=node, k=True)

# True
# False
# False (should be True)

[QUOTE=capper;20735]Haha whoops Warheart, I edited the hell out of my post.

Maybe I just don’t know what attributeQuery is doing, but it’s results are weird:

node = cmds.createNode('transform')
cmds.addAttr(node, ln='myAttr', k=True)
print cmds.attributeQuery('myAttr', n=node, k=True)
cmds.setAttr('%s.myAttr' % node, k=False)
print cmds.attributeQuery('myAttr', n=node, k=True)
cmds.setAttr('%s.myAttr' % node, k=True)
print cmds.attributeQuery('myAttr', n=node, k=True)

# True
# False
# False (should be True)

[/QUOTE]

After posting I messed around with it and definitely an odd command. Got the same results. Nice catch on the channelbox though, didnt think of that.

Warheart pretty much got it right about attributeQuery. From my experience, attributeQuery returns information about inherent qualities of the attribute. For instance, querying keyability of a transform’s ‘translateX’ attribute will always return true because it CAN BE keyable, whereas the same query for ‘translate’ (the double3 container attribute) will always return false, since it can never be keyed. GetAttr is the command you want if you are looking for the current state of an attribute.

Wish I’d seen this thread a while ago as I was experiencing the same problem! Now I know why! Thanks!

I use listAttr for the calls in the Red9 pack for this…



def getChannelBoxAttrs(node=None,asDict=True,incLocked=True):
    '''
    return a dict of attributes in the ChannelBox by their status
    @param node: given node
    @param asDict:  True returns a dict with keys 'keyable','locked','nonKeyable' of attrs
                    False returns a list (non ordered) of all attrs available on the channelBox
    @param incLocked: True by default - whether to include locked channels in the return (only valid if not asDict)
    '''
    statusDict={}
    if not node:
        node = cmds.ls(sl=True, l=True)[0]
    statusDict['keyable']=cmds.listAttr(node, k=True, u=True)
    statusDict['locked'] =cmds.listAttr(node, k=True, l=True)
    statusDict['nonKeyable'] =cmds.listAttr(node,cb=True)
    if asDict:
        return statusDict
    else:
        attrs=[]
        if statusDict['keyable']:
            attrs.extend( statusDict['keyable'])
        if statusDict['nonKeyable']:
            attrs.extend(statusDict['nonKeyable'])
        if incLocked and statusDict['locked']:
            attrs.extend(statusDict['locked'])
        return attrs


++ to that last one, that’s my usual method too

Hey all, long delay, but thanks for all the replies! I ended using the listAttr command like suggested and it definitely worked.

I actually got help from a friend with it as well, and he told me to check for visible, unlocked and keyable. The script worked, but I just checked, and it seems like the only thing I need to check is if its keyable. If i get rid of the other 2, it still works, even if i have something locked and hidden. No errors. So, my question for you all is if there are any situations where I would need to check for unlocked or visible, or would it just be faster / cleaner to check for only keyable?

Here’s my code before taking out the visible/unlocked check. Thanks capper for the CODE vs QUOTE tip.

#imports all of mayas MEL commands for me to use
import maya.cmds as cmds

#arrays
myControls = cmds.ls("*control")
attributes = ["rotate", "translate"]
axes = ["X", "Y", "Z"]

#iterate through all the controls
for myControl in myControls:
    
    #interate through all the attributes
    for attribute in attributes:
        
        #iterate through all the axes
        for axis in axes:
            
            #build the attribute name using the control name, the attribute name, and the axis
            myAttrName = myControl + "." + attribute + axis
            
            
            if cmds.listAttr(myAttrName, v=True, u=True, k=True):
                print myAttrName
                cmds.setAttr(myAttrName, 0)

Wish I saw this thread sooner , I love how in Maya you get 3 commands to do similar tasks =)

listAttr is another good heavy hitter in Maya.

And thanks for supporting Eat3D! Hope you’re enjoying the video and my overly nasal voice isn’t too distracting. =)

  • Luiz

ya you will find that you will be useing a lot of listAttr, getAttr, and setAttr, some of the most used functions aside from ls and the compont filters.

[QUOTE=lkruel;20942]Wish I saw this thread sooner , I love how in Maya you get 3 commands to do similar tasks =)

listAttr is another good heavy hitter in Maya.

And thanks for supporting Eat3D! Hope you’re enjoying the video and my overly nasal voice isn’t too distracting. =)

  • Luiz[/QUOTE]

ahhh! Thank you for making the tutorial. Honestly, I’ve had a BIT of action script 3 experience before, but that was 6 years ago. I mostly just do animation. Your tut has been such a big help. Ive run into a problem here or there, but you taught enough that I could problem solve and figure it out. For example, I had to reinstall maya mid way through the MEL teachings. Since MEL keeps a history, when I jumped into a later section, it wasnt working, since it didnt have the history. So I had to isolate the code, and create an array. It was the 8 minute mark in chapter 7. You set up the array differently than how you did it earlier, and I think that was just because you`re so use to doing it. Muscle memory, sort of speak. But ya, its been a killer tutorial so far. I follow along, then try and change something after. Or add something new. Whether it be a new attribute or what have you. Very very useful!

But back to my previous question. Is there a reason I need to check v, k, and u? or can I only check k and get away with it?