Anthropic

Blender 3D Mastery: A Complete Reference for Claude Code with Blender MCP

by Research compilation — Claude Code

other
Pages744
Formatmarkdown
ListedMay 26, 2026
UpdatedMay 26, 2026
Subscribers0

About

Comprehensive AI context book for Claude Code operating Blender via blender-mcp (ahujasid). 22 chapters, 83 runnable bpy recipes, complete tool reference for all 22 blender-mcp tools (including Hyper3D Rodin and Hunyuan3D). Domain workflows: arch viz, game assets, product viz, character sculpting, motion graphics. Blender 4.x. Written TO Claude Code as a dense retrieval-optimized knowledge base.

744Chapters
1078Topics
744Pages

Preview

Blender 3D Mastery: A Complete Reference for Claude Code with Blender MCP

Version: 1.0
MCP Target: blender-mcp (all 22 tools)
Purpose: A comprehensive reference for Claude Code agents operating Blender via the blender-mcp MCP server. Covers Blender fundamentals, the bpy API, MCP tool signatures, domain workflows, and ready-to-run code recipes.
Blender Target: Blender 4.x


How to Use This Book (For Claude Code)

This book is structured as a lookup reference, not a linear read. When given a Blender task, navigate it as follows:

  1. Start with the relevant domain workflow chapter (Ch. 17–22) for end-to-end sequences. Each workflow chapter provides a complete task breakdown from scene setup to final output — follow these sequences before improvising.

  2. Look up specific Blender operations in Parts I–III (Ch. 1–13) when you need to understand a particular system (mesh editing, modifiers, materials, lighting, geometry nodes, etc.) before executing it.

  3. Consult Ch. 14 for exact blender-mcp tool signatures before calling any tool. Parameter names, types, and defaults are documented there. Never guess a tool signature — incorrect calls can corrupt scene state.

  4. Use Ch. 16 recipes directly as execute_blender_code inputs — they are tested and ready. Copy the recipe, adapt the variable assignments at the top, and send. Do not rewrite recipe internals unless the chapter notes instruct otherwise.

  5. Always use the iterative loop: get_scene_info → plan → execute_blender_codeget_viewport_screenshot → verify. Never chain multiple destructive operations without a viewport check between them. If a step produces unexpected results, stop and inspect before continuing.

Blender 4.x Note: Several bpy APIs changed in Blender 4.0. All code in this book targets Blender 4.x. See Ch. 22 for backwards compatibility notes.


Table of Contents

Part I — Blender Foundations

Part II — Materials, Shading & Rendering

Part III — Advanced Systems

Part IV — Blender MCP Mastery

Part V — Domain Workflows


Part I — Blender Foundations

Chapter 1: Blender Architecture & Data Model

Every entity in Blender is an ID datablock — a named, reference-counted data container stored in bpy.data. Understanding this model is prerequisite to all bpy scripting: you always work with datablocks, not raw Python objects.

ID Datablocks

All major Blender entities are ID datablocks accessible under bpy.data:

Datablock Typebpy.data Collectionbpy.types Class
Objectbpy.data.objectsbpy.types.Object
Meshbpy.data.meshesbpy.types.Mesh
Materialbpy.data.materialsbpy.types.Material
Imagebpy.data.imagesbpy.types.Image
Actionbpy.data.actionsbpy.types.Action
Scenebpy.data.scenesbpy.types.Scene
Collectionbpy.data.collectionsbpy.types.Collection
Worldbpy.data.worldsbpy.types.World
Armaturebpy.data.armaturesbpy.types.Armature
Camerabpy.data.camerasbpy.types.Camera
Lightbpy.data.lightsbpy.types.Light
Node Groupbpy.data.node_groupsbpy.types.NodeTree
Curvebpy.data.curvesbpy.types.Curve
Texturebpy.data.texturesbpy.types.Texture

Datablocks are created with .new() and removed with .remove():

mesh = bpy.data.meshes.new(name="MyMesh")      # create
bpy.data.meshes.remove(mesh)                    # remove (frees memory if no users)

Object vs. Data Distinction

An Object is a scene entity with a transform (location, rotation, scale) and a pointer to a data datablock. The same data datablock can be shared by multiple objects (instances share one mesh in memory).

Add to library to read more

Table of Contents

Access object and its mesh
Check the type of obj.data:
Multiple objects can share one mesh:
Object type values: 'MESH', 'CURVE', 'SURFACE', 'META', 'FONT',
'VOLUME', 'GPENCIL', 'ARMATURE', 'LATTICE', 'EMPTY',

Iterate all objects in the master collection (non-recursive):
Recursive traversal of all objects in scene:

Get evaluated depsgraph for current frame:
Get evaluated version of an object (modifiers applied):
IMPORTANT: free the evaluated mesh after use to avoid memory leaks:
Force depsgraph update after data changes:

Link — keeps reference to external .blend file (live link, read-only data):
Append — copies datablock into current file (editable, no external dependency):

---- Data access ----
---- Evaluated (modifiers applied) ----
---- Scene graph traversal ----

Requires an active object to be set first
Toggle edit mode:

READ active object:
WRITE active object (Blender 4.x):
Equivalent alias:
WRONG (raises AttributeError):
bpy.context.active_object = obj ← DO NOT USE

Get cursor location (mathutils.Vector):
Set cursor location:
Set cursor rotation:
Snap cursor to selected objects:
Snap cursor to world origin:

Get VIEW_3D area:
OLD WAY (Blender 3.x, deprecated in 4.x — do NOT use):

Active object:
Iterate visible objects in view layer:

--- Location ---
--- Rotation (Euler, default) ---
Rotation mode options: 'XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX', 'AXIS_ANGLE', 'QUATERNION'
--- Rotation (Quaternion) ---

World matrix: 4×4 matrix (mathutils.Matrix)
Decompose world transform:
Get world position of origin:
Transform a local point to world space:

Must be in Object mode with target objects selected:

Full safe pattern:

Set origin to geometry center (median point of all vertices):
Options for center: 'MEDIAN', 'BOUNDS'
Set origin to bounding box center:
Set origin to 3D cursor position:
Move geometry to origin (origin stays, mesh moves):
All origin_set types:
'GEOMETRY_ORIGIN' — moves geometry to origin
'ORIGIN_GEOMETRY' — moves origin to geometry center
'ORIGIN_CURSOR' — moves origin to 3D cursor

Set parent:
matrix_parent_inverse = parent's inverted world matrix at time of parenting
Without this, child will jump to account for parent's current transform
Clear parent (keep visual transform):

Collection instancing (most common):
Vertex instancing — each vertex of a mesh spawns an instance:

Duplicate linked (shares mesh data):
Duplicate unlinked (independent copy):

Iterate vertices:
Access by index:
Modify vertex position directly:
Iterate edges:

Access UV layer:
Read UV coordinates (indexed by loop):
Create a new UV layer:
UV Unwrap (requires EDIT_MESH mode, with faces selected):
Smart UV Project:
Angle-based unwrap:
method options: 'ANGLE_BASED', 'CONFORMAL'
Lightmap UV unwrap (for baking AO/shadows):

Create a custom float attribute on vertices:
type options: 'FLOAT', 'INT', 'FLOAT_VECTOR', 'FLOAT_COLOR', 'BYTE_COLOR', 'BOOLEAN', 'FLOAT2', 'INT8', 'QUATERNION'
domain options: 'POINT' (vertex), 'EDGE', 'FACE' (polygon), 'CORNER' (loop)
Write values:
Read:
Remove attribute:

Per-vertex normals (read from Mesh):
Per-polygon normals:
Recalculate normals (Edit mode required):
inside=True: flip normals inward
Enable Auto Smooth (Blender 4.1+: replaced by Smooth by Angle modifier):
Pre-4.1:
Blender 4.1+: add a "Smooth by Angle" geometry node modifier instead

Iterate bmesh elements:
Ensure lookup tables are up to date before indexing:
Select by index:
Push changes back to mesh:

Non-destructive (modifier):

Ensure active mesh object in Edit mode:

Select / Deselect / Invert all:
Selection mode (Vert / Edge / Face):
Check current select mode:
Select border / box:
bpy.ops.mesh.select_box() # interactive only; not scriptable
Select linked (connected geometry):
Select edge loops:

Extrude and move in one operation:
Extrude along normals:
Extrude individual faces:
Extrude edges:

Loop cut and slide:

Bevel edges:

Fill hole (select boundary edges/verts):
Bridge two edge loops:
Grid fill (selected edge loops):
Merge vertices:
type options: 'FIRST', 'LAST', 'CENTER', 'CURSOR', 'COLLAPSE'
Merge by distance (Blender 4.x — only valid operator):

Subdivide:
Knife tool (interactive; use bisect for scripting):
bpy.ops.mesh.knife_tool() # interactive only

Dissolve (removes geometry without creating holes):
Delete:
Separate into new object:

Intersect Boolean (uses second selected mesh to cut first):
NOTE: both objects must share geometry or overlap; use modifier approach for reliability
operation: 'INTERSECT', 'UNION', 'DIFFERENCE'
Setup: cutter object exists in scene
Apply modifier to make permanent:

Remesh (voxel) for clean topology from sculpt:

Translate (move) selected:
Rotate selected:
Scale selected:
Shrink/Fatten along normals:

Access the modifier stack:
Modifier index/order (position 0 = top of stack = applied first):
Move modifier in stack:
Blender 4.x direct reorder:
obj.modifiers.move(from_index=2, to_index=0)
Remove modifier without applying:
Apply modifier (bakes into mesh, removes from stack):
Apply as shape key (stores deformation as shape key):

Offset method:
Constant offset:
Fit to curve:
Object offset (use another object's transform):

Cloth:
Soft Body:
Particle System:
Collision:

Add Geometry Nodes modifier:
Create or assign a node group:

Order: Mirror → Boolean(s) → Bevel → Subdivision
On cloth object:
On floor/obstacle:

Create material:
Access Principled BSDF (always present when use_nodes=True):
Assign to object:

Control tiling and offset:

Area light:
All light types:
'POINT' — omnidirectional point source
'SUN' — infinitely distant directional light (sun/moon)
'SPOT' — cone-shaped directional light

POINT light:
SUN light:
SPOT light:

Build HDRI node graph:
Load HDRI image:
Connect:
Layout:
Full rotation reference:
0 = 0° (original orientation)
1.5708 = 90°
3.1416 = 180° (flip horizontally)
4.7124 = 270°
Use a separate background for camera rays vs. diffuse/glossy:
Camera rays use solid color, all other rays use HDRI
Via MCP: download_polyhaven_asset(asset_id="rural_asphalt_road", asset_type="hdris", resolution="2k")

Create a volume material for an object:

sky.sky_type = 'HOSEK_WILKIE' # alternative physically-based model

Disable shadow casting for a light:
Object visibility flags:
Cycles-specific light visibility:

Light linking is configured per light via the light object's data.
In bpy, access via Cycles light settings — this feature is primarily UI-based.
For scripted control, the recommended approach is separate render layers
with lights on different collections with render visibility toggled per layer.

Create camera object:
Access camera data:

Projection type:
Perspective settings:
Sensor (film back) size:
Orthographic:

Enable DoF:
Focus by distance:
Focus on a specific object (auto-tracks as object moves):
Aperture (f-stop controls blur amount):
f-stop guide:
f/1.4 — very shallow, extreme blur (portrait)
f/2.8 — shallow, moderate blur (standard portrait/product)
f/5.6 — moderate depth
f/11 — deep, little blur (landscape/architecture)
f/22 — maximum depth (near-infinite focus)
Aperture shape (bokeh shape):

Optionally limit influence:

Create multiple cameras:

Set render resolution to match camera aspect:
Camera border rendering (render only a portion of the frame):
Fit camera to selected objects (requires operator context):

Keyframe at frame 1 (start position):
Keyframe at frame 100 (end position):

Cycles — physically-based path tracer:
EEVEE Next (Blender 4.2+) — real-time rasterizer:
Legacy EEVEE (Blender 4.0–4.1):

Sample count:
Denoising:
Device:
Note: GPU must be configured in Preferences > System > Cycles Render Devices
Light bounces (ray depth):
Clamping (suppress fireflies):
Caustics:
Seed (reproducible noise):
Per-scene light path limits (same as cycles.max_bounces family above)

EEVEE Next (Blender 4.2+) — ray tracing replaces SSR and shadow maps
Sampling (still valid in EEVEE Next):
Ambient Occlusion (still valid):
Ray Tracing (EEVEE Next 4.2+ — replaces SSR and shadow maps):
Bloom: REMOVED in EEVEE Next — use Compositor > Glare node instead
Shadow map sizes: REMOVED in EEVEE Next — shadows are ray-traced
Motion Blur:
Depth of Field:
Controlled per camera via cam.dof — EEVEE uses camera DoF settings
Legacy EEVEE (Blender 4.0–4.1 only — do NOT use on 4.2+):
eevee.use_bloom = True # removed in 4.2
eevee.use_ssr = True # removed in 4.2

Resolution:
Aspect ratio override:
Output path and format:
File format options:
'PNG' — lossless, supports alpha (RGBA), 8 or 16 bit
'JPEG' — lossy, smaller file, no alpha
'OPEN_EXR' — HDR float output, single layer
'OPEN_EXR_MULTILAYER'— HDR float with render passes as layers
'TIFF' — lossless, photographic workflow
'BMP' — uncompressed, no alpha
'WEBP' — modern lossy/lossless with alpha

Render current frame to file (writes to render.filepath):
Render current frame without saving:
Result accessible as:
Render animation (entire frame range):

Standard passes:
Diffuse:
Glossy:
Other:

Preferences must be set via bpy.context.preferences (not bpy.context.scene):
Refresh available devices:
Enable all available GPU devices:
Set compute device type:

View transform (tone mapping):
Note: Blender 4.0+ default is 'AgX' (better shadow handling than Filmic)
Exposure and gamma:
Look (contrast preset):

Access compositor nodes:
The render output automatically connects to the Render Layers node:

1. Configure engine and settings via execute_blender_code:
2. Trigger render (this blocks until complete — respect 180s MCP timeout):
3. After render, use get_viewport_screenshot for quick preview,

Add the modifier:

============================================================
Blender 3.x (OLD) — BROKEN in Blender 4.0+:
============================================================
============================================================
Blender 4.0+ (CORRECT) — use node_tree.interface:

Float input:
Boolean input:
Vector input (tuple of 3 floats):
Integer input:
Object input:
Example output:
Socket_1: NodeSocketFloat (INPUT)

Add a Distribute Points on Faces node:
Set density by socket name:
Set distribution mode via node property (not a socket):
Add an Instance on Points node:
Add a Transform node:

Add Store Named Attribute node:

Create the surface object:
Add Geometry Nodes modifier:
--- Blender 4.x interface sockets ---
--- Nodes ---
--- Links ---

Create a small sphere to instance:
Create the surface:
Geometry Nodes modifier:
Interface:
Nodes:
Links:

List all nodes in the tree:
List all links:
List interface sockets:

Create a top-level collection and link it to the scene:
Move an existing object into the collection:

Visibility:
Display mode in viewport:
Object color (used in Solid mode with "Object" color source):
Pass index (used in render passes for compositing):

Deselect all:
Select a specific object:
Set the active object (required for many operators):
WRONG — this raises AttributeError in all Blender versions:
bpy.context.active_object = obj
Select multiple objects:

Append an object (copies it into the current file):
After append, bpy.context.selected_objects contains the appended objects.
Append an entire collection:
Link a collection (live reference — read-only in current file):
Appended objects land in the scene collection and are selected.

List all view layers:
Add a new view layer:
Remove a view layer (must have at least one remaining):
Switch the active view layer (requires a window reference):
Configure render passes on a view layer:

Frame range:
FPS:
Units:

Mark the active object as an asset:
Clear asset status (un-mark):
set_fake_user=True: keeps the datablock alive even with zero users
Mark programmatically (without using ops):

Add to Claude Code:

MCP call (not Python):
→ returns JSON with complete scene inventory
Parse the output to learn object names before any execute_blender_code
→ returns JSON with location, rotation_euler, scale, dimensions,
material_slots, vertex_count, polygon_count, modifier_stack
→ returns PNG image of the 3D viewport at up to 800×800 pixels
Use after every significant change to verify results visually

Minimal usage pattern:
... your bpy code ...

Step 1: Browse categories
→ "indoor (293), studio (96), outdoor (683), ..."
Step 2: Search
→ sorted list: asset_id, name, downloads, categories
Step 3: Download and apply
→ "The HDRI has been set as the world environment."
No further steps needed — addon handles the world node setup
Download creates a full PBR material:
→ "Created material 'wood_floor_deck' with maps: albedo, roughness, normal, ao"
Apply to object:
→ returns node count and texture node connection details
→ "The model has been imported into the current scene."

Step 1: Search
→ list of models with uid, name, author, license, face_count
Step 2: Preview (optional but recommended)
→ JPEG thumbnail
Step 3: Download and import
→ "Imported objects: ['Chair_mesh', 'Chair_legs']
Dimensions: X=0.52m Y=0.55m Z=1.01m
Scale applied: 0.34"

Step 1: Generate
→ {"task_uuid": "abc-123", "subscription_key": "xyz-789"}
Step 2: Poll until done (repeat until all statuses "Done")
→ ["Done", "Done", "Done"] ← all parts complete
Step 3: Import
→ success message
Step 4: Inspect bounding box (execute_blender_code)
(use the bounding box recipe above)
Step 1: Generate from image URL
→ {"request_id": "fal-req-456"}
Step 2: Poll
→ {"status": "COMPLETED"} ← done

Step 1: Generate
→ {"job_id": "job_00042"}
Step 2: Poll (repeat until status "DONE")
→ {"status": "DONE", "ResultFile3Ds": "/tmp/hunyuan/job_42/result.zip"}
Step 3: Import

Step 1: Always call get_scene_info first
(via MCP, not bpy — this is an MCP tool call, not Python code)
get_scene_info() returns JSON with all objects, lights, cameras
Step 2: Based on scene info, build your bpy code
Target specific objects by name from scene info results
Step 3: execute_blender_code(code=code)
Always wrap execute_blender_code content with try/except:
After significant changes, force an update:
Ensure correct mode before every operator call:
Enter edit mode:
... edit operations ...
Always return to object mode:
Full PolyHaven HDRI workflow via MCP tools:
1. get_polyhaven_categories(asset_type="hdris") → see available categories
2. search_polyhaven_assets(asset_type="hdris", categories="studio") → find assets
3. download_polyhaven_asset(asset_id="<id>", asset_type="hdris", resolution="2k") → download
4. Then apply via execute_blender_code:
After download, the HDRI file is in Blender's asset library
Apply it to the World shader:

By name (KeyError if not found):
Safe get (returns None if not found):
By index:
Iterate:
Create:
Remove (frees memory if no other users):

WRITE active object — always use view_layer, never direct assignment:
WRONG — raises AttributeError in all Blender versions:

PREFER direct manipulation (no context requirements, faster):
USE bpy.ops when no direct equivalent exists:

OLD WAY — Blender 2.x / 3.x — DEPRECATED / broken in 4.x:
bpy.ops.view3d.some_op({"area": area, "region": region}) ← do NOT use
NEW WAY — Blender 4.0+:
Find the VIEW_3D area:

Create a new bmesh and load from mesh:
Select all faces:
Inset faces:
Write back to mesh and free:
Move first vertex:

--- Vector ---
Swizzle:
Component access:
--- Matrix (4x4) ---
Decompose (from world matrix):
rot is a Quaternion
Invert:
Column/row access:
--- Euler ---
--- Quaternion ---
Slerp (smooth interpolation between quaternions):

Get the depsgraph for the current frame:
Get the evaluated version of an object:
Get the final mesh with all modifiers applied:
CRITICAL: free the evaluated mesh when done to avoid memory leaks:

Set frame and insert location keyframe:
Keyframe rotation:
Keyframe scale:
Keyframe individual axis (index):
Keyframe material property:

--- Transform ---
--- Identity ---
--- Visibility ---
--- Selection ---
--- Collections ---
--- Materials ---
--- Custom Properties ---
--- Constraints ---
--- Modifiers ---

Shade smooth:
or direct:

Recipe A1: Clear scene completely (remove all objects, meshes, materials, lights, cameras)
Recipe A2: Set render resolution and percentage
Recipe A3: Create standard camera pointing at origin
Recipe A4: Set frame range and FPS
Recipe A5: Set scene units to metric meters
Recipe A6: Enable Cycles with GPU and denoising
Recipe A7: Enable EEVEE Next (Blender 4.2+) with ray tracing

Recipe B1: Create all primitive types in a row
Recipe B2: Create object from raw vertex/face data
Recipe B3: Duplicate object with offset
Recipe B4: Create empty (null object) as pivot / instancer
Recipe B5: Create icosphere and apply subdivision

Recipe C1: Set exact location, rotation (degrees), and scale
Recipe C2: Apply all transforms (bake into mesh data)
Recipe C3: Reset transforms to identity
Recipe C4: Move object to world origin, keeping geometry in place
Recipe C5: Place object flush with Z=0 (floor level)

Recipe D1: Create and assign Principled BSDF material (blue plastic)
Recipe D2: Create emission (glowing) material
Recipe D3: Create glass material (Blender 4.x)
Recipe D4: Create metallic gold material
Recipe D5: Create matte white material
Recipe D6: Assign a different material to one specific face
Recipe D7: Create subsurface skin material

Recipe E1: Add and configure an area light
Recipe E2: Three-point lighting rig
Recipe E3: Setup HDRI world lighting from a file path
Recipe E4: Delete all lights in scene
Recipe E5: Add sun light pointing down at 45 degrees

Recipe F1: Add Subdivision Surface modifier
Recipe F2: Add Mirror modifier with clipping
Recipe F3: Add Bevel modifier (angle-limited)
Recipe F4: Apply all modifiers
Recipe F5: Remove all modifiers without applying
Recipe F6: Add Array modifier (5 copies along X)
Recipe F7: Add Solidify modifier (for flat meshes like walls)

Recipe G1: Cycles render to file
Recipe G2: Quick EEVEE preview render
Recipe G3: Render specific frame to specific path

Recipe H1: List all objects with type, location, and visibility
Recipe H2: Get scene summary
Recipe H3: Find objects by material name
Recipe H4: Purge all unused data blocks
Recipe H5: Print object bounding box and dimensions
Recipe H6: Get mesh statistics (vertex/edge/face count)

Recipe I1: Keyframe object location over 60 frames
Recipe I2: Keyframe full transform (location + rotation + scale)
Recipe I3: Keyframe object visibility (appear at frame 30)
Recipe I4: Keyframe material Roughness (shiny to matte)
Recipe I5: Set all keyframe interpolation to BEZIER

Recipe J1: Create nested collection hierarchy
Recipe J2: Move object to a specific collection
Recipe J3: Move all selected objects to a new collection
Recipe J4: Rename all objects with a prefix
Recipe J5: Print collection hierarchy tree

Recipe K1: Subdivide all edges of active object
Recipe K2: Inset all faces
Recipe K3: Triangulate all faces
Recipe K4: Recalculate normals outward
Recipe K5: Merge vertices by distance (remove doubles)

Recipe L1: Export selected objects as GLB
Recipe L2: Export all objects as FBX
Recipe L3: Import a GLB file

Recipe M1: Align object's origin to world floor (Z=0)
Recipe M2: Create a procedural color gradient material using ColorRamp
Configure gradient type:
Set ramp colors:
Link:
Recipe M3: Parent multiple objects to an empty pivot
Create or find pivot empty:
Parent all named objects to pivot:
Recipe M4: Scatter objects on a surface using vertex positions
Recipe M5: Check Blender version and report API compatibility
Recipe M6: Delete object and all its data cleanly
Recipe M7: Snap all selected objects to ground (Z=0) plane

Set units to metric meters:
Set render resolution (2K for arch viz):
Set Cycles for quality:

Floor — 20 m plane (extends beyond room for ground shadows):
Ceiling:
Front wall (faces camera, no window):
Back wall:
Left wall:

Surface presets (all Roughness/Metallic physically grounded):
Glass — uses Transmission Weight (Blender 4.x name):

After downloading via Polyhaven MCP:

Clear everything:
Cycles configuration for product viz:

1. Infinite white background sweep (no seam visible):
2. Key light — large Area light from upper left (main illumination):
3. Fill light — from right, lower energy, larger size (softer):

Assume product object is named "Product" at origin:

1. Create rotation pivot at origin:
2. Camera orbits at product height, 2.5 m away:
3. Parent camera to pivot:
4. Track camera to product:
5. Animate pivot 0→360° over 120 frames (= 5 seconds at 24fps):

Use HDRI at low strength (0.3) for ambient reflections,

1. Create base sphere for head sculpting:
2. Smooth shading:
3. Enter Sculpt mode:
4. Enable X-axis symmetry:

Phase 1: rough block-in at 2 cm:
Phase 2 (after rough sculpt): fine remesh at 5 mm:

Enable Rigify addon:
Add Human Meta-Rig:

Interpolation modes and when to use each:
'BEZIER' — smooth ease in/out (default, best for organic motion)
'LINEAR' — constant speed (turntables, scrolling text)
'CONSTANT' — no interpolation, stepped (stop-motion style)
'BACK' — overshoot past target, then settle (bouncy UI)
'BOUNCE' — physical bounce on arrival
'ELASTIC' — spring oscillation
'EXPO' — exponential acceleration or deceleration

Render to image sequence (recommended for long animations):

Example: run a VIEW_3D operator when context area might be wrong:

Check scene complexity before expensive operations:
1. Limit Subdivision Surface viewport level:
2. Reduce particle viewport display:

StringProperty — text input, file paths, passwords
BoolProperty — checkbox (name displays to RIGHT of checkbox)
EnumProperty — dropdown; each item is (id, label, tooltip) or (id, label, tooltip, icon, number)
IntProperty / FloatProperty — slider widget

Run a script in background mode with no UI:
Open a specific file, then run script:
Pass arguments to the script (after `--`):

--- Create a new GN tree and attach to object ---
Add Geometry Nodes modifier
Create a new node group
Add interface sockets (Blender 4.0+ API)
Add Group Input/Output nodes
Add a Subdivide Mesh node
Wire it up: Input.Geometry → Subdivide → Output.Geometry
Drive the modifier's exposed Count input:
Modifier inputs are named by socket identifier (e.g. "Socket_2", "Input_3")

Usage:

Bulk-mark all objects matching a pattern:
In a library's blender_assets.cats.txt:
VERSION 1
01234567-89ab-cdef-0123-456789abcdef:Trees:Trees

Create top-level collections
Nested collection
Assign bones to collections (Edit Mode or via API)

Add to Library

Free · Live updates included