0
$\begingroup$

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'

# Load object
def model_loader(scene):

    # 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__":
    model_loader(scene)
    bpy.data.objects

I have included two screenshots:

one of the model pre-resize,

pre-resize

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

enter image description here

(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!

$\endgroup$
  • 1
    $\begingroup$ Hi Jack, check out blender.stackexchange.com/questions/48268/… proportionally set the scale vector by multiplying it by your scalar ratios. obj.scale *= ratio $\endgroup$ – batFINGER Aug 5 '16 at 6:45
  • $\begingroup$ @batFINGER thanks! Can/should I multiply it by all three? Like, obj.scale *= (obj_x, obj_y, obj_z)? $\endgroup$ – Jack Lynch Aug 5 '16 at 6:48
  • 1
    $\begingroup$ 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 $\endgroup$ – batFINGER Aug 5 '16 at 6:55
  • $\begingroup$ 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 $\endgroup$ – Jack Lynch Aug 5 '16 at 6:59
  • $\begingroup$ @batFINGER so I don't have my ratio correct, but the model scales proportionally! Thanks so much! $\endgroup$ – Jack Lynch Aug 5 '16 at 7:23
1
$\begingroup$

In the comments, @batFINGER pointed out that I could achieve what I was looking for by multiplying the object's "scale" parameter by the ratio required to give me the correct height: e.g., obj.scale *= ratio. This worked perfectly for me. See the comments for a slightly more in-depth discussion.

$\endgroup$

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.