blender-scripting
Write and run Blender Python scripts for 3D automation. Use when the user wants to automate Blender tasks, run headless scripts, manipulate scenes, batch process .blend files, import/export 3D models, manage objects, or script Blender from the command line using the bpy API.
Usage
Getting Started
- Install the skill using the command above
- Open your AI coding agent (Claude Code, Codex, Gemini CLI, or Cursor)
- Reference the skill in your prompt
- The AI will use the skill's capabilities automatically
Example Prompts
- "Process all PDFs in the uploads folder and extract invoice data"
- "Set up a workflow that converts uploaded spreadsheets to formatted reports"
Documentation
Overview
Automate Blender tasks using Python and the bpy API. Run scripts headlessly from the terminal to manipulate scenes, batch process files, import/export models, and build 3D pipelines without opening the GUI.
Instructions
1. Run a Blender script from the terminal
# Run a script in background mode (no GUI)
blender --background --python script.py
# Run with a specific .blend file
blender myfile.blend --background --python script.py
# Pass custom arguments (use -- to separate Blender args from script args)
blender --background --python script.py -- --output /tmp/result.png --scale 2.0
Parse custom arguments in the script:
import sys
argv = sys.argv
# Everything after "--" is a custom argument
if "--" in argv:
custom_args = argv[argv.index("--") + 1:]
else:
custom_args = []
2. Understand the bpy module structure
import bpy
# bpy.data — all data in the file (meshes, materials, objects, scenes)
bpy.data.objects["Cube"]
bpy.data.meshes["Cube"]
bpy.data.materials["Material"]
# bpy.context — current state (active object, selected objects, scene)
bpy.context.active_object
bpy.context.selected_objects
bpy.context.scene
# bpy.ops — operators (actions like add, delete, transform)
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
bpy.ops.object.delete()
3. Scene setup and cleanup
import bpy
def clear_scene():
"""Remove all objects from the scene."""
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)
# Also clear orphan data
for block in bpy.data.meshes:
if block.users == 0:
bpy.data.meshes.remove(block)
for block in bpy.data.materials:
if block.users == 0:
bpy.data.materials.remove(block)
def setup_scene():
"""Set up a clean scene with basic settings."""
clear_scene()
scene = bpy.context.scene
scene.unit_settings.system = 'METRIC'
scene.unit_settings.scale_length = 1.0
4. Create and transform objects
import bpy
from mathutils import Vector, Euler
import math
# Add primitives
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
cube = bpy.context.active_object
cube.name = "MyCube"
# Transform
cube.location = (3, 0, 1)
cube.rotation_euler = (0, 0, math.radians(45))
cube.scale = (1, 2, 0.5)
# Duplicate
bpy.ops.object.duplicate(linked=False)
duplicate = bpy.context.active_object
duplicate.location.x += 5
# Parent objects
child = bpy.data.objects["ChildObj"]
parent = bpy.data.objects["ParentObj"]
child.parent = parent
5. Import and export 3D files
import bpy
# Import
bpy.ops.wm.obj_import(filepath="/path/to/model.obj")
bpy.ops.import_scene.fbx(filepath="/path/to/model.fbx")
bpy.ops.import_scene.gltf(filepath="/path/to/model.glb")
bpy.ops.wm.stl_import(filepath="/path/to/model.stl")
# Export
bpy.ops.wm.obj_export(filepath="/path/to/output.obj")
bpy.ops.export_scene.fbx(filepath="/path/to/output.fbx", use_selection=True)
bpy.ops.export_scene.gltf(filepath="/path/to/output.glb", export_format='GLB')
bpy.ops.wm.stl_export(filepath="/path/to/output.stl")
6. Batch process .blend files
import bpy
import glob
import os
blend_files = glob.glob("/path/to/projects/*.blend")
for filepath in blend_files:
bpy.ops.wm.open_mainfile(filepath=filepath)
# Do work on each file
for obj in bpy.data.objects:
if obj.type == 'MESH':
print(f" Mesh: {obj.name}, verts: {len(obj.data.vertices)}")
# Save modified file
output = filepath.replace(".blend", "_processed.blend")
bpy.ops.wm.save_as_mainfile(filepath=output)
print(f"Saved: {output}")
7. Work with custom properties
import bpy
obj = bpy.context.active_object
# Set custom properties
obj["my_property"] = 42
obj["tags"] = "hero,main"
# Read custom properties
value = obj.get("my_property", 0)
# Iterate all custom properties
for key, value in obj.items():
if key not in {"_RNA_UI"}:
print(f"{key}: {value}")
Examples
Example 1: Export all objects as separate OBJ files
User request: "Export every mesh object in my .blend file as a separate OBJ"
import bpy
import os
output_dir = "/tmp/exports"
os.makedirs(output_dir, exist_ok=True)
bpy.ops.object.select_all(action='DESELECT')
for obj in bpy.data.objects:
if obj.type == 'MESH':
bpy.ops.object.select_all(action='DESELECT')
obj.select_set(True)
bpy.context.view_layer.objects.active = obj
filepath = os.path.join(output_dir, f"{obj.name}.obj")
bpy.ops.wm.obj_export(filepath=filepath, export_selected_objects=True)
print(f"Exported: {filepath}")
Run: blender scene.blend --background --python export_all.py
Example 2: Batch rename objects by type
User request: "Rename all mesh objects to mesh_001, mesh_002, etc. and all lights to light_001, etc."
import bpy
counters = {}
for obj in sorted(bpy.data.objects, key=lambda o: o.name):
prefix = obj.type.lower()
counters[prefix] = counters.get(prefix, 0) + 1
obj.name = f"{prefix}_{counters[prefix]:03d}"
print(f"Renamed to: {obj.name}")
bpy.ops.wm.save_mainfile()
Example 3: Scene statistics report
User request: "Give me a summary of what's in this .blend file"
import bpy
print("=== Scene Report ===")
print(f"Objects: {len(bpy.data.objects)}")
print(f"Meshes: {len(bpy.data.meshes)}")
print(f"Materials: {len(bpy.data.materials)}")
print(f"Textures: {len(bpy.data.images)}")
print(f"Scenes: {len(bpy.data.scenes)}")
print(f"Collections: {len(bpy.data.collections)}")
total_verts = sum(len(m.vertices) for m in bpy.data.meshes)
total_faces = sum(len(m.polygons) for m in bpy.data.meshes)
print(f"Total vertices: {total_verts:,}")
print(f"Total faces: {total_faces:,}")
for obj in bpy.data.objects:
info = f" {obj.name} ({obj.type})"
if obj.type == 'MESH':
info += f" — {len(obj.data.vertices)} verts"
print(info)
Guidelines
- Always use
--backgroundwhen running scripts from the terminal to avoid opening the GUI. - Start scripts with
clear_scene()if building a scene from scratch to avoid leftover default objects. - Use
bpy.datafor direct data access (fast, reliable). Usebpy.opsfor complex operations that mirror user actions (operators require correct context). - When using operators, ensure the correct object is active and selected:
bpy.context.view_layer.objects.active = objandobj.select_set(True). - For batch processing, always save to a new file (not overwrite originals) unless the user explicitly requests in-place modification.
- Import/export operator names vary between Blender versions. The ones listed here work for Blender 3.6+. For older versions, check
dir(bpy.ops.import_scene). - Use
mathutilsfor vector math, quaternions, and matrix operations — it's bundled with Blender's Python. - To debug, use
print()statements — output goes to the terminal when running with--background.
Information
- Version
- 1.0.0
- Author
- terminal-skills
- Category
- Automation
- License
- Apache-2.0