Basic Scripts (No UI)¶
Some times, you don’t need a UI but just a button to run some code.
Following are some example scripts to help you get started.
1. Select All Animated Objects
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import bpy animated_objs = [] for material in bpy.data.materials: if material.animation_data: for obj in bpy.data.objects: for slot in obj.material_slots: if slot.material == material: animated_objs.append(obj) for obj in bpy.data.objects: if obj.animation_data: animated_objs.append(obj) for obj in animated_objs: obj.select_set(True)
2. Set Animation Range to selected object/s animation range
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import bpy import math # get keyframes of object list def get_keyframes(obj_list): keyframes = [] for obj in obj_list: anim = obj.animation_data if anim is not None and anim.action is not None: for fcu in anim.action.fcurves: for keyframe in fcu.keyframe_points: x, y = keyframe.co if x not in keyframes: keyframes.append((math.ceil(x))) return keyframes # get all selected objects selection = bpy.context.selected_objects # check if selection is not empty if selection: # get all frames with assigned keyframes keys = get_keyframes(selection) # print all keyframes print (keys) # print first and last keyframe print ("{} {}".format("first keyframe:", keys[0])) print ("{} {}".format("last keyframe:", keys[-1])) bpy.context.scene.frame_start = keys[0] bpy.context.scene.frame_end = keys[-1] else: print ('nothing selected')
3. Create Curve Object with no CP
1 2 3 4 5 6 7 8 import bpy bpy.ops.object.mode_set(mode = 'OBJECT') bpy.ops.curve.primitive_bezier_curve_add(radius=1, enter_editmode=False, location=(0, 0, 0)) bpy.ops.object.editmode_toggle() bpy.ops.curve.select_all(action='SELECT') bpy.ops.curve.delete(type='VERT') bpy.ops.object.editmode_toggle()
4. Create Curve Object with single CP
1 2 3 4 5 6 7 import bpy bpy.ops.object.mode_set(mode = 'OBJECT') bpy.ops.curve.primitive_bezier_curve_add(radius=1, enter_editmode=False, location=(0, 0, 0)) bpy.ops.object.editmode_toggle() bpy.ops.curve.select_all(action='SELECT') bpy.ops.curve.dissolve_verts() bpy.ops.object.editmode_toggle()
5. Separate select mesh object faces
As you can see, these are unedited code from info panel pasted as it is, which just worked for me. I didn’t even bother to edit the long line which has so many default parameter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import bpy bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={"linked":False, "mode":'TRANSLATION'}, TRANSFORM_OT_translate={"value":(0, 0, 0), "orient_type":'GLOBAL', "orient_matrix":((0, 0, 0), (0, 0, 0), (0, 0, 0)), "orient_matrix_type":'GLOBAL', "constraint_axis":(False, False, False), "mirror":False, "use_proportional_edit":False, "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "use_proportional_connected":False, "use_proportional_projected":False, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "gpencil_strokes":False, "cursor_transform":False, "texture_space":False, "remove_on_cancel":False, "release_confirm":False, "use_accurate":False}) bpy.ops.object.editmode_toggle() bpy.ops.mesh.select_all(action='SELECT') bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE') bpy.ops.mesh.extrude_faces_move(MESH_OT_extrude_faces_indiv={"mirror":False}, TRANSFORM_OT_shrink_fatten={"value":0, "use_even_offset":False, "mirror":False, "use_proportional_edit":False, "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "use_proportional_connected":False, "use_proportional_projected":False, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "release_confirm":False, "use_accurate":False}) bpy.ops.mesh.select_all(action='INVERT') bpy.ops.mesh.delete(type='FACE') bpy.ops.mesh.select_all(action='INVERT') bpy.ops.mesh.separate(type='LOOSE') bpy.ops.object.editmode_toggle()
6. Purge Orphan Data
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # purge, it will removed unused deleted data. import bpy def purge(): # purge won't run more than 5 times. # for any unknown reason, lets say their is some cyclic dependency and purge never return # {'CANCELLED'}, which it returns when it has nothing to purge # when I am using api, I don't fully understand, I use this trick to avoid infinite loop safety_cnt = 5 for i in range(safety_cnt): op_result = bpy.ops.outliner.orphans_purge() # returns {'FINISHED'} or {'CANCELLED'} if op_result == {'CANCELLED'}: if i == 0: print(f'ran purge {i + 1} times, there was nothing to purge') else: print(f'ran purge {i + 1} times') return print(f"purging {safety_cnt} times wasn't enough, run once more") purge()
Tip
Tips For beginners coders, for majority of tasks, rarely you need to write from scratch.
1. If you turn on preference->interface-> developer extra
you get a copy python command
in
the context menu.
Copy code from info_panel, it’s reflects history of commands you ran from interface.
All the addons that are installed or you can find in net.
execute
method is called when operator is run, so you can copy that code and any other function that is called by that methodOnline from blender stack_exchange, blender_artist, SO etc