Blender Scripting Cookbook

Using scripts in Blender

Easy:

  1. Open the Text Editor.
  2. Press New to create new text. Give an optional name.
  3. Write / paste the script.
  4. Press Run Script.

It really worth learning some Python basics!

Blender API reference

Operator reference: operations in the same way as they would be done by interacting with the editor. Example: mesh operators
Types reference: properties and methods available from scripting at datablock level. Example: mesh types

Some useful collections:

bpy.context.object                # Active object (last object selected)
bpy.context.selected_objects      # All selected objects 
context.scene.objects             # All objects in current scene
bpy.data.objects                  # All objects 
bpy.data.meshes                   # All meshes

All bpy.data elements

Reset Parent Inverse

Clear the parent inverse without actually moving the object.

This script assumes you have the child selected.

import bpy
ob = bpy.context.object

# store a copy of the objects final transformation
# so we can read from it later.
ob_matrix_orig = ob.matrix_world.copy()

# reset parent inverse matrix
# (relationship created when parenting)
ob.matrix_parent_inverse.identity()

# re-apply the difference between parent/child
# (this writes directly into the loc/scale/rot) via a matrix.
ob.matrix_basis = ob.parent.matrix_world.inverted() @ ob_matrix_orig

Source

Remove animation data

import bpy

context = bpy.context
for ob in context.selected_objects:
    ob.animation_data_clear()

Replace context.selected_objects with context.scene.objects for all in the current scene, or bpy.data.objects to remove all animation data from all objects.

Source

Update image files to other format (e.g. dds to png) (Blender 2.8+)

import os 

for img in bpy.data.images:
    if img.source == "FILE":
        img.filepath = os.path.splitext(img.filepath)[0] + '.png'
        img.reload()

Use after converting .dds images to .png with some tool (e.g. image magick).

Remove inactive UV maps from the selected objects (Blender 2.8+)

import bpy

for ob in bpy.context.selected_objects:
    if ob.type == 'MESH':
        i = 0
        while i < len(ob.data.uv_layers):
            ob.data.uv_layers.active_index = i
            if ob.data.uv_layers.active.active_render:
                i += 1
            else:
                ob.data.uv_layers.remove(ob.data.uv_layers.active)

Remove vertex colors

This script also shows how to remove all elements in a bpi_prop_collection list (it seems there’s no clear method or equivalent).

This script assumes you have a mesh object selected.

import bpy

ob = bpy.context.object
while len(ob.data.vertex_colors) > 0:
    ob.data.vertex_colors.active_index = 0
    ob.data.vertex_colors.remove(ob.data.vertex_colors.active)

Find broken images

Selects objects containing materials with textures pointing to missing image files

import bpy

context = bpy.context
for ob in bpy.data.objects:
    if ob.type == 'MESH':
        for mat in ob.data.materials:
            for tex in mat.texture_slots:
                if tex and tex.texture and tex.texture.image and not tex.texture.image.has_data:
                    print(ob.name, mat.name, tex.texture.image.filepath)
                    ob.select_set(True)

Animate labels in the video sequencer

Source

Show current frame

import bpy

scene = bpy.context.scene
obj = scene.sequence_editor.sequences_all["Text.001"]

def recalculate_text(scene):
  obj.text = 'Current frame: ' + str(scene.frame_current)

bpy.app.handlers.frame_change_pre.append(recalculate_text)

Show elapsed time

import bpy

scene = bpy.context.scene
obj = scene.sequence_editor.sequences_all["Text.001"]

def recalculate_text(scene):
   fps = scene.render.fps / scene.render.fps_base # actual framerate
   obj.text = 'Elapsed time: {0:.1f} seconds'.format(scene.frame_current/fps)

bpy.app.handlers.frame_change_pre.append(recalculate_text)

Bonus: Writing Blender Addons (updated for Blender 2.80)

Any of the above scripts may be added to Blender as operator via add-on.

Useful: Addon for Running scripts in the Python console (or directly using the python console, no addon)

Example: this is the script Clear parent inverse without actually moving the object turned into addon:

bl_info = {
    "name": "Reset Parent Inverse",
    "category": "Object",
    "blender": (2, 80, 0),
}

import bpy

class ObjectResetParentInverse(bpy.types.Operator):
    """Applies parent inverse and resets it. Object transform becomes relative to the parent. Actual visible position won't change."""      # blender will use this as a tooltip for menu items and buttons.
    bl_idname = "object.reset_parent_inverse"                                                                                               # unique identifier for buttons and menu items to reference.
    bl_label = "Reset Parent Inverse"                                                                                                       # display name in the interface.
    bl_options = {'REGISTER', 'UNDO'}                                                                                                       # enable undo for the operator.

    def execute(self, context):        # execute() is called by blender when running the operator.
        
        for ob in context.selected_objects:
            # store a copy of the objects final transformation
            # so we can read from it later.
            ob_matrix_orig = ob.matrix_world.copy()

            # reset parent inverse matrix
            # (relationship created when parenting)
            ob.matrix_parent_inverse.identity()

            # re-apply the difference between parent/child
            # (this writes directly into the loc/scale/rot) via a matrix.
            ob.matrix_basis = ob.parent.matrix_world.inverted() @ ob_matrix_orig
        
        return {'FINISHED'}            # this lets blender know the operator finished successfully.
    
def register():
    bpy.utils.register_class(ObjectResetParentInverse)

def unregister():
    bpy.utils.unregister_class(ObjectResetParentInverse)

# This allows you to run the script directly from blenders text editor
# to test the addon without having to install it.
if __name__ == "__main__":
    register()

Write and test the addon:

  1. Open the Text Editor.
  2. Create new text (New button). Give an optional name.
  3. Write / paste the script.
  4. Run Script. This registers the operator, but doesn’t run it.
  5. Press SpaceBar to bring up the operator search dialog and type in the operator’s label, then press Enter.

Source

Install the addon:

  1. Save the file to disk (Text -> Save As in the Text Editor) with .py extension.
  2. File -> User Preferences, selected the Addon section, press Install Addon… and select the file.
  3. Enable the addon by pressing the check-box.
  4. Press Save User Settings if you want it to be enabled on other files.

Source