When you use operators like:
bpy.ops.object.transform_apply
they are acting on the selected objects so you need to select each object before calling it.
Apply all transforms to scene mesh objects
import bpy
scene = bpy.context.scene
objects = scene.objects
for obj in objects:
if obj.type=="MESH":
obj.select = True
else:
obj.select = False
# As this operator works on all selected objects not just the active one we
# only need to call it once here instead of within the for loop, this will also be faster.
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
and you can replace:
for obj in objects:
if obj.type=="MESH":
obj.select = True
else:
obj.select = False
with:
for obj in objects:
obj.select = True if obj.type == "MESH" else False
Although that won’t make your code any faster. Here is a basic example of an operator that I think will do everything you’ve asked:
#TO RUN:
# Object Mode->[space_bar]->Test Example Operator
import bpy
from bpy.props import *
import math
class ExampleOperator(bpy.types.Operator):
bl_idname = "object.example_operator"
bl_label = "Test Example Operator"
bl_options = {'REGISTER', 'UNDO'}
ob_types = [('ALL_TYPES', "All Types", "", 1),
('MESH', "Meshes Only", "", 2),
('CURVE', "Curves Only", "", 3)]
# Filter
object_type = EnumProperty(items=ob_types, name="Object Types", default='ALL_TYPES')
selected_only = BoolProperty(name="Selected Only",
description="Apply only to the selected object(s) otherwise apply to \
all scene objects of the specified object type.",
default=True)
origin_types = [('GEOMETRY_ORIGIN', "GEOMETRY_ORIGIN", "", 1),
('ORIGIN_GEOMETRY', "ORIGIN_GEOMETRY", "", 2),
('ORIGIN_CURSOR', "ORIGIN_CURSOR", "", 3),
('ORIGIN_CENTER_OF_MASS', "ORIGIN_CENTER_OF_MASS", "", 4)]
origin_type = EnumProperty(items=origin_types,
name="Origin Set To",
default="ORIGIN_GEOMETRY")
location = BoolProperty(name="Location", default=False)
rotation = BoolProperty(name="Rotation", default=True)
scale = BoolProperty(name="Scale", default=True)
autosmooth_angle = FloatProperty(name="Auto Smooth Angle", subtype='ANGLE', default=math.radians(37.0))
@classmethod
def poll(cls, context):
return True if context.mode == 'OBJECT' else False
def execute(self, context):
scene = bpy.context.scene
objects = context.selected_objects if self.selected_only else scene.objects
if self.object_type == 'ALL_TYPES':
if not self.selected_only: # No point reselecting as we used context.selected_objects
for obj in objects:
obj.select = True
else:
for obj in objects:
obj.select = True if obj.type == self.object_type else False
#bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.origin_set(type=self.origin_type)
bpy.ops.object.transform_apply(location=self.location, rotation=self.rotation, scale=self.scale)
bpy.ops.object.shade_smooth()
mesh_objects = [ob for ob in objects if ob.type == 'MESH']
for ob in mesh_objects:
mesh = ob.data
mesh.use_auto_smooth = True
mesh.auto_smooth_angle = self.autosmooth_angle
mesh.show_normal_face = True
scene.objects.active = ob # Make this object the active one
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.normals_make_consistent()
bpy.ops.object.mode_set(mode='OBJECT')
return {'FINISHED'}
def register():
bpy.utils.register_class(ExampleOperator)
def unregister():
bpy.utils.unregister_class(ExampleOperator)
if __name__ == '__main__':
register()
Hope it helps!