Select all objects type mesh using python

Select all objects type mesh using python

victorgaldonv
Participant Participant
1,858 Views
6 Replies
Message 1 of 7

Select all objects type mesh using python

victorgaldonv
Participant
Participant

Hi

 I need to select objects type mesh using python. They are inside groups and I want to locate any of them which any coordinate is different from 0 (translation, rotation,scale)

 

import maya.cmds as cmds

def seleccionar_geometria_con_coordenadas_no_cero():
    # Obtener una lista de todos los nodos de geometría en la escena
    geometria = cmds.ls(geometry=True)

    # Lista para almacenar los nombres de los nodos de geometría que no tienen coordenadas x, y, z en valor 0
    geometria_no_cero = []

    # Iterar sobre cada nodo de geometría
    for geo in geometria:
        # Verificar si el objeto de geometría existe y es válido
        if cmds.objExists(geo):
            # Obtener las coordenadas de transformación del nodo de geometría
            coordenadas = cmds.xform(geo, query=True, translation=True, worldSpace=True)
            
            # Verificar si alguna de las coordenadas x, y, z no es cero
            if coordenadas and any(coordenada != 0 for coordenada in coordenadas):
                geometria_no_cero.append(geo)
        else:
            print("El objeto {} no existe o no es válido.".format(geo))

    # Seleccionar la geometría que no tiene coordenadas x, y, z en valor 0
    if geometria_no_cero:
        cmds.select(geometria_no_cero)
        print("Geometría con coordenadas no cero seleccionada.")
    else:
        print("No se encontró geometría con coordenadas no cero.")

# Llamar a la función
seleccionar_geometria_con_coordenadas_no_cero()

 

I'm getting a "No valid objects spplied to 'xform' command " with this one

0 Likes
Accepted solutions (1)
1,859 Views
6 Replies
Replies (6)
Message 2 of 7

FirespriteNate
Advocate
Advocate

Geometry "objects" in Maya are made up of two nodes, a transform parent, and a shape child (the actual geometry). You can only use xform on transforms, not shapes, so when you collect geometry with cmds.ls() you are getting a list of shapes. When you later iterate over those shapes and try to do an xform on "geo", it doesn't work as "geo" is a shape and not a transform. 

To fix this, you need to get the parent transform of your "geo" shape. You do this using the cmds.listRelatives() command. You could do this inside your for loop to every "geo", but it's simpler and quicker to do it on the original list, something like this:

 

geometria = cmds.ls(geometry=True)
transforms = cmds.listRelatives(geometria, parent=True)

 

Then you can iterate over transforms instead of geometria.

 

One other suggestion, "geometry" covers ALL object shapes (NURBS, curves, locators, etc, ) so if you don't want all that junk, and you explicitly want (poly) meshes, don't use geometry=True, use type="mesh" instead:

polyMeshes = cmds.ls(type="mesh", noIntermediate=True)
transforms = cmds.listRelatives(polyMeshes, parent=True)

(we add noIntermediate=True so that intermediate (history based) poly meshes don't get listed. trust me, you probably don't want that).

Message 3 of 7

flay02
Explorer
Explorer

 

Not sure what I'm wrong. I got the group coordinates not the meshes coordinates

 

import maya.cmds as cmds

geometria = cmds.ls(geometry=True)
all_objects = cmds.listRelatives(geometria, parent=True)

for obj in all_objects:
    positions = [cmds.xform(obj, query=True, worldSpace=True, translation=True) for obj in all_objects]
    rotations = [cmds.xform(obj, query=True, worldSpace=True, rotation=True) for obj in all_objects]
    
filtered_objects = [obj for obj, pos in zip(all_objects, positions) if pos != [0, 0, 0]]
cmds.select(filtered_objects)

print (positions)
print (rotations)
print(filtered_objects)

 

0 Likes
Message 4 of 7

flay02
Explorer
Explorer

ok, worldSpace must be false (DOH!), sorry.

 

So, this is the code I got to do the job... probably not elegant, but it works:

import maya.cmds as cmds

geometria = cmds.ls(geometry=True)
all_objects = cmds.listRelatives(geometria, parent=True)

for obj in all_objects:
    positions = [cmds.xform(obj, query=True, worldSpace=False, translation=True) for obj in all_objects]
    rotations = [cmds.xform(obj, query=True, worldSpace=False, rotation=True) for obj in all_objects]
    
filtered_objects = [obj for obj, pos in zip(all_objects, positions) if pos != [0, 0, 0]]
filtered_objects += [obj for obj, pos in zip(all_objects, rotations) if pos != [0, 0, 0]]
cmds.select(filtered_objects)
0 Likes
Message 5 of 7

victorgaldonv
Participant
Participant

It takes time to process... Could it be improved and work faster?

 

0 Likes
Message 6 of 7

FirespriteNate
Advocate
Advocate
Accepted solution

There is a mistake in flay's code, where he's for..looping over every object, and in each iteration also creating a full list of positions and rotations for every object, so it's taking exponentially longer than it should be.

If you remove the first for loop and un-indent both the position = and rotation = lines, you will speed it up considerably.

 

Also, the code is effectively looping over the objects array 4 separate times. List comprehensions are great for compactness, but if you are generating the same list comprehension multiple times, it's possibly more efficient to actually just use one for..loop. For example:

 

from maya import cmds

geometria = cmds.ls(type='mesh', ni=True)
all_objects = cmds.listRelatives(geometria, parent=True)

non_zero_objs= []
for obj in all_objects:
    if any(cmds.xform(obj, query=True, worldSpace=False, translation=True)):
        non_zero_objs.append(obj)
    if any(cmds.xform(obj, query=True, worldSpace=False, rotation=True)):
        non_zero_objs.append(obj)

cmds.select(non_zero_objs)

 

(this does both translate and rotate as per flays original example)

Message 7 of 7

victorgaldonv
Participant
Participant

Just perfect! Thanks