The xform
command has a limitation due to its architecture:
This command can only work with a transform node, and only with a single transform node…
Instead of:
bbx = cmds.xform( obj, q=True, wd=True, bbi=True )
you can use:
bbx = cmds.exactWorldBoundingBox( obj, ii=False, ce=False )
MAYA HELP : exactWorldBoundingBox
This command figures out an exact-fit bounding box for the specified objects (or selected objects if none are specified) This bounding box is always in world space.
exactWorldBoundingBox( [dagObject...] , [calculateExactly=boolean], [ignoreInvisible=boolean])
Flags:
calculateExactly(ce)
boolean, create mode
Should the bounding box calculation be exact?
ignoreInvisible(ii)
boolean, create mode
Should the bounding box calculation include or exclude invisible objects?
Python example:
sel = ['set1', 'set2', 'pCube1', 'pCubeShape2', 'group1', 'spotLight1', 'directionalLight1']
bbox = cmds.exactWorldBoundingBox( sel, ignoreInvisible = False, calculateExactly = False)
The calculateWorldBoundingBox
command can correctly return the bounding box for invisible objects.
When the calculateExactly
flag is disabled, the bounding box calculation is very fast (this is important when you are passing thousands of objects as an argument).
And most importantly, the calculateWorldBoundingBox
command can take almost any combination of objects as an argument: you can pass the name of the set (s) either individually or together with a list of transformation nodes and mesh nodes.
import maya.cmds as cmds
import maya.api.OpenMaya as om
def generate_bbox( goal_obj ):
exWBB = cmds.exactWorldBoundingBox(goal_obj, ii = False, ce = False)
# We substitute the received values in the Maya API MBoundingBox.
# This will allow us to obtain, without additional calculations,
# such properties of the bounding box as:
# width - Width (size in X) of bounding box.
# height - Height (size in Y) of bounding box.
# depth - Depth (size in Z) of bounding box.
# center - Center of bounding box.
# max - Bounding box's maximum values.
# min - Bounding box's minimum values.
bbox = om.MBoundingBox(om.MPoint(exWBB[0], exWBB[1], exWBB[2], 1),
om.MPoint(exWBB[3], exWBB[4], exWBB[5], 1))
# Let's create a polycube and get a string of its name.
# For best performance, disable construction history and disable UV creation.
poly_cube = cmds.polyCube(constructionHistory = False,
createUVs = False,
texture = False,
name = 'LOD_BBox_0001',
width = bbox.width,
height = bbox.height,
depth = bbox.depth)[0]
cmds.xform('{}.vtx[*]'.format(poly_cube),
relative = True,
translation = [bbox.center.x, bbox.center.y, bbox.center.z])
# To improve performance, turn off shading and texturing
# and assign a more saturated color to the wireframe.
cmds.setAttr('{}.overrideEnabled'.format(poly_cube), 1)
cmds.setAttr('{}.overrideShading'.format(poly_cube), 0)
cmds.setAttr('{}.overrideTexturing'.format(poly_cube), 0)
cmds.setAttr('{}.overrideColor'.format(poly_cube), 17)
generate_bbox( sel )