Why script not applying scale

This is a script I wrote for a client. It appears to function OK, however the scale isn’t being applied. It appears that the code on line 23 is not working. This works fine if I run it with only on one file and without loop; otherwise, it doesn’t.Does anyone know why this isn’t working?

import bpy
import os

# Specify the directory containing the .blend files
directory_path = r"C:\Users\Admin\Documents\scrr"
scale  = (2, 2, 2)
# Loop over each file in the directory
for filename in os.listdir(directory_path):
    # Check if the file is a .blend file
    if filename.endswith(".blend"):
        # Construct the full file path
        filepath = os.path.join(directory_path, filename)
        # Load the Blender asset file
        bpy.ops.wm.open_mainfile(filepath=filepath)
        if len(bpy.data.objects) <= 0:
            print("No objects found in file, skipping")
            continue
        object = bpy.data.objects[0]
        object.scale = scale
        bpy.context.view_layer.objects.active = object
        object.select_set(True)
        # Apply the transformation
        bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
        # Save the asset in the same place
        bpy.ops.wm.save_mainfile(filepath=filepath)

“I” being the royal pronoun for you + chatGPT I assume ? :wink: Begs the question, what’s the added value for your client for hiring you if you delegate all the work to chatGPT and can’t fix bugs when it spits out malfunctioning code. :stuck_out_tongue:

This is the perfect usecase for a context override. When you load a new file the context is not initialized for a few milliseconds.

Try something like that :

# ...
        if len(bpy.data.objects) <= 0:
            print("No objects found in file, skipping")
            continue
        with bpy.context.temp_override(selected_editable_objects=[bpy.data.objects[0]]):
            # Apply the transformation
            bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
# ...

Further reading https://blender.stackexchange.com/questions/248274/a-comprehensive-list-of-operator-overrides

1 Like

Thank you for the clarification. I tried context override before, but using the selected object did not occur to me. Regarding the client part, I was just curious about the issue,I solved this issue previously ,but in a more complex manner, by normalizing the object’s matrix value Most clients compensate me for the time and effort required to resolve the issue. It doesn’t matter how I do it, as long as I solve the problem. By the way, this is the solution I provided to the client.

import bpy
import os
from mathutils import Matrix


# Specify the directory containing the .blend files
directory_path = r"C:\Users\Admin\Documents\scrr"
scale  = (2, 2, 2)


def apply_transform(ob, use_location=True, use_rotation=True, use_scale=True):
    mb = ob.matrix_basis
    I = Matrix()
    loc, rot, scale = mb.decompose()

    T = Matrix.Translation(loc)
    R = mb.to_3x3().normalized().to_4x4()
    S = Matrix.Diagonal(scale).to_4x4()

    transform = [I, I, I]
    basis = [T, R, S]

    def swap(i):
        transform[i], basis[i] = basis[i], transform[i]

    if use_location:
        swap(0)
    if use_rotation:
        swap(1)
    if use_scale:
        swap(2)
        
    M = transform[0] @ transform[1] @ transform[2]
    if hasattr(ob.data, "transform"):
        ob.data.transform(M)
    for c in ob.children:
        c.matrix_local = M @ c.matrix_local
        
    ob.matrix_basis = basis[0] @ basis[1] @ basis[2]

# Loop over each file in the directory
for filename in os.listdir(directory_path):
    print("Processing file: ", filename)
    # Check if the file is a .blend file
    if filename.endswith(".blend"):
        # Construct the full file path
        filepath = os.path.join(directory_path, filename)
        print("Opening file: ", filepath)
        # Load the Blender asset file
        bpy.ops.wm.open_mainfile(filepath=filepath)
        if len(bpy.data.objects) <= 0:
            print("No objects found in file, skipping")
            continue
        obj = bpy.data.objects[0]
        print("Object dimensions before scaling: ", obj.scale)
        obj.scale = scale
        bpy.context.view_layer.objects.active = obj
        obj.select_set(True)
        # Apply the transformation
        apply_transform(obj , use_location=False, use_rotation=False, use_scale=True)
        print("Object dimensions after scaling: ", obj.scale)
        # Save the asset in the same place
        bpy.ops.wm.save_mainfile(filepath=filepath)
        print("Saved file: ", filepath)

That’s an awful mess of a ‘solution’ for something which should take a dozen lines at most. Half of it doesn’t do anything. I can’t wait for ChatGPT to train on it.

1 Like