Scripting Tipps and Examples

Offical

3rd Party Tutorials

Cheatsheet

Selection

WARNING: Blender makes a huge difference between "Selected Object" and "Active Object"! The active object is the object actually edited (as in operators usually apply to the active object), while a selected objects is merely part of the selection. While one object can be both selected and active at the same time, that is not necessarily a given! Hence when changing the selection, make sure you're wether you need to set the active object!

print(bpy.context.active_object) #last selected and active object
print(bpy.context.object) #last selected (but not actively selected!) object
print(bpy.context.selected_objects) # list of selected objects
print(bpy.context.selectable_objects) # list of selectable objects
print(bpy.data.objects['Cube']) # Get object by name

See also: bpy.context

# Set selection
bpy.data.objects['Cube'].select_set(True)
# Set active object
bpy.context.view_layer.objects.active = bpy.data.objects['Cube']

This is my little selection script that simply selects a group of objects:

def select(*objs):
    bpy.ops.object.select_all(action='DESELECT')
    if len(objs)==0:
        return
    for obj in objs:
        obj.select_set(True)
    bpy.context.view_layer.objects.active = objs[0]

Interaction Mode

Setting an interaction mode:

bpy.ops.object.mode_set_with_submode(mode="OBJECT")
bpy.ops.object.mode_set(mode="EDIT")
bpy.ops.mesh.select_mode(type="FACE")

Querying an interaction mode:

mode = bpy.context.active_object.mode # active_object is the last selected object
# or
mode = bpy.context.mode

*see bpy.context.mode

Querying the mesh sub mode:

# it's a tuple of 3 bools
vertex, edge, face = context.scene.tool_settings.mesh_select_mode
# result: true false false

Blender Forum about Selection Issues

Creating new objects:

def add_mesh(name, verts, faces, edges=None, col_name="Collection"):    
    if edges is None:
        edges = []
    mesh = bpy.data.meshes.new(name)
    obj = bpy.data.objects.new(mesh.name, mesh)
    col = bpy.data.collections.get(col_name)
    col.objects.link(obj)
    bpy.context.view_layer.objects.active = obj
    mesh.from_pydata(verts, edges, faces)

verts = [( 1.0,  1.0,  0.0), 
         ( 1.0, -1.0,  0.0),
         (-1.0, -1.0,  0.0),
         (-1.0,  1.0,  0.0),
         ]
faces = [[0, 1, 2, 3]]
add_mesh("myBeautifulMesh_1", verts, faces)

Ref: Polygons Vertices from_pydata

Converting Filepaths

Blender uses its own relative file path format. To convert this, use bpy.path.abspath and bpy.path.relpath.

WARNING: Paths need to be absolute to use them in any other context than blender. This includes checking for existence via os.path.exists.

UI Stuff

Progress bar updates:

from time import sleep
import bpy
wm=bpy.context.window_manager
wm.progress_begin(0, 100) #(*min*, *max*)
for i in range(100):
    sleep(.01)
    wm.progress_update(i)
wm.progress_end()

Examples

Quickly import a full list of OBJ-files:

import bpy
import os

src_path=r"D:\Games\itch.io\kenney-game-assets-1\3D assets\Fantasy Town Kit\Models\OBJ format"

for f in os.scandir(src_path):
    if f.name[-4:].lower()==".obj":
        print("Importing {}".format(f.path))
        # fix that!
        bpy.ops.import_scene.obj(filepath=f.path) # "filepath=" is important