Skip to content

Commit e7e10fb

Browse files
TMHSDigitalclaude
andauthored
feat(examples): add gn-sim-fountain (#299)
Witness the Simulation Zone frame contract: stepped frames land on the closed-form ballistic arc, an unbaked frame_set(N) jump runs one step, and calculate_to_frame is PASS_THROUGH headless. Only a bake gives random access. Identical on 4.5, 5.1 and 5.2. Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent 54e7f71 commit e7e10fb

15 files changed

Lines changed: 1832 additions & 13 deletions

File tree

‎.cursor-plugin/plugin.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
"examples/gn-instance-grid",
103103
"examples/gn-modifier-inputs",
104104
"examples/gn-sdf-remesh",
105+
"examples/gn-sim-fountain",
105106
"examples/gn-socket-rename",
106107
"examples/gn-zone-iterate",
107108
"examples/gp-lineart-contour",

‎AGENTS.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ a `.cursor-plugin/plugin.json` manifest so the ecosystem drift checker
2020
classifies it as a `cursor-plugin`. This is content the AI loads when the user
2121
asks Blender questions or works on Blender add-ons in Cursor or Claude Code.
2222

23-
The content base is 16 skills, 9 rules, 3 templates, 27 snippets, 59
23+
The content base is 16 skills, 9 rules, 3 templates, 27 snippets, 60
2424
examples, and 26 showcase pieces (counts are CI-enforced against README.md)
2525
and the manifest). The full inventory tables and per-item purposes live in
2626
`CLAUDE.md`. Example anatomy and authoring rules: copy `examples/bmesh-gear/`;
@@ -36,7 +36,7 @@ Blender-Developer-Tools/
3636
rules/<rule-name>.mdc # 9 rule files
3737
templates/<template-name>/ # 3 starter templates
3838
snippets/<snippet-name>.py # 27 standalone Python snippets
39-
examples/<name>/ # 59 runnable smoke-gated examples (+ gallery.json)
39+
examples/<name>/ # 60 runnable smoke-gated examples (+ gallery.json)
4040
examples/gallery_framing.py # shared Layer 1 framing measurement (render path only)
4141
showcase/<name>/ # budget-conformance props (sibling of examples/)
4242
showcase/gallery.json # this tree's gallery index; merged into docs/gallery/

‎CLAUDE.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ skills/<skill-name>/SKILL.md - AI workflow definitions, 16 total
2121
rules/<rule-name>.mdc - Anti-pattern rules, 9 total
2222
templates/<template-name>/ - Starter projects, 3 total
2323
snippets/<snippet-name>.py - Standalone code patterns, 27 total
24-
examples/<name>/ - Runnable smoke-gated examples, 59 total (+ gallery.json)
24+
examples/<name>/ - Runnable smoke-gated examples, 60 total (+ gallery.json)
2525
showcase/<name>/ - Budget-conformance props, 36 pieces (sibling of examples/; see showcase/README.md)
2626
scripts/build_gallery.py - Regenerates docs/gallery/ from examples/gallery.json + showcase/gallery.json
2727
scripts/site/ - Vendored landing-page build (Jinja2)
@@ -104,12 +104,12 @@ v0.2.0: Principled BSDF material, driver-with-custom-function via `driver_namesp
104104

105105
AI asset pipeline track: `decimate_to_budget.py`, `convex_hull_collider.py`, `lod_chain.py` (helper duplicated, not imported), `gltf_draco_export.py`, `export_preset_unity.py`, `export_preset_godot.py`, `export_preset_unreal.py`, `setup_bake_target_image.py`, `bake_normal_high_to_low.py`, `save_baked_image.py`.
106106

107-
## Examples (59)
107+
## Examples (60)
108108

109109
Runnable scripts at `examples/<name>/`, each asserting a real API contract with
110110
deterministic checks (exit non-zero on failure) and optionally rendering a still via
111111
`--output`. All of them run headless on Blender 5.2 LTS and 4.5 LTS in `blender-smoke.yml` (5.1 on the weekly cron, the `needs-5.1` PR label, or manual dispatch);
112-
**51 of the 59 ship a render in the site gallery** at `docs/gallery/`. The other
112+
**52 of the 60 ship a render in the site gallery** at `docs/gallery/`. The other
113113
eight are **check-only**: they carry no `--output` path, no gallery entry, and no
114114
hero asset. The criterion is whether the contract is expressible in pixels. An
115115
example is check-only when its witness is a data or state fact that no scene

‎README.md‎

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
</p>
1919

2020
<p align="center">
21-
<strong>16 skills</strong> &nbsp;&bull;&nbsp; <strong>9 rules</strong> &nbsp;&bull;&nbsp; <strong>3 templates</strong> &nbsp;&bull;&nbsp; <strong>27 snippets</strong> &nbsp;&bull;&nbsp; <strong>59 examples</strong> &nbsp;&bull;&nbsp; <strong>36 showcase pieces</strong>
21+
<strong>16 skills</strong> &nbsp;&bull;&nbsp; <strong>9 rules</strong> &nbsp;&bull;&nbsp; <strong>3 templates</strong> &nbsp;&bull;&nbsp; <strong>27 snippets</strong> &nbsp;&bull;&nbsp; <strong>60 examples</strong> &nbsp;&bull;&nbsp; <strong>36 showcase pieces</strong>
2222
</p>
2323

2424
<p align="center">
@@ -37,7 +37,7 @@
3737

3838
## Overview
3939

40-
This repository ships **16 skills, 9 rules, 3 templates, 27 snippets, 59 examples, and 36 showcase pieces** for Blender Python development targeting Blender 5.2 LTS (current stable) with Blender 4.5 LTS fallback support. Blender 5.1 is prior stable.
40+
This repository ships **16 skills, 9 rules, 3 templates, 27 snippets, 60 examples, and 36 showcase pieces** for Blender Python development targeting Blender 5.2 LTS (current stable) with Blender 4.5 LTS fallback support. Blender 5.1 is prior stable.
4141

4242
The content is consumed by AI coding agents reading these files directly from a checkout — **there is no MCP server in this repository, and none is required**. Cursor applies `rules/*.mdc` automatically wherever their scope globs match and takes skills by name in chat; Claude Code reads `skills/` and `rules/` from the project workspace, or from this repo kept as a referenced checkout. Any agent that can read files in a workspace can use it the same way. There is no build step for the content — edit the Markdown and Python files directly.
4343

@@ -75,7 +75,7 @@ blender --background --python examples/bmesh-gear/bmesh_gear.py --
7575

7676
## Falsifiers
7777

78-
Every one of the 59 examples carries a **falsifier**: a flag that changes the
78+
Every one of the 60 examples carries a **falsifier**: a flag that changes the
7979
input so a real assertion fails. It never disables the assertion, skips the
8080
check, or short-circuits to an error — it feeds the script something the
8181
contract says must not pass, and the same check that guards the happy path
@@ -556,7 +556,7 @@ exits 0 on all three. `--assume-present` is red only on 5.2.
556556
</details>
557557

558558
<details>
559-
<summary><strong>Geometry Nodes</strong> — 6 examples</summary>
559+
<summary><strong>Geometry Nodes</strong> — 7 examples</summary>
560560

561561
<table>
562562
<tr>
@@ -617,6 +617,23 @@ evaluated cubes against closed forms — Repeat `8×(1+N)` with X-centers at
617617
nodes exist. Unpaired evaluates empty; For Each's main Geometry socket is a
618618
passthrough.
619619

620+
</td>
621+
</tr>
622+
<tr>
623+
<td width="46%" valign="middle">
624+
<a href="examples/gn-sim-fountain/"><img src="examples/gn-sim-fountain/preview.webp" alt="GN simulation fountain: a two-tier sandstone fountain whose twenty jets are strings of cyan droplet beads, each bead a stepped Simulation Zone position threaded on its thin closed-form ballistic arc" /></a>
625+
</td>
626+
<td valign="middle">
627+
628+
### [gn-sim-fountain](examples/gn-sim-fountain/)
629+
630+
A Simulation Zone integrates twenty jets under gravity with the exact
631+
constant-g update, and every stepped frame lands on `p0 + v0 t - g t^2/2`
632+
(worst 6.6e-7 m). Two silent traps, identical on 4.5, 5.1 and 5.2: a direct
633+
`frame_set(N)` jump runs one step, not N; and `calculate_to_frame` returns
634+
`PASS_THROUGH` headless and leaves interpolated frames. Only a bake gives
635+
random access.
636+
620637
</td>
621638
</tr>
622639
<tr>

‎ROADMAP.md‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,14 +176,17 @@ Not committed; target list for the next content version. (v0.3.0 shipped the smo
176176
- **Flagship showcase: pirate sloop** — lofted hull from stations, deck planking, mast, boom, gaff, shrouds and ratlines to chainplates, cannon ports: hull mirror-symmetric to the keel plane, every shroud terminating on its chainplate and masthead within a band, ratlines horizontal and evenly spaced
177177
- **Flagship showcase: full chess set on a board** — 32 lathe-turned pieces (king to pawn, two woods) on an inlaid board: every piece centred on its square's computed centre, base seated on the board, lathe profiles revolved exactly (radii match profile closed form), 64 squares alternating by (file + rank) parity
178178
- **Flagship showcase: modular dungeon kit** — floor, wall, corner, arch, stair and pillar tiles on a 2 m grid composed into a room: every open-edge boundary vert on the grid, zero gap/overlap at every joint, stair riser × count equal to one storey height, per-tile budgets plus a composed-room budget
179-
- **Flagship example: GN simulation-zone ballistic fountain** — a Simulation Zone integrating particles under gravity: positions at frame N match the closed-form ballistic arc (p₀ + v₀t − ½gt²) per particle, determinism across re-bakes, and the 4.x vs 5.x bake/cache API paths documented; `--no-cache-reset` falsifier
179+
- ~~**Flagship example: GN simulation-zone ballistic fountain**~~ **SHIPPED** as `examples/gn-sim-fountain/` — 20 jets integrated by the exact constant-g update land on p₀ + v₀t − ½gt² every stepped frame; an unbaked `frame_set(N)` jump runs one step, `calculate_to_frame` is PASS_THROUGH headless, only a bake gives random access. The 4.x vs 5.x divergence the entry anticipated does not exist: zone and bake operators measured identical on 4.5.11, 5.1.2 and 5.2.1. Falsifiers `--unpair` / `--euler` / `--prebake-trap` / `--calc-to-frame` replace the proposed `--no-cache-reset`, which had no failing check to target
180180
- **Flagship example: GN procedural building generator** — one node tree with floor count, bay count and roof type as modifier inputs driving storeys, windows (instanced), cornices and a pitched or flat roof: window instance count = floors × bays × faces closed-form, storey heights exact, three buildings from the same tree side by side
181181
- **Flagship example: GN road along a curve** — a Bezier path swept into a road with kerbs, lane markings and lamp posts instanced at equal arc-length spacing aligned to the tangent: post count = floor(length / spacing) + 1, every post perpendicular to the curve tangent within a band
182182
- **Flagship example: L-system tree via GN repeat zone** — branching generated by a Repeat Zone: branch/leaf counts closed-form in the iteration depth, each child branch attached to its parent's tip, total height the closed-form series sum
183183
- **Flagship example: UDIM texture set** — `Image.tiles.new` for 1001–1004, a UV layout spanning four tiles, per-tile bake/paint writes: tile numbers map to UV offsets exactly, each tile's pixels land only in its tile, `<UDIM>` filepath round-trips through save and reload
184184
- **Flagship example: channel-packed ORM bake** — Cycles-bake AO, roughness and metallic of a prop into R/G/B of one Non-Color image: each channel matches its independently baked single-channel reference within a stated tolerance, and sRGB tagging is the falsifier
185185
- **Flagship example: Cryptomatte ID witness** — a multi-object scene rendered with Cryptomatte passes to multilayer EXR: decoded object IDs (MurmurHash3 of the names) cover exactly each object's coverage mask, re-read with the stdlib-only EXR reader
186186
- **Flagship example: walk cycle with planted feet** — slotted-action walk cycle on a leg rig with IK and NLA strip blending: planted-foot world position constant during each contact phase (foot slide below a band), stride length × cycles equals root travel, 4.5 vs 5.x channelbag paths
187+
- Simulation-zone cache interpolation witness — frames between two cached simulation frames read as a linear interpolation of the endpoints (measured: steps 1.27 at frame 4 between cached 1 and 12), not a simulated state; assert the interpolant closed form and that a bake removes it (found authoring `gn-sim-fountain`)
188+
- Operator PASS_THROUGH trap snippet — an operator whose poll fails headless (`simulation_nodes_cache_calculate_to_frame`) logs "Invalid operator call" and returns `{'PASS_THROUGH'}` without raising; check the returned set, never assume a non-raising `bpy.ops` call ran (found authoring `gn-sim-fountain`)
189+
- Simulation-zone substeps witness — a Repeat Zone inside the Simulation Zone splitting Delta Time into k substeps: explicit Euler error shrinks exactly by 1/k against the closed-form arc, the exact update is invariant in k
187190
- ~~Small modular kit showcase on recognizable geometry (`modular-kit-snap` contract)~~ **SHIPPED** as `showcase/fence-kit/` — tiling post-and-rail section (AABB X is the tile width; does not re-witness the snap contract); `--skip-decimate` exits 9 on the LOD1 ratio band
188191

189192
- ~~Custom ID-property delete witness~~ **SHIPPED** as `examples/cross-version-property-delete/` — IDs built via `bpy.data.objects.new` (not `active_object`); `property_unset` is TypeError and leaves the key; `del` removes it on 4.5 LTS and 5.x
54.7 KB
Loading
53.9 KB
Loading

0 commit comments

Comments
 (0)