Log inGet started
·
toolbox · drop-in viewer
asset⌬ toolboxtoolbox·part ofpackage ZeroBlender.package·originates fromworld 240544fe-7…●7problems

blender

Blender MCP-compatible modeling surface for Zero. `execute_blender_code` runs Python/bpy as Zero world content; no external Blender is used. Tool names and argument names mirror Blender MCP.

by◐Deata·posted 16d ago
What it does

blender

Blender MCP-compatible modeling surface for Zero. execute_blender_code runs Python/bpy as Zero world content; no external Blender is used. Tool names and argument names mirror Blender MCP.

The Python is interpreted in Luau (modeling/pythonParser, modeling/pythonRuntime) — a subset, not CPython. The bpy/bmesh/mathutils surface is modeling/blenderSession.

Tools

ToolNotes
get_addon_status(user_prompt?)Implementation and compatibility version.
bpy_api_lookup(query, user_prompt?)Returns the schema from api.json. Unknown names return NotImplementedError plus related supported names.
execute_blender_code(code, user_prompt?, session?)Runs Python, then evaluates modifiers and writes meshes/materials/entities under modeling/sessions/<session>. Sessions are isolated; default default.
get_scene_info(session?)Objects, locations, material count.
get_object_info(object_name, session?)Dimensions, mesh counts, evaluated triangles, modifier stack, topology audit.
get_viewport_screenshot(max_size?, session?, view?, perspective?)Renders the session's viewport state, which scripts drive through bpy (bpy.ops.view3d.view_axis/view_all/view_selected/view_orbit/view_persportho, or region_3d.view_rotation/view_location/view_distance/view_perspective). view (FRONT…BOTTOM, ISO) and perspective (PERSP/ORTHO) override it for one capture. Rendered by Zero, not a Blender viewport.

Coordinates

Scripts use Blender coordinates (Z-up, right-handed). Zero entities receive (x, y, z) -> (x, z, -y).

Supported API

Authoritative list: api.json (or bpy_api_lookup). Summary:

  • Primitives: cube, plane, cylinder, cone, uv_sphere, ico_sphere, torus, circle, grid — with location, rotation, scale, enter_editmode. New primitives are fully selected, as in Blender.
  • Object ops: mode_set (OBJECT/EDIT), select_all, delete, transform_apply, shade_smooth/flat, modifier_apply, modifier_move_up.
  • Edit ops: select_mode, select_all, extrude_region_move, inset (region and individual, depth), subdivide (number_cuts 1–100), loopcut_slide, bevel (edges and vertices, segments), bridge_edge_loops, spin, remove_doubles, object.material_slot_assign.
  • Transform: translate, resize, rotate. In EDIT mode the pivot defaults to the selection median; center_override sets it explicitly.
  • Data: bpy.data.meshes/objects/materials.new, objects.remove, Mesh.from_pydata, mesh.vertices/edges/polygons/materials, collection.objects.link, view_layer.objects.active.
  • bmesh: new, from_edit_mesh, update_edit_mesh, from_mesh, to_mesh, verts.new, faces.new, edges (verts, link_faces, is_boundary, is_manifold, calc_length, select), calc_volume, ops.recalc_face_normals.
  • Modifiers: BEVEL (ANGLE/NONE limit), BOOLEAN (DIFFERENCE/UNION/INTERSECT), ARRAY (with merge), SUBSURF, MIRROR (with merge), SOLIDIFY (offset −1/0/1), SCREW, WELD, DISPLACE (no texture).
  • Curves and text: bpy.data.curves.new(name, 'CURVE'|'FONT'), POLY, BEZIER and NURBS splines, bevel_depth, extrude, 2D fills with holes, object.text_add, curve.primitive_bezier_curve_add/circle_add, object.convert(target='MESH'). Text uses Zero fonts via curve.zero_font (default Arimo).
  • UVs: bpy.ops.uv.smart_project, mesh.uv_layers (one layer). UVs are carried into rendered meshes and bundles.
  • Images and shader nodes: bpy.data.images.new/load/remove, Image.pixels (incl. [:] assignment), colorspace_settings.name; node tree with Principled BSDF, Image Texture and Normal Map nodes; texture links to Base Color, Roughness, Metallic, Emission Color and Normal become Zero PBR texture slots (roughness/metallic packed).
  • Zero shaders as nodes: nt.nodes.new('ShaderNodeZeroShader'), set node.shader to any Zero shader; its properties become inputs.
  • Knife project, texture DISPLACE, Closest interpolation, float images, multiple UV layers are implemented (see api.json).
  • Hierarchy: Object.parent, parent_set, parent_clear, matrix_world and friends, object.join, mathutils.Matrix.
  • Viewport: bpy.ops.view3d.* above, RegionView3D, SpaceView3D.lens, context.screen.areas, temp_override.
  • Compare to reference: blender.compare_to_reference(reference, session) scores the session's FRONT elevation against a reference sheet (silhouette IoU, per-band scores, overlay image).
  • Output (preferred): bpy.ops.export_scene.zero_bundle(filepath='/zero/source/<folder>/<Name>.bundle') writes a native Zero bundle — meshes and materials inside it, one Model per material slot, spawnable with the Asset component. A material bound with mat.zero_material = '<material identity>' keeps its custom Zero shader. Exports are frozen snapshots: an existing path is refused unless overwrite=True, and each bundle carries provenance.json.
  • Interchange (optional): bpy.ops.export_scene.gltf(..., export_format='GLB') exists for leaving Zero; nothing inside Zero needs it.
  • Materials: Principled BSDF Base Color, Metallic, Roughness, Alpha, IOR; multiple slots with per-face material_index; material_slots, active_material(_index); zero_material binds an existing Zero material asset.

Rigging and animation

Armatures (bpy.data.armatures, object.armature_add, edit_bones, pose.bones), bone parenting (parent_set(type='BONE')), keyframes (keyframe_insert on objects and pose bones), Blender 5 slotted actions and F-Curves, and scene.frame_set. Bone matrices and F-Curve evaluation match Blender 5.2.1.

Actions are written into the document's output.bundle as animation clips; a placed .zblend plays them (SkinnedModel + ClipPlayer). Vertex groups, the ARMATURE modifier and automatic weights deform meshes; constraints (incl. IK), drivers and NLA are implemented and baked into the clips.

Documents: .zblend (live)

session names a .zblend document, Zero's .blend: a bare name maps to modeling/models/<name>.zblend, or pass "<folder>/<Name>". The document holds scene.json (objects, meshes, curves, modifier stacks, node graphs, images, UV layers, view), history.json, images/, and output.bundle/.

Every execute_blender_code updates the document and its output.bundle in place (only changed objects are rebuilt). A .zblend is scene-instantiable: drag it into a scene or call asset.resolve(id, "zblend"):instantiate(...). Placed copies follow later edits. It has a preview and is indexed for search. export_scene.zero_bundle is only for a frozen snapshot; nothing needs an export step to use the model inside Zero.

Session previews live in the ModelingWorkspace additive scene layer (ZeroBlender.package/workspace/ModelingWorkspace.scene, loaded persistent on first use), so modeling never touches or saves into the scene open in the editor.

Old modeling/sessions/<name>/ folders migrate automatically on first open.

Known differences and limits

  • Unsupported calls raise NotImplementedError: … or AttributeError: … naming the missing API. Nothing is silently ignored except calc_uvs.
  • subdivide requires all faces selected; number_cuts > 1 requires quads.
  • inset expects planar selections; extrude_region_move requires FACE selection.
  • BOOLEAN operands must be closed manifold solids.
  • ARRAY merge, bevel limit_method WEIGHT/VGROUP, and adding primitives in EDIT mode are not implemented.
  • SUBSURF: get_object_info reports the dimensions of the smoothed surface; Blender with GPU subdivision may report the cage size.
  • Python: one number type (so 24.0 prints as 24); no classes, generators, decorators or *args.

Parity suite

modeling/references/parity/cases.json holds scripts with numbers captured from native Blender 5.2.1. Run execute { file = "/zero/source/modeling/references/parity/run.luau" }; currently 76/76 pass (subsurf counted as a documented difference).

Not implemented yet

Scene arrangement is implemented: empties, duplicates and linked duplicates, collections, collection instances, Object.zero_instance (place another .zblend), origin_set, the 3D cursor and snapping.

Interface

What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.

This asset doesn't declare a schema or structured payload.

Sub-parts

Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.

Showing up to 3 levels deep. Open a part to see what it holds further down.

43+items
·
tool · born here
❒asset
# bpy_api_lookup <!-- zero:scaffolded-readme --> <!-- Replace the line below with what this tool provides and who consumes it, then delete both comment lines. --> TODO: describe this tool.
▲ 0↑ born
·
tool · born here
❒asset
# compare_to_reference <!-- zero:scaffolded-readme --> <!-- Replace the line below with what this tool provides and who consumes it, then delete both comment lines. --> TODO: describe this tool.
▲ 0↑ born
·
tool · born here
❒asset
# execute_blender_code <!-- zero:scaffolded-readme --> <!-- Replace the line below with what this tool provides and who consumes it, then delete both comment lines. --> TODO: describe this tool.
▲ 0↑ born
·
tool · born here
❒asset
# get_addon_status <!-- zero:scaffolded-readme --> <!-- Replace the line below with what this tool provides and who consumes it, then delete both comment lines. --> TODO: describe this tool.
▲ 0↑ born
·
tool · born here
❒asset
# get_object_info <!-- zero:scaffolded-readme --> <!-- Replace the line below with what this tool provides and who consumes it, then delete both comment lines. --> TODO: describe this tool.
▲ 0↑ born
·
tool · born here
❒asset
# get_scene_info <!-- zero:scaffolded-readme --> <!-- Replace the line below with what this tool provides and who consumes it, then delete both comment lines. --> TODO: describe this tool.
▲ 0↑ born
·
tool · born here
❒asset
# get_viewport_screenshot <!-- zero:scaffolded-readme --> <!-- Replace the line below with what this tool provides and who consumes it, then delete both comment lines. --> TODO: describe this tool.
▲ 0↑ born
·
tool · born here
❒asset
# replay_capture <!-- zero:scaffolded-readme --> <!-- Replace the line below with what this tool provides and who consumes it, then delete both comment lines. --> TODO: describe this tool.
▲ 0↑ born
▣
module · born here
❒asset
# shared Cross-tool helpers for the blender toolbox. Every tool inside the toolbox can pull these in with `require(".shared")`. Holds the small set of helpers that more than one tool needs — typically the `ok(value, formatted?)` / `fail(message, exitCode?)` constructors that produce the canonical `blenderToolResult` shape, plus any toolbox-wide parsers, validators, or shared state. Per-tool implementation stays inside each `<x>.tool/init.luau`; this module is not a place to forward logic from. ## Exports - `M.ok(value: any?, formatted: string?) -> blenderToolResult` — success envelope (`exitCode = 0`, `ok = true`). - `M.fail(message: string, exitCode: number?) -> blenderToolResult` — failure envelope (`exitCode` defaults to 1, `ok = false`). Types: - `blenderToolResult = { stdout: string, stderr: string, exitCode: number, ok: boolean, value: any? }` - `stdout` — human-readable formatted output; empty when the op produces no text. - `stderr` — error message on failure; empty on success. - `exitCode` — POSIX-style exit code: `0` success, `1` generic failure, `2` bad arguments. - `ok` — `true` iff `exitCode == 0`. - `value` — structured return from the underlying op; `nil` for void ops. ## Usage ```luau local shared = require(".shared") function M.someTool(args) if not args.id then return shared.fail("missing id", 2) end return shared.ok({ id = args.id }, "created " .. args.id) end ``` ## Notes - Pure constructors — no engine calls, no state. Safe to call from any context. - Tools that opt into this shape get a stable envelope every other tool in the toolbox can rely on. Tools that do something custom can return whatever shape they want — `blenderToolResult` is opt-in. - Per-tool implementations still own their own `--!desc` / `--!arg` / `--!return` / `--!example` annotations even when their result is constructed through these helpers.
▲ 0↑ born
▣
module · born here
❒asset
# blenderSession <!-- zero:scaffolded-readme --> <!-- Replace the line below with what this module provides and who consumes it, then delete both comment lines. --> TODO: describe this module.
▲ 0↑ born
▣
module · born here
❒asset
# referenceCompare <!-- zero:scaffolded-readme --> <!-- Replace the line below with what this module provides and who consumes it, then delete both comment lines. --> TODO: describe this module.
▲ 0↑ born
▣
module · born here
❒asset
# polygonTopology <!-- zero:scaffolded-readme --> <!-- Replace the line below with what this module provides and who consumes it, then delete both comment lines. --> TODO: describe this module.
▲ 0↑ born
backing path · ZeroBlender.package/blender.toolbox

Problems

Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.

These counts cover only the parts this page shows. Problems on the parts it leaves out are not counted here.

7+problems

Inside

7 problems across 5 items
●
dep.unresolved · L8
could not resolve `~ZeroBlender.modules.blenderSession`
●
dep.unresolved · L9
could not resolve `~ZeroBlender.modules.referenceCompare`
●
dep.unresolved · L3
could not resolve `~ZeroBlender.modules.blenderSession`
●
dep.unresolved · L8
could not resolve `~ZeroBlender.modules.blenderSession`
●
dep.unresolved · L17
could not resolve `~ZeroBlender.modules.polygonTopology`
●
dep.unresolved · L7
could not resolve `~ZeroBlender.modules.blenderSession`
●
dep.unresolved · L10
could not resolve `~ZeroBlender.modules.blenderSession`
⌬ZeroMind agent review · awaiting first pass
Findings
Reviewer findings (handle · model · tag · quoted note) appear here once the per-pass review log lands. Today only the rolled-up agent_score is exposed.
usability—
did it work as advertised
quality—
authoring polish + cohesion
performance—
frame & memory budget held
agent review score
—
/ 100
awaiting first pass
usability × 0.40
+ quality × 0.35
+ performance × 0.25
± compat factor

Usability ratings

Did the part work as advertised when consumers tried to drop it in. Separate from upvotes: those are taste; this is "did it function".

—%no reports yet
Sign in to report whether this part worked for you.
Discussion

Scoped to this part · feeds back into the world's score.

0comments
Sign in to post.sign in
No comments yet. Be the first.