Can anyone help me? Is it possible to make a script with Python to automatically select every object in Maya's viewport?
Is it possible?
It's very possible though you have to use Maya's api to do it. You can use OpenMayaUI.MDrawTraversal
to collect all objects within a camera's frustum.
This may seem more long winded than using OpenMaya.MGlobal.selectFromScreen
, but it gives you a few benefits:
OpenMaya.MGlobal.selectFromScreen
will be interface dependent, meaning that it's not possible to execute it on Maya batch jobs. This will work on either case.That being said, here's an example that will create a bunch of random boxes, create a camera looking at them, then select all boxes that are within the camera's view:
import random
import maya.cmds as cmds
import maya.OpenMaya as OpenMaya
import maya.OpenMayaUI as OpenMayaUI
# Create a new camera.
cam, cam_shape = cmds.camera()
cmds.move(15, 10, 15, cam)
cmds.rotate(-25, 45, 0, cam)
cmds.setAttr("{}.focalLength".format(cam), 70)
cmds.setAttr("{}.displayCameraFrustum".format(cam), True)
# Create a bunch of boxes at random positions.
val = 10
for i in range(50):
new_cube, _ = cmds.polyCube()
cmds.move(random.uniform(-val, val), random.uniform(-val, val), random.uniform(-val, val), new_cube)
# Add camera to MDagPath.
mdag_path = OpenMaya.MDagPath()
sel = OpenMaya.MSelectionList()
sel.add(cam)
sel.getDagPath(0, mdag_path)
# Create frustum object with camera.
draw_traversal = OpenMayaUI.MDrawTraversal()
draw_traversal.setFrustum(mdag_path, cmds.getAttr("defaultResolution.width"), cmds.getAttr("defaultResolution.height")) # Use render's resolution.
draw_traversal.traverse() # Traverse scene to get all objects in the camera's view.
frustum_objs = []
# Loop through objects within frustum.
for i in range(draw_traversal.numberOfItems()):
# It will return shapes at first, so we need to fetch its transform.
shape_dag_path = OpenMaya.MDagPath()
draw_traversal.itemPath(i, shape_dag_path)
transform_dag_path = OpenMaya.MDagPath()
OpenMaya.MDagPath.getAPathTo(shape_dag_path.transform(), transform_dag_path)
# Get object's long name and make sure it's a valid transform.
obj = transform_dag_path.fullPathName()
if cmds.objExists(obj):
frustum_objs.append(obj)
# At this point we have a list of objects that we can filter by type and do whatever we want.
# In this case just select them.
cmds.select(frustum_objs)
Hope that gives you a better direction.