3

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?

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220

2 Answers2

5

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:

  1. You can do it on any camera, despite it not being used as an active view.
  2. You can perform whatever you need to do all in memory without selecting and forcing a redraw.
  3. 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.

Green Cell
  • 4,677
  • 2
  • 18
  • 49
4

you can try the following script

import maya.OpenMaya as om
import maya.OpenMayaUI as omUI
view = omUI.M3dView.active3dView()
om.MGlobal.selectFromScreen( 0, 0, view.portWidth(), view.portHeight(),om.MGlobal.kReplaceList)

I found this snippet on https://forums.cgsociety.org/t/list-objects-in-viewport/1463426, and it seems to do the trick. You can read through the discussion for more information

burned_fenrir
  • 138
  • 2
  • 13