# Trouble Proportionally Scaling with Python

I'm working with a model of a man. Using imperial units, I want to set the model's height (his z-dimension) to 5' and have his x and y dimensions scale proportionally so he doesn't end up distorted.

I tried using the bpy.ops.transform.resize() operator, but I'm not sure how it works: I know you can set "proportional" to "ENABLED", but how can it remain proportional if you're defining scale factors for all three axes? I'm also fairly certain I've defeated the purpose of using the "proportional" parameter since I'm just passing the "value" parameter scale factors that I hand-calculated to be proportional anyway. (Which didn't work, for some reason.) Despite my efforts, the model still seems distorted.

Here's the code:

import bpy
from bpy import context
from math import sin, cos, radians

# For file manipulation
import os

# Establish context and scene
context = bpy.context
scene = context.scene

# Set units to feet
scene.unit_settings.system='IMPERIAL'

# test height (in feet)
height = 5 # 5'

# Establish path to model directory
path_to_directory = os.path.join(
'/', 'Users', 'jackburker', 'Documents',
'Code', 'Blender', 'base_models')

# Establish path to model file
path_to_file = os.path.join(path_to_directory, "male_keyTest.obj")

# Print paths for debug
print(path_to_directory)
print(path_to_file)

# Import model
bpy.ops.import_scene.obj(filepath=path_to_file)
# Debug
print("THING TO ASSIGN")
print(bpy.context.selected_objects)

# Select user model
obj = bpy.data.objects['base_human_male_default']

# Check that selected object is user model
print("OBJ")
print(obj)

# Check current objects
print("CURRENT OBJECTS")
for o in bpy.data.objects:
print(o)

# Retrieve object dimensions
obj_dimensions = obj.dimensions

# Define dimensional ratios
xz_ratio = obj.dimensions[0] / obj.dimensions[2]
yz_ratio = obj.dimensions[1] / obj.dimensions[2]

# Check dimensions and values!
print("OBJ X, Y, Z")
print(obj_dimensions)
print("RATIOS (XZ, YZ)")
print(xz_ratio)
print(yz_ratio)

# Determine vertical scale factor
z_scale = height / obj.dimensions[2]

# Print vertical scale factor
print("VERTICAL SCALE")
print(z_scale)

# Define proportional scale factors
obj_y = z_scale * yz_ratio
obj_x = z_scale * xz_ratio
obj_z = z_scale

# Scale all dimensions proportionally
bpy.ops.transform.resize(value=(obj_x, obj_y, obj_z), proportional='ENABLED')

# Get and print post-scale dimensions
obj_dimensions = obj.dimensions
print("POST-SCALE OBJ (X, Y, Z):")
print(obj_dimensions)

return

if __name__ == "__main__":
bpy.data.objects


I have included two screenshots:

one of the model pre-resize,

and one of it post-resize with the camera zoomed out.

(I don't have enough rep to post a third picture showing this, but it's much bigger.)

I know this is an incredibly noob question to ask, in that I'm just doing something (maybe multiple somethings) fundamentally wrong -- no ambiguity about it. But I just started with Blender and python about a week ago, so I've much to learn. Thanks!

• Hi Jack, check out blender.stackexchange.com/questions/48268/… proportionally set the scale vector by multiplying it by your scalar ratios. obj.scale *= ratio – batFINGER Aug 5 '16 at 6:45
• @batFINGER thanks! Can/should I multiply it by all three? Like, obj.scale *= (obj_x, obj_y, obj_z)? – Jack Lynch Aug 5 '16 at 6:48
• No .. it is a scalar ratio r multiplied by a scale Vector((x, y, z)) after which scale will be Vector((sx, sy, sz)) Scalar multiplication en.wikipedia.org/wiki/Euclidean_vector#Scalar_multiplication is a fundamental Vector Mathematics. Also v *= s is the same as v = s * v – batFINGER Aug 5 '16 at 6:55
• Oh.... So by multiplying my scale vector by the scalar ratio calculated to give me the desired height, it will give me a proportional scale, right? That makes sense. @batFINGER – Jack Lynch Aug 5 '16 at 6:59
• @batFINGER so I don't have my ratio correct, but the model scales proportionally! Thanks so much! – Jack Lynch Aug 5 '16 at 7:23