blender-assembly
Skill20 starsChanged 41 days agoMITView on GitHub
Use this skill whenever building, assembling, or creating any 3D model in Blender via MCP tools (mcp__blender__execute_blender_code). Covers all object types: furniture, vehicles, architecture, props, mechanical parts, scenes. Trigger any time Blender Python code will create geometry with primitives, bmesh, curves, modifiers, or booleans. It prevents the most common geometry bugs (exploded models, silent scale errors, broken boolean meshes) AND enforces a detail pass so models don't ship as bare boxes — beveled edges, panel recesses, hardware, cables, lofted grips/stocks, baked normal maps. Includes a mesh-integrity gate (non-manifold, duplicate verts, degenerate faces) that runs after every boolean or modifier apply. Always invoke before writing any Blender geometry code, including 'simple' objects.
1 other project uses a version of this, 1 of them edited.
Adopted by
Most recently taken up by
- laxmimerit/Claude-Skillsedited, first seen May 1, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 1
- laxmimerit/Claude-Skills★ 649% same
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository47 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- 3d-generation-harnessSkill
- ai-3d-to-dayzSkill
- ardy-motion-generationSkill
- blender-animationSkill
- blender-visual-reviewSkill
- dayz-3d-viewerSkill
- dayz-ai-patternsSkill
- dayz-animation-pipelineSkill
- dayz-aviationSkill
- dayz-basebuildingSkill
- dayz-charactersSkill
- dayz-clothingSkill
- dayz-doorsSkill
- dayz-environment-hazardsSkill
- dayz-feature-specSkill
- dayz-mcp-verifySkill
- dayz-model-pipelineSkill
- dayz-mod-workflowSkill
- dayz-motorbikesSkill
- dayz-p3d-auditSkill
- dayz-p3d-inspectorSkill
- dayz-particlesSkill
- dayz-pbo-buildSkill
- dayz-pbo-reverse-engineeringSkill
- dayz-persistenceSkill
- dayz-physics-engineSkill
- dayz-preflightSkill
- dayz-proxy-alignSkill
- dayz-realistic-animation-directorSkill
- dayz-sound-systemSkill
- dayz-test-ingameSkill
- dayz-texture-pipelineSkill
- dayz-ui-developmentSkill
- dayz-undergroundSkill
- dayz-vehiclesSkill
- dayz-weaponsSkill
- enforce-script-referenceSkill
- mixamo-retargetSkill
- ovh-cloudSkill
- rigorous-data-auditSkill
- rip-vehicle-importSkill
- systematic-debuggingSkill
- task-observerSkill
- uv-clean-atlasSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
18 rules. About 0 are common, 9 are distinctive, and 9 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈9
Distinctive · estimate
This author's own choices. Worth a look.
9
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 26
Create a connection map listing every joint before writing any geometry.
- Distinctive: line 40
Write this as a comment block in your first code cell, before any bpy calls.
- Distinctive: line 60
Every exterior edge of every visible part gets a bevel — Rule 6.
- Very specific: line 65
If no reference image exists, get one first — blender-visual-review §C compares against it later, and a detail list invented from memory …
- Distinctive: line 110
Never create a cylinder and rotate it to point in a direction.
- Distinctive: line 114
Use for: chair/table legs, beams, axles, frame members, railings, any angled strut.
- Very specific: line 120
When creating objects in a loop, bpy.context.active_object can silently reference the wrong object by the end of the loop, causing a scale …
- Very specific: line 138
Never hardcode a dimension for a part that must reach between two existing parts.
- Distinctive: line 156
Extend geometry 10–15% past the target boundary: before applying subsurf, then verify:
- Very specific: line 179
Cables / pipes / hoses / trigger guards: never chain rotated cylinders.
- Distinctive: line 186
NEVER leave coplanar faces between operands.
- Very specific: line 214
No UVs on the low → hard error.
- Distinctive: line 224
Call these after creating each part.
- Distinctive: line 258
Every Blender model, every time:
- Very specific: line 265
transform_apply(scale=True)immediately: after every scale assignment, inside the loop - Very specific: line 270
verify_bounds()+verify_overlap(): after every part, every joint - Very specific: line 271
verify_mesh_integrity(): after every boolean/modifier apply, every loft, and at finalization - Very specific: line 279
When driving the HOST Blender via MCP, obj.data.transform() (and other low-level in-place datablock writes) update the data — verifiable by …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Blender Assembly Skill
This skill prevents geometry errors when building 3D models in Blender via MCP, and enforces a detail pass so models come out looking like objects, not boxes. The recurring failure modes it addresses:
- Cube size math —
primitive_cube_add(size=1)creates vertices at ±0.5, soscale=0.4gives half-extent 0.2, not 0.4. This silently halves every dimension, misplacing all connected parts. - Euler rotation on cylinders — rotating a cylinder to point in a direction using Euler angles frequently points it along the wrong axis due to XYZ rotation order.
- Invisible gaps — parts placed "near" each other with no geometric overlap look exploded when rendered. Even a 5mm gap is visible at model scale.
- Bare-box output — nothing in the workflow asked for detail, so none was built. Phase 1.5 and Rules 6–11 fix this.
- Broken meshes — booleans and joins leave non-manifold edges, duplicate verts, and degenerate faces that bounding-box checks never see. The integrity gate (Phase 3) fixes this.
Helper library
All helper functions live in references/blender_helpers.py, versioned. At session start, read that file and execute it whole via the Blender MCP instead of re-pasting individual functions — this eliminates drift between copies. A new helper enters the library only after surviving its fixtures (library-learning convention). The v2 helpers are marked PENDING FIXTURES in the file header until validated.
Routing: build it, or generate it?
This skill covers parametric hard-surface modeling — anything definable by dimensions, joints, and repeated features (furniture, machines, crates, frames, pipes, electrical devices, weapons). For organic or densely decorative geometry (statues, creatures, irregular props, sculpted surfaces), hand-building in Blender is the expensive path: route to hunyuan3d-local (canonical image→3D ladder: local → fal → paid) instead (AI base mesh → optimize/remesh → this pipeline for cleanup and export). Decide before writing any geometry code; a half-sculpted bmesh blob is the worst of both worlds.
Phase 1: Connection Planning (before any code)
Create a connection map listing every joint before writing any geometry. This forces correct thinking about where parts touch.
For each joint, write:
- The two parts that connect
- Which face/edge of each meets the other
- The target overlap (minimum 0.005m / 5mm)
Connection Map:
tabletop_bottom (Z=0.73) <-> leg_top (Z=0.74) overlap: 0.01m on Z
leg_bottom (Z=0.01) <-> floor (Z=0.00) sits on floor
drawer_back <-> desk_body_front overlap: 0.01m on YWrite this as a comment block in your first code cell, before any bpy calls.
Phase 1.5: Detail Planning (before any code)
The connection map guarantees the model holds together; it does not stop the model from shipping as a set of bare boxes. A model with zero detail features is unfinished by default — nothing in the real world has perfect 90° edges.
Next to the connection map, write a detail list: for each visible part, enumerate the features the real object has, the technique that produces each, and its approximate size. Think like the reference photo, not like the primitive.
Detail List:
housing edge chamfer bevel 3mm/2seg all exterior edges
housing side vent recess inset+sink 0.12 x 0.06m, depth 5mm
housing corner bolts place_copies 4 per corner plate
front panel panel line inset+sink 2mm wide, 1mm deep
frame cable run make_cable r=6mm junction box to motor
grip compound shape loft_profile palm swell + taper
grip stippling bake (Rule 11) normal map, not geometryFloors (a model below these is not done):
- Every exterior edge of every visible part gets a bevel — Rule 6. No exceptions for "background" parts; un-beveled edges read as CGI from any distance.
- A hero object carries at least 3 distinct detail feature types (e.g. bevel + recess + hardware). If the detail list has fewer, go back to the reference before coding.
- Budget by LOD: full list on LOD0; drop hardware/recesses progressively on lower LODs (poly budgets live in
dayz-model-pipeline). - Fine surface detail (knurling, threads, stippling, stamped text) goes to the bake (Rule 11), never to LOD0 geometry.
If no reference image exists, get one first — blender-visual-review §C compares against it later, and a detail list invented from memory produces generic detail.
Detail scan protocol (added 2026-07-30, adapted from img2threejs v1.4.3, Apache-2.0 — provenance in blender-visual-review/references/NOTICE-img2threejs.md)
An eyeballed detail list misses small identity-defining marks — a bevel highlight, a row of rivets, a stain — because the whole reference gets one glance. Scan zone by zone and record the scan alongside the list:
- Scan method —
component-zoneswhen part boundaries are already planned (walk each part's region of the reference), elsegrid-3x3(inspect every cell, no skipping). Write which method was used at the top of the detail list. - Count floor by complexity — simple 3, moderate 6, complex 10, ultra-complex 16 details. A list below its floor means the scan stopped early — go back to the reference, not to memory. (The "≥3 distinct feature types on a hero object" floor above still applies; this one is about count.)
- Per-detail record — each row also carries: where on the reference (zone / grid cell), evidence (
seenin a specific crop vsinferredfrom symmetry or occlusion), and confidence 0–1. Inferred and occluded details score low and MUST NOT be counted toward the floor. - Maps-to gate — every row names the technique that builds it (Rules 6–11) or the texture channel that carries it (table below). A detail that maps to nothing is a planning failure: nothing reads prose, so it never reaches the model.
Texture-side detail kinds — the technique column above covers geometry; these kinds are details too and belong in the same list, with their destination in the DayZ texture pipeline (recipes in dayz-texture-pipeline):
| Kind | Reads as | DayZ destination |
| local gloss | low-roughness zone / specular hotspot on one region | _smdi gloss zone or rvmat |
| stain / patina / fade | darker cavity-biased dirt, gravity streaks, oxidation hue, sun-bleach | _co composite layer |
| scratch / chip | thin bright/dark line, may expose underlayer color at edges | _co + detail in the _nohq bake |
| decal / painted line | flat printed graphic or stripe — color contrast, zero relief | _co (or _ca when alpha) |
| emissive | self-lit region (LED, screen, ember) | rvmat emissive semantics |
Linework is three different techniques that read differently — pick the one the evidence supports, never default to geometry: an engraved groove is real negative relief that catches shadow (panel_recess / boolean); a painted line is color only (_co); a panel-line is a soft dark AO seam with no depth (bake / _co darkening). A hard groove where the reference shows a soft dark line is a wrong detail even though "a line" exists.
Phase 2: Geometry Creation Rules
Rule 1: Always Use size=2 for Cube Primitives
A cube with size=S has vertices at ±S/2. After scale=K, the half-extent is K * S/2 — not K.
Always use size=2. With size=2, vertices are at ±1, so after scale=K the half-extent equals K directly. The math is transparent and the factor-of-2 error disappears.
# CORRECT — size=2, scale = desired half-extent
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0.75))
obj.scale = (0.60, 0.30, 0.02) # box is 1.2m wide, 0.6m deep, 0.04m tall
# WRONG — size=1, scale misread as full extent
bpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0.75))
obj.scale = (0.60, 0.30, 0.02) # box is only 0.6m wide — half of intended!Cylinders and spheres use radius which is already the actual radius — no conversion needed.
Rule 2: Use bmesh for Directional Geometry — Never Rotate Cylinders
Never create a cylinder and rotate it to point in a direction. Euler rotation order (XYZ) makes this fail silently — the cylinder often ends up on the wrong axis.
For any geometry that must span from point A to point B (legs, beams, axles, supports, pipes, rails), build it with explicit vertex positions: make_beam(name, start, end, hw, hh) from the helper library.
Use for: chair/table legs, beams, axles, frame members, railings, any angled strut.
Skip for: vertical posts, wheels, hubs — anything aligned with a world axis where no rotation is needed.
For round cross-sections (pipes, cables, trigger guards): make_cable (Rule 8). For varying cross-sections (grips, stocks): loft_profile (Rule 10).
Rule 3: Always Call transform_apply Immediately After Setting Scale
When creating objects in a loop, bpy.context.active_object can silently reference the wrong object by the end of the loop, causing a scale assignment to fail or apply to the wrong mesh. Call transform_apply immediately after every scale assignment — inside the loop, before anything else:
# CORRECT
bpy.ops.mesh.primitive_cube_add(size=2, location=(x, y, z))
obj = bpy.context.active_object
obj.name = name
obj.scale = (sx, sy, sz)
bpy.ops.object.transform_apply(scale=True) # ← immediately, inside the loop
# WRONG — scale may silently not apply
obj.scale = (sx, sy, sz)
# ... more operations ...
bpy.ops.object.transform_apply(scale=True) # too late; active_object may have changedRule 4: Derive Spanning Dimensions from Verified Neighbour Bounds
Never hardcode a dimension for a part that must reach between two existing parts. Hardcoded values drift from actual geometry. Instead, call verify_bounds() on both neighbours and compute the required size from their real extents:
# CORRECT — measure first, then size the new part
b_a = verify_bounds("Part_A")
b_b = verify_bounds("Part_B")
half_span = (b_b['x'][1] - b_a['x'][0]) / 2 # actual half-width needed to bridge A and B
# WRONG — dimension set independently of actual neighbour positions
half_span = 0.28 # guessed; will be wrong if neighbours shifted even slightlyApply this rule whenever one part must cover, fill, or connect two others on any axis. Always measure the gap from real bounds; never guess.
Rule 5: Compensate for Subsurf Shrinkage
Subdivision surface modifiers pull geometry inward. A box spanning 0.0–0.30m may only reach 0.26m after level-2 subsurf.
Extend geometry 10–15% past the target boundary before applying subsurf, then verify:
target_reach = 0.28
build_to = target_reach * 1.13 # 13% longer to compensate for shrinkageAlternative: use bevel modifier instead of subsurf for structural parts — it adds smooth edges without shrinking the shape.
Rule 6: Bevel Every Exterior Edge (the box-to-object rule)
80% of the visual difference between "primitive" and "object" is edge bevels. Add an angle-limited bevel to every visible part as the last step of its construction, after all booleans: add_bevel(obj, width=0.003, segments=2, angle_deg=40) — width in meters, 2–4mm reads right at prop scale.
Apply (don't leave live) so LOD decimation and export see real geometry. Scale must already be applied (Rule 3) — a live scale makes bevel width anisotropic. Run verify_mesh_integrity after applying (Phase 3).
Rule 7: Panel Recesses and Insets via bmesh
Panel lines, vents, screens, and recessed faces come from inset + sink: panel_recess(obj, near_point, inset, depth). The face is picked by its world-space center — never by index, which changes with any earlier edit. For a raised panel instead of a recess, translate along +face.normal (edit the helper call). Chain two insets (frame + sink) for vent-style detail.
Rule 8: Repeated Hardware and Cables
Hardware (bolts, rivets, handles): model one low-poly instance (cylinder, 8 segments is plenty at bolt scale), then place copies by explicit loop with place_copies(src, positions) — consistent with this skill's explicit-math philosophy and easier to verify than an Array modifier. Each copy must overlap its mount surface by ≥1mm (the connection map applies to hardware too).
Cables / pipes / hoses / trigger guards: never chain rotated cylinders. make_cable(name, points, radius) builds a Bezier curve through explicit points, bevels it, and converts to mesh. Endpoints come from verify_bounds() of the parts being connected (Rule 4), with ≥5mm penetration into each.
Rule 9: Boolean Protocol
Booleans are the main source of broken meshes. Three rules, then mandatory cleanup:
- Apply scale on both operands first (Rule 3) — booleans on live scale produce garbage intersections.
- NEVER leave coplanar faces between operands. The cutter must overshoot every surface it cuts through by ≥1mm. Flush == coplanar == the #1 boolean failure (degenerate slivers, open holes).
- Solver is always
'EXACT'.
boolean_cut(target, cutter, op) enforces all three plus cleanup (remove_doubles + dissolve_degenerate). After every boolean, run verify_mesh_integrity before building anything on top. A broken mesh discovered three parts later costs the whole session.
(adjusted 2026-06-10, fixture F3) Point 2's "NEVER" is downgraded to a strong recommendation: Blender 5.1 EXACT handled an exactly-flush, axis-aligned cutter without breaking the mesh (identical open pocket and volume vs the overshoot cut, clean hard counters; only the ring-ngon layout differs — LL-119). Keep the ≥1mm overshoot as the default for robustness (float drift, oblique cuts), but a flush cut that passes the integrity gate plus the visual checkpoint is acceptable, not an automatic fail. The gate reports ngons as warnings, never failures (LL-120).
Rule 10: Loft Cross-Sections for Compound Shapes
Boxes and beams cannot make a pistol grip, a stock, a bottle, or an ergonomic handle. The technique for those is cross-section lofting: define a 2D profile, sweep it through a 3D path, scale it per section. This is the standard parametric approach for weapon grips and receivers.
Helpers: ellipse_profile(rx, ry, n), rounded_rect_profile(hw, hh, r, seg), loft_profile(name, profile, path, scales, close_caps).
Usage pattern for a grip: rounded_rect_profile swept down a slightly curved path with scales like [1.0, 1.05, 0.95, 0.9] (palm swell → taper). Path points come from the connection map; the top ring must overlap the receiver by ≥5mm. The helper recalculates face normals, so winding is verified rather than assumed — but degenerate rings (duplicate path points) still produce zero-area faces, so run verify_mesh_integrity after every loft. If the result looks faceted in review, raise the profile's n.
Rule 11: Fine Detail Goes to the Normal Map, Not to LOD0
Knurling, grip stippling, screw threads, stamped text, fine panel seams — modeling these as geometry blows the poly budget and still reads worse than a bake. The game-industry standard is the high→low pass, and it slots directly into the DayZ texture pipeline (_nohq normal map, AO multiplied into _co):
- Build the part twice from the same build script: high (bevel segments 4–6, knurl/thread geometry, deep panel lines) and low (game budget, Rules 1–10 only). Same script, two parameter sets — never two divergent scripts.
- UV-unwrap the low:
smart_uv(obj)(Smart UV Project is acceptable for hard surface; islands need margin or the bake bleeds). Smart UV Project atomizes: median 2-4 faces/island is the classic failure — an unusable atlas for detail texturing. For DayZ visual assets unwrap by logical SECTIONS with contiguous islands and a human-readable atlas; the gate is a human reading the atlas. Full reference:<vault>\AI\20_Knowledge\uv-mapping-dayz.md+ audit tool<dayz-projects>\LFQuad_dev\tools\uv_audit.py. - Bake from high to low with
bake_map(high, low, 'NORMAL', ...)andbake_map(high, low, 'AO', ...)(Cycles, selected-to-active).
Known pitfalls (all reproduced in community reports, all controllable):
- No UVs on the low → hard error.
smart_uvfirst, always. - High and low not occupying the same space, or
raytoo small/large → patchy garbage in the map. Tunemax_ray_distanceto slightly more than the largest high/low surface gap; use a cage for parts with deep recesses. - Blender bakes OpenGL-convention (Y+) tangent normals; DirectX-convention engines need the green channel inverted. Which convention DayZ's
_nohqexpects MUST be verified empirically against a vanilla_nohq(fixture F7) before shipping — do not guess and do not assume.
Output feeds dayz-model-pipeline: normal PNG → _nohq.paa, AO PNG → multiply layer in the _co composite.
(resolved 2026-06-10, fixture F7) DayZ
_nohqis DirectX-convention (Y−): invert the green channel (G' = 255−G) on every Cycles bake before export — Cycles emits OpenGL (Y+), verified by calibration. Full verdict, the DXT5nm swizzle caveat (the .paa stores X in alpha) and the reproducible calibration chain live indayz-model-pipeline§"Convención _nohq" and LL-123/LL-125. Theray=0.01default was validated by fixture F6 (clean 1024px NORMAL+AO bakes at a ~4mm high/low gap).
Phase 3: Verify After Every Part
Call these after creating each part. Catching a defect immediately is far cheaper than debugging an exploded or broken model later. All three live in the helper library.
verify_bounds(name) — print and return the world-space bounding box of a part.
verify_overlap(name_a, name_b, axis, min_overlap) — confirm two parts physically overlap on the given axis. Run for every joint in your connection map before moving to the next part. If it shows a gap, fix the position before continuing.
verify_mesh_integrity(name, require_closed, allow_ngons) — the broken-geometry gate. verify_bounds proves position; it passes happily on a non-manifold mess. This gate proves the mesh itself is sound. Run it after every boolean, every modifier apply, every loft, and once per part at finalization. Reading the result:
non_manifold_edges > 0— an edge shared by 3+ faces: almost always a boolean leftover or two parts joined without merging. Fix at the operation that caused it; don't patch around it.duplicate_verts > 0— runremove_doubleson the real mesh (the gate's pass is on a throwaway copy).boundary_edges > 0withrequire_closed=True— a hole. Collision geometry MUST be closed; for visual meshes with intentional openings, call withrequire_closed=Falseand record why in the build script comment.ngonson curved surfaces shade badly and decimate badly — triangulate or re-inset; on large flat faces they're tolerable (hence warn, not hard fail).
The gate failing means stop and fix before the next part — same discipline as verify_overlap, same reason: broken geometry compounds.
Component checkpoint: for complex parts (lofts, boolean-heavy pieces), also take one quick visual capture of the part alone before building on top — see blender-visual-review. Numbers verify topology; only eyes verify intent.
Moving mechanisms: check the fit over the WHOLE travel and the whole length (SP-451, added 2026-10-01) [OFFLINE MEASURED]. A vertical mechanism checked on one representative section failed twice on SecretRock R7: standing leaves checked only at their widest section (y = 0.8) stuck out of the rock by up to 0.96 m elsewhere, and a platform checked only at the top touched the lining at the hangar end by up to 1.1 m.
Per-frame sampling skips short collisions [OFFLINE MEASURED]: folding a 2.46 m leaf hinged on its top edge
brings each lower corner 4.7 mm closer in the first degrees — a collision shorter than one frame. Sweep the
kinematics with hand-set angles and a fine step near 0°, with the actions unhooked so the depsgraph does not
override the angles. (Keyframe clearance in presentation renders: blender-visual-review §A, "Animated
parts".)
Phase 4: Finalization
Apply to every mesh object: finalize(name) (transforms applied, origin set, shade smooth), then audit_all() to confirm rotation=(0,0,0) and scale=(1,1,1) across the whole scene. Both in the helper library.
Workflow Checklist
Every Blender model, every time:
- Route first — parametric hard-surface stays here; organic/sculpted goes to
hunyuan3d-local(canonical image→3D ladder: local → fal → paid) - Connection map — every joint, written before any bpy code
- Detail list — zone-scanned (
grid-3x3/component-zones), count floor by complexity, every row maps to a technique or texture channel; ≥3 feature types on a hero object; reference image in hand size=2for all cube primitives — scale = actual half-extentmake_beam()/make_cable()/loft_profile()for A-to-B and compound shapes — no Euler rotations, evertransform_apply(scale=True)immediately after every scale assignment, inside the loop- Spanning dimensions from
verify_bounds()— measured, never guessed - Booleans by protocol — scale applied, cutter overshoots ≥1mm, EXACT, cleanup, gate
- Bevel every visible part — angle-limited, applied, after all booleans
- Fine detail to the bake — high/low twins from one script,
smart_uv+bake_map(NORMAL + AO), never knurl on LOD0 verify_bounds()+verify_overlap()after every part, every jointverify_mesh_integrity()after every boolean/modifier apply, every loft, and at finalization- Component checkpoint — one quick
vr_captureof each complex part (lofts, boolean-heavy) before building on top finalize()+audit_all()— transforms clean across the scene- Hand off to
blender-visual-review— numbers verify topology; only eyes verify intent
MCP render-depsgraph stale after in-place mesh edits (added 2026-06-11, verified 2026-06-10)
When driving the HOST Blender via MCP, obj.data.transform() (and other low-level in-place
datablock writes) update the data — verifiable by reading vertices — but the RENDER depsgraph
keeps serving a FROZEN copy of that datablock: every render.render() shows the pre-edit mesh.
data.update(), update_tag(), view_layer.update() and evaluated_depsgraph_get().update()
do NOT clear it, and a mesh.copy() INHERITS the stale cache. NEW objects render fine.
- Fix: write edited geometry to a new mesh datablock via
bm.to_mesh(new_mesh)and link it on a NEW object; remove the old object+mesh. Cost of not knowing: phantom renders that contradict your measurements (nearly mis-diagnosed a correct orientation on A6_MK47). - Diagnose with the marker-sphere test: add primitive spheres at known coords and render — markers correct + mesh stale = this cache, not your math.
- Also:
bpy.context.scenecan silently revert to the USER's scene between MCP calls — pinbpy.context.window.sceneand passscene=torender.render()on EVERY call, or you render (and screenshot) the wrong scene.
Rules promoted from the lessons corpus (added 2026-07-27)
Promoted from AI/20_Knowledge/lessons-learned.md so that they arrive via trigger instead
of relying on someone remembering to look them up. Each rule cites its source LL-NNN;
the full entry (symptom, origin, evidence) lives there. Do not remove the citation: the index
lessons-index.md detects promotion by searching for that reference inside the skills.
- LL-065 — Do not use booleans to carve open or non-watertight organic meshes; prefer extruding the boundary loop or doing manual bridge. If you use boolean, operate between closed solids and validate raycast, boundary, and non-manifold before continuing.
- LL-121 — After modifying
location,rotation, orscalevia API, executebpy.context.view_layer.update()before readingmatrix_world. Place the update in the reader helper and use fixtures that vary all axes. - LL-122 — For closed tubes, enable
use_fill_caps, convert to mesh, and weld withremove_doubles(1e-5). Maintain therequire_closedgate; do not lower it for boundary edges. - LL-126 — Always call
transform_apply(location=False, rotation=<bool>, scale=<bool>)with all three arguments explicit. Create copy sources at world origin before baking transforms. - LL-127 — Call
finalize()immediately on newly created active object; do not iterate names expecting helper to do lookup. Verify helper's actual contract and confirm name→bbox after renaming. - LL-128 — For planar curved pieces, build a 2.5D loft with fixed world-axis width and depth derived from planar tangent. Execute
remove_doublesanddissolve_degenerateafter each loft. - LL-129 — In hollow pieces, size each cutter to cross only the target wall, with overshoot toward hollow without reaching opposing wall. Execute integrity gate after each boolean.
- LL-132 — Keep components of each cutter disjoint and apply circles/slots in separate passes. Make gate fail if mesh is left with zero vertices and alert if successive operations produce identical signatures.
- LL-133 — Do not use
panel_recesson loft caps/ngons; use an oriented boolean or defer detail to bake. Position cutters from analytical path, scales, and profile, never sampling bands of the resulting mesh.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

