1

I'm trying to make a simple script to, move all the children of a parent one by one to the origin, resize them a according to their size, render the image, and then put them back were they belonged.

However, I'm having a strange issue, as resizing the children apparently is also resizing the parent. The code is not running for the parent, but it's getting resized nonetheless.

Thank you.

Here's the code.

import bpy

scene = bpy.context.scene

def print_heir(ob, levels=10):

count = 0

def return_largest_element_index(array): largest = 0 largestIndex = 0 for x in range(0, len(array)): if(array[x] > largest): largest = array[x] largestIndex = x return largestIndex

def recurse(ob, parent, depth, count): if depth > levels: return count print(" " * depth, ob.name)

if ob.type == 'MESH':


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

    bpy.context.view_layer.objects.active = ob

    ob.select_set(state = True)
    bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')


    #save original positions and scale
    x = ob.matrix_world.translation.x
    y = ob.matrix_world.translation.y
    z = ob.matrix_world.translation.z
    dimensionSaved = [ob.dimensions.x, ob.dimensions.y, ob.dimensions.z]

    scaleSaved = [ob.scale.x, ob.scale.y, ob.scale.z]


    #get the multiplier for the scaling, based on the size, smaller objects get scalled more
    highestDimensionIndex = return_largest_element_index(dimensionSaved)

    multiplier = 0.5/dimensionSaved[highestDimensionIndex]

    bpy.context.view_layer.objects.active = ob
    print(bpy.context.view_layer.objects.active, "fack")

    #apply the scaling
    bpy.ops.transform.resize(value=(scaleSaved[0]*multiplier, scaleSaved[1]*multiplier, scaleSaved[2]*multiplier))

    print(bpy.context.object.scale)     

    #move to the origin
    ob.matrix_world.translation = (0, 0, 0)

    #render the image
    bpy.data.scenes["Scene"].render.filepath = "e:\Osso1\osso" + str(count)

    bpy.ops.render.render(write_still = True)

    #put the object back where it was
    ob.matrix_world.translation = (x, y, z)

    bpy.context.view_layer.objects.active = ob

    bpy.ops.transform.resize(value=(scaleSaved[0], scaleSaved[1], scaleSaved[2]))

    ob.select_set(state = False)

    count +=1

for child in ob.children:
    count = recurse(child, ob,  depth + 1, count)


return count

count = recurse(ob, ob.parent, 0, count)

root_obs = bpy.context.object

#for o in root_obs: print_heir(root_obs)

  • 2
    Firstly would do this with matrices directly without using any operators. Requiring no setting of active object mode changing etc. Can temporarily set a matrix world, de-parent, then set it back. My guess is Issue is operators work on selected objects. Your logic requires only one object is active and selected, otherwise as you select more, more are scaled via operator call etc. May be as simple as root_ob.select_set(False) – batFINGER Jul 09 '21 at 21:56
  • This was absolutely it, I wasn't aware that it was adding the original selected empty to the selection. Adding that line before the mesh check solved everything. Thanks a lot mate! Yeah, I realize now that matrices would result in cleaner code, but I was in a rush and though this method was easier, as this is the first script I'm writting. Thanks again, have a great weekend – user3742604 Jul 10 '21 at 10:43

0 Answers0