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 ? 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.
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)
# ...
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.