简体   繁体   中英

Maya Python: matching the bounding boxes of two different objects

I have two objects that will always have random different bounding box sizes, particularly heights. But both will have the pivot at the origin.

I want to match, via scaling, one objects bounding box height with the other's. But I can only think of gradually scaling the smaller one up by very small increments. That seems a little tedious and sub-optimal.

Is there a better way within Python and Maya to match the height of the two bounding boxes?

You should be able to take the height of the larger object and divide it by the height of the smaller object to get a scale factor to use on the smaller object.

very very simple example (in pseudo code):

objectA height = 20  
objectB height = 10  
20 / 10 = 2 (so, scale objectB by 2 to match the height)

Your actual code will be a matter of extracting the height from each bounding box, comparing the heights to determine the smaller object and scale factor, and then scaling the smaller one. Hope that helps!

Here are two functions that will scale a given set of objects to a second set of object's combined bounding box size. (Works with individual objects as well)

The first function will scale each given object individually to match the second group of object's bounding box:

def matchScale(to, frm):
'''Scale each of the given objects to the bounding box of a second set of objects.

:Parameters:
    to (str)(obj)(list) = The object(s) to scale.
    frm (str)(obj)(list) = The object(s) to get a bounding box size from.

:Return:
    (list) scale as x,y,z.
'''
xmin, ymin, zmin, xmax, ymax, zmax = pm.exactWorldBoundingBox(frm)
ax, ay, az = aBoundBox = [xmax-xmin, ymax-ymin, zmax-zmin]

for obj in pm.ls(to, flatten=True):

    xmin, ymin, zmin, xmax, ymax, zmax = pm.exactWorldBoundingBox(obj)
    bx, by, bz = bBoundBox = [xmax-xmin, ymax-ymin, zmax-zmin]

    oldx, oldy, oldz = bScaleOld = pm.xform(obj, q=1, scale=1)
    diffx, diffy, diffz = boundDifference = [ax/bx, ay/by, az/bz]
    bScaleNew = [oldx*diffx, oldy*diffy, oldz*diffz]

    pm.xform(obj, scale=bScaleNew)

return bScaleNew

The second function changes the behavior slightly in that the objects are scaled as a group:

def matchScale(to, frm):
'''Scale combined objects to the bounding box of a second set of objects.

:Parameters:
    to (str)(obj)(list) = The object(s) to scale.
    frm (str)(obj)(list) = The object(s) to get a bounding box size from.

:Return:
    (list) scale as x,y,z.
'''
xmin, ymin, zmin, xmax, ymax, zmax = pm.exactWorldBoundingBox(frm)
ax, ay, az = aBoundBox = [xmax-xmin, ymax-ymin, zmax-zmin]

xmin, ymin, zmin, xmax, ymax, zmax = pm.exactWorldBoundingBox(to)
bx, by, bz = bBoundBox = [xmax-xmin, ymax-ymin, zmax-zmin]

frm = pm.ls(frm, flatten=True)
oldx, oldy, oldz = bScaleOld = [
    sum([pm.xform(o, q=1, s=1)[0::3][0] for o in frm]), 
    sum([pm.xform(o, q=1, s=1)[1::3][0] for o in frm]),     
    sum([pm.xform(o, q=1, s=1)[2::3][0] for o in frm])
]

diffx, diffy, diffz = boundDifference = [ax/bx, ay/by, az/bz]
bScaleNew = [oldx*diffx, oldy*diffy, oldz*diffz]

[pm.xform(o, scale=bScaleNew) for o in pm.ls(to, flatten=True)]

return bScaleNew

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM