1
$\begingroup$

In the MWE (Minimal Working Example) below I created 4 spheres and placed them at 4 different locations along the Y-axis. I would like to scale each sphere as per my wish (lets say 2 in the X,Y,Z).

import bpy

bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False, confirm=False)

bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(0, 2.5, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(0, 5, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(0, 7.5, 0), scale=(1, 1, 1))

bpy.ops.object.select_all(action='DESELECT')
bpy.ops.object.select_by_type(type="MESH")   
bpy.ops.object.join() 

bpy.ops.object.mode_set(mode='EDIT')

bpy.context.tool_settings.transform_pivot_point = 'INDIVIDUAL_ORIGINS'

bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.transform.resize(value=(2, 2, 2))

I'm scaling the spheres in Edit Mode using INDIVIDUAL_ORIGINS where the center of the spheres should have stayed exactly where they currently are and scale by a factor of 2. But somehow this is not respected, and looks like BOUNDING_BOX_CENTER is used instead. How can I achieve that using python scripting? Though I can use the scale function in the MWE for each individual sphere, in my actual case there exist several thousands of spheres and individually scaling each sphere is out of reach.

Also how can I scale the objects (spheres in my example) that lie between certain specific coordinates? For example, I just want to scale the spheres whose centers are engulfed between (0,2,0) to (0,6,0) i.e only spheres 2, 3 are scaled and the spheres 1, 4 remain unscaled?

I am using Blender version 3.3.1 for reference.

$\endgroup$
1
  • $\begingroup$ very interesting. it seems that even when setting bpy.context.tool_settings.transform_pivot_point = 'INDIVIDUAL_ORIGINS', it is not being respected when doing bpy.ops.transform.resize(value=(2, 2, 2)) in Edit Mode. It sticks to BOUNDING_BOX_CENTER $\endgroup$
    – Harry McKenzie
    Commented Jul 23, 2023 at 15:50

1 Answer 1

1
$\begingroup$

Though not a complete answer, a partial solution to the first part of the question regarding scaling of the objects from the objects respective centers (I should accept the fact that the procedure used is not elegant though):

import bpy

bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False, confirm=False)

bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(0, 2.5, 0), scale=(1.25, 1.25, 1.25))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(0, 5, 0), scale=(2, 2, 2))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(0, 7.5, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(0, 10, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(0, 12.5, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(0, 15, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(0, 17.5, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(0, 20, 0), scale=(1, 1, 1))

bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(5, 0, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(5, 2.5, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(5, 5, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(5, 7.5, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(5, 10, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(5, 12.5, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(5, 15, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(5, 17.5, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_uv_sphere_add(enter_editmode=False, align='WORLD', location=(5, 20, 0), scale=(1, 1, 1))

bpy.ops.object.select_all(action='DESELECT')

cnt_1digits = 0
while cnt_1digits >= 0 and cnt_1digits < 10:
    cnt_1digits+=1
    test_str1 = "Sphere.00"
    res1 = test_str1 + str(cnt_1digits)
    for o in (res1,""):
        obj = bpy.context.scene.objects.get(o)
        if obj:
            obj.select_set(True)
            obj.scale=(2,2.,2.)

 cnt_2digits = 9
 while cnt_2digits > 8 and cnt_2digits < 100:
     cnt_2digits+=1
     test_str2 = "Sphere.0"
     res2 = test_str2 + str(cnt_2digits)
     for o in (res2,""):
         obj = bpy.context.scene.objects.get(o)
         if obj:
            obj.select_set(True)
            obj.scale=(1,1.,1.)
        
 cnt_3digits = 99
 while cnt_3digits > 98 and cnt_3digits < 110:
     cnt_3digits+=1
     test_str3 = "Sphere."
     res3 = test_str3 + str(cnt_3digits)
     for o in (res3,""):
         obj = bpy.context.scene.objects.get(o)
         if obj:
            obj.select_set(True)
            obj.scale=(1.,1.,1.)
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .