1
$\begingroup$

I have two objects, one of them is an armature and the other is a mesh. I want to scale the mesh using it's bounding box so that the bounding box y length matches the bounding box y of the armature object using python.

This is the mesh and the armature:

enter image description here

This is what I want to do where the mesh object was proportionally scaled using the bounding boxes y dimensions:

enter image description here

My .blend file can be found here:

$\endgroup$
5
$\begingroup$

The bounding box corresponds to a property named 'dimensions'.

So, take the dimensions of each (eventually converted to world coordinates as in your blend file, objects are rotated), calculate the ratio and scale Suzanne by the ratio:

Edit following the comments:

We don't use the world matrix directly, as we only need the rotation part, because the dimensions are already scaled (as said by batFINGER in the comments). So we keep the quaternion.

The abs() is used because the rotations may return a negative value (and we don't want that for dimensions)

Script for Blender 2.79 and below

import bpy

suz = bpy.data.objects['Suzanne']
arm = bpy.data.objects['Armature']

#Convert to world coordinates if you want to use world Y
suzBound = suz.matrix_world.to_quaternion() * suz.dimensions
armBound = arm.matrix_world.to_quaternion() * arm.dimensions

ratio = abs(armBound.y) / abs(suzBound.y)

suz.scale *= ratio

Script for Blender 2.80 and above

import bpy

suz = bpy.data.objects['Suzanne']
arm = bpy.data.objects['Armature']

# Convert to world coordinates if you want to use world Y
# We now use @ instead of * as per https://wiki.blender.org/wiki/Reference/Release_Notes/2.80/Python_API#Matrix_Multiplication
suzBound = suz.matrix_world.to_quaternion() @ suz.dimensions
armBound = arm.matrix_world.to_quaternion() @ arm.dimensions

ratio = abs(armBound.y) / abs(suzBound.y)

suz.scale *= ratio

End of the edit

Just for your information, note that we are talking about bounding boxes here. If the object were rotated differently, that is different than talking about their size along an axis. For instance, this size:

enter image description here

| improve this answer | |
$\endgroup$
  • $\begingroup$ what if my armature had scale and rotation and I don't want to apply them? this is my case and the suzzanne becomes very large $\endgroup$ – Tak Feb 26 '17 at 12:15
  • $\begingroup$ Considering the scale is homogeneous in x, y, z, use "suz.scale *= ratio * suz.scale.x" $\endgroup$ – lemon Feb 26 '17 at 12:28
  • $\begingroup$ I tried it but it didn't work, still the bounding box is very big $\endgroup$ – Tak Feb 26 '17 at 12:33
  • $\begingroup$ It works here. The code of the last comment may replace the last line of the code in the answer $\endgroup$ – lemon Feb 26 '17 at 12:38
  • 3
    $\begingroup$ Not sure about the use of obj.matrix_world * obj.dimensions. For instance if the object is scaled, the dimensions change accordingly. Multiplying by the matrix_world will apply that scale factor again. $\endgroup$ – batFINGER Feb 26 '17 at 12:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.