简体   繁体   English

Maya Python:匹配两个不同对象的边界框

[英]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? Python 和 Maya 中是否有更好的方法来匹配两个边界框的高度?

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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