[Maya] One liner to get transform nodes having a shape in them

Hi all!

I don’t remember well but I was thinking there was a direct way to get every transform nodes having a shape in them.

For now I use:

import maya.cmds as mc
for node in mc.ls(exactType='transform') :
    if not mc.listRelatives(node, shapes=True) : # skip the node if there is  no shape above it
        continue
    # deal with your transform with shapes here...

But I’m almost sure Maya provide a nice way to have such nodes in one line instead of a check.

Anyone recall this?

Big thanks in advance! :slight_smile:

this returns the transforms for all meshes in the scene…

meshTransforms = [cmds.listRelatives(i, p=True)[0] for i in cmds.ls(type='mesh')]

i’m sure with pymel its even easier, but I don’t know the syntax off the top of my head.

Thanks! Yes you could use list comprehension but I was thinking there was another Maya Command to do that.

PS: EDIT: My bad. :smiley:

I don’t think there is a combination of flags for the ls command that will return transforms for only shape nodes, but I could be wrong.

this returns all the transforms and the shapes

cmds.ls(type='mesh', tr=True) # does not satisfy OT request.

or


cmds.ls(*cmds.ls(type='camera', tr=True), type='transform')

I’m not sure what that is supposed to do Theodox. The interior ls call returns all camera shapes and all transforms, then the exterior just restricts that to transforms, which has the same result as just calling ls with the -tr flag (unless I’m mistaken).


The only thing to keep in mind with rgkovach123’s method, is that if a transform has multiple shapes under it, you will get duplicate listings of that transform. Use a set to remove duplicates. You also don’t need to use a list comprehension and can pass the result of cmds.ls straight to cmds.listRelatives

meshTransforms = list(set(cmds.listRelatives(cmds.ls(type='mesh'), p=True)))

yea, this is much better.

[QUOTE=capper;25643]I’m not sure what that is supposed to do Theodox. The interior ls call returns all camera shapes and all transforms, then the exterior just restricts that to transforms, which has the same result as just calling ls with the -tr flag (unless I’m mistaken).


The only thing to keep in mind with rgkovach123’s method, is that if a transform has multiple shapes under it, you will get duplicate listings of that transform. Use a set to remove duplicates. You also don’t need to use a list comprehension and can pass the result of cmds.ls straight to cmds.listRelatives

meshTransforms = list(set(cmds.listRelatives(cmds.ls(type='mesh'), p=True)))

[/QUOTE]

Thanks for all your answers. So no basic command to do that.
[QUOTE=capper;25643]

meshTransforms = list(set(cmds.listRelatives(cmds.ls(type='mesh'), p=True)))

[/QUOTE]
This one id very nice! :smiley:
Thanks a lot! :slight_smile:

Doh, I was testing with camera. But the outer ls removes the shapes from the results of the inner, which I thought was what OP wanted. -tr includes both shapes and transforms

Maybe I’m missing something but cmds.ls(type=‘mesh’, tr=True) returns all transforms in the scene in addition to mesh shapes. It doesn’t restrict the result to mesh transforms.

In a random scene I’m working in, I get this:

cmds.ls(cmds.ls(type='mesh', tr=True), tr=True) == cmds.ls(tr=True)
# Result: True # 

I just read rgkovachs as having transforms and shapes mixed and thought ‘oh, just filter it to transforms!’ :slight_smile: listRelatives > ls mesh is the the way to do it.

Ha yeah, that makes sense. I was more just hoping that there was some ls flag behavior that I didn’t understand yet and wasn’t fully utilizing :slight_smile: