Skip to content

Commit 1cde7d3

Browse files
TMHSDigitalclaude
andcommitted
feat(showcase): add canyon-mesa-tile (terrain)
A square desert map tile of Colorado Plateau character: two mesas with a canyon between them, a butte and a spire, all cut from one horizontal layer cake (talus apron at the angle of repose, five bedded sandstone beds, a shale slope, a flat overhanging caprock), a dry wash falling edge to edge, a dune field, fallen blocks, junipers, sage and cottonwoods. Measured invariants with falsifiers: formations sealed in their aprons (--perch-butte 17), bedding planes at one height on every formation and across the canyon (--tilt-beds 18), caprock tops flat (--dome-cap 19), talus inside 30-37 deg (--steep-talus 20), the wash never rising and crossing the tile (--uphill-wash 21), blocks sealed and apart (22, 23), plants rooted (--float-plants 24). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 94bf214 commit 1cde7d3

94 files changed

Lines changed: 3073 additions & 168 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎AGENTS.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ 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

2323
The content base is 18 skills, 9 rules, 3 templates, 29 snippets, 66
24-
examples, and 77 showcase pieces (counts are CI-enforced across README.md, the agent docs, ROADMAP.md,
24+
examples, and 78 showcase pieces (counts are CI-enforced across README.md, the agent docs, ROADMAP.md,
2525
`site.json` and the site templates). The full inventory tables and per-item purposes live in
2626
`CLAUDE.md`. Example anatomy and authoring rules: copy `examples/bmesh-gear/`;
2727
showcase conventions: `showcase/README.md`. The render look is specified

‎CLAUDE.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ 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, 29 total
2424
examples/<name>/ - Runnable smoke-gated examples, 66 total (+ gallery.json)
25-
showcase/<name>/ - Budget-conformance props, 77 pieces, each with a gallery `category` (sibling of examples/; see showcase/README.md § Categories)
25+
showcase/<name>/ - Budget-conformance props, 78 pieces, each with a gallery `category` (sibling of examples/; see showcase/README.md § Categories)
2626
scripts/build_gallery.py - Regenerates docs/gallery/ from examples/gallery.json + showcase/gallery.json
2727
scripts/site/ - Vendored landing-page build (Jinja2); tokens.css is the shared palette
2828
tests/check_site_links.py - Internal link/anchor/alt gate over the built site (docs/)

‎CONTRIBUTING.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ The drift-check workflow enforces these on every push and PR.
287287

288288
## Aggregate Counts
289289

290-
`README.md` declares aggregate counts (e.g. "18 skills, 9 rules, 3 templates, 29 snippets, 66 examples, and 77 showcase pieces"). The `validate-counts` job in `.github/workflows/validate.yml` enforces these substrings against the filesystem on every push and PR. Showcase pieces are counted separately from examples. When you add or remove content, update the README counts in the same commit.
290+
`README.md` declares aggregate counts (e.g. "18 skills, 9 rules, 3 templates, 29 snippets, 66 examples, and 78 showcase pieces"). The `validate-counts` job in `.github/workflows/validate.yml` enforces these substrings against the filesystem on every push and PR. Showcase pieces are counted separately from examples. When you add or remove content, update the README counts in the same commit.
291291

292292
## Pull Request Process
293293

‎README.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
</p>
2626

2727
<p align="center">
28-
<strong>18 skills</strong> &nbsp;&bull;&nbsp; <strong>9 rules</strong> &nbsp;&bull;&nbsp; <strong>3 templates</strong> &nbsp;&bull;&nbsp; <strong>29 snippets</strong> &nbsp;&bull;&nbsp; <strong>66 examples</strong> &nbsp;&bull;&nbsp; <strong>77 showcase pieces</strong>
28+
<strong>18 skills</strong> &nbsp;&bull;&nbsp; <strong>9 rules</strong> &nbsp;&bull;&nbsp; <strong>3 templates</strong> &nbsp;&bull;&nbsp; <strong>29 snippets</strong> &nbsp;&bull;&nbsp; <strong>66 examples</strong> &nbsp;&bull;&nbsp; <strong>78 showcase pieces</strong>
2929
</p>
3030

3131
<p align="center">
@@ -44,7 +44,7 @@
4444

4545
## Overview
4646

47-
This repository ships **18 skills, 9 rules, 3 templates, 29 snippets, 66 examples, and 77 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.
47+
This repository ships **18 skills, 9 rules, 3 templates, 29 snippets, 66 examples, and 78 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.
4848

4949
The content is consumed by AI coding agents, installed as a plugin or read from a checkout — **there is no MCP server in this repository, and none is required**. Cursor and Claude Code both install it as a plugin (see [Quick start](#quick-start)): Cursor loads the skills and applies `rules/*.mdc` wherever their scope globs match; Claude Code loads the skills and gets the rules through a generated `blender-rules` skill, since it does not read Cursor `.mdc` files. An agent picks a skill up when its description matches the task. 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.
5050

@@ -140,7 +140,7 @@ per-script exit-code model, are in
140140

141141
## Examples and showcase
142142

143-
**66 examples** in [`examples/`](examples/) are runnable, self-checking scripts: each asserts one API contract, carries a falsifier, and runs headless on Blender 5.2 LTS and 4.5 LTS in the `blender-smoke` workflow (5.1 on the weekly cron or by manual dispatch). Those whose contract is visible also render a still. **77 showcase pieces** in [`showcase/`](showcase/) exist to show the skills working together at production scale: each is a single headless script that models a game prop, then runs it through the same cleanup, bake, LOD, collider and export steps the skills teach, and fails if a measured budget (triangle counts, colliders, materials, real-world size) is missed. They are not API examples. Conventions: [`showcase/README.md`](showcase/README.md).
143+
**66 examples** in [`examples/`](examples/) are runnable, self-checking scripts: each asserts one API contract, carries a falsifier, and runs headless on Blender 5.2 LTS and 4.5 LTS in the `blender-smoke` workflow (5.1 on the weekly cron or by manual dispatch). Those whose contract is visible also render a still. **78 showcase pieces** in [`showcase/`](showcase/) exist to show the skills working together at production scale: each is a single headless script that models a game prop, then runs it through the same cleanup, bake, LOD, collider and export steps the skills teach, and fails if a measured budget (triangle counts, colliders, materials, real-world size) is missed. They are not API examples. Conventions: [`showcase/README.md`](showcase/README.md).
144144

145145
Browse both, with filters, full-size renders and each script's README, in the **[gallery](https://tmhsdigital.github.io/Blender-Developer-Tools/gallery/)**.
146146

@@ -163,7 +163,7 @@ rules/<name>.mdc - 9 rule files, anti-pattern + correction
163163
templates/<name>/ - 3 template directories (extension-addon-template, headless-batch-script-template, ai-asset-pipeline-template)
164164
snippets/<name>.py - 29 standalone Python snippets, 5 to 75 lines each
165165
examples/<name>/ - 66 example directories: script, README with exit codes and falsifier
166-
showcase/<name>/ - 77 showcase pieces: budget-gated game props, script and README
166+
showcase/<name>/ - 78 showcase pieces: budget-gated game props, script and README
167167
claude/ - generated Claude Code copies of the rules (blender-rules skill + import file)
168168
```
169169

‎ROADMAP.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ Not committed; open subjects only. Remove a subject when it ships (CLAUDE.md §
152152
- **Nature:** (all candidates shipped)
153153
- **Household:** laundry basket
154154
- **Vehicles:** sci-fi supply crate
155-
- **Terrain:** river delta tile; canyon mesa tile; terraced paddy hillside; volcanic caldera island
155+
- **Terrain:** river delta tile; terraced paddy hillside; volcanic caldera island
156156
- `persistent` app-handler witness — handlers registered without `@bpy.app.handlers.persistent` are dropped by `wm.read_homefile`/file load while persistent ones survive; assert the registered-handler set before and after a reload (silent loss AI code hits)
157157
- Link vs append witness — `bpy.data.libraries.load(link=True)` yields a linked, non-editable datablock (`library` set, `is_editable` False) while append yields a local copy; write a temp .blend with `bpy.data.libraries.write`, then assert both paths
158158
- Orphan purge witness — `bpy.data.orphans_purge(do_recursive=...)` removes exactly the zero-user datablocks computed independently beforehand, and `bpy.data.batch_remove` removes a given set in one call (counts closed-form)

‎docs/gallery/anvil/index.html‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ <h1>Anvil</h1>
4848
<p>A procedural blacksmith anvil on a timber stump through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.</p>
4949
</header>
5050
<main id="main">
51-
<nav class="pager" aria-label="Showcase pieces"><a rel="prev" href="../wheelbarrow/" aria-label="Previous showcase piece: wheelbarrow"><span aria-hidden="true">&larr;</span><span class="pager-label">wheelbarrow</span></a><span class="pager-pos hud">14 of 77 showcase pieces<span class="pager-keys"> &middot; <kbd>&larr;</kbd><kbd>&rarr;</kbd></span></span><a rel="next" href="../water-trough/" aria-label="Next showcase piece: water-trough"><span class="pager-label">water-trough</span><span aria-hidden="true">&rarr;</span></a></nav>
51+
<nav class="pager" aria-label="Showcase pieces"><a rel="prev" href="../wheelbarrow/" aria-label="Previous showcase piece: wheelbarrow"><span aria-hidden="true">&larr;</span><span class="pager-label">wheelbarrow</span></a><span class="pager-pos hud">14 of 78 showcase pieces<span class="pager-keys"> &middot; <kbd>&larr;</kbd><kbd>&rarr;</kbd></span></span><a rel="next" href="../water-trough/" aria-label="Next showcase piece: water-trough"><span class="pager-label">water-trough</span><span aria-hidden="true">&rarr;</span></a></nav>
5252
<button class="detail-hero" id="heroZoom" type="button" aria-label="View full size: A London-pattern forged anvil with a thick face block, tapered horn and broad flared foot on a hooped oak stand, a cross-peen hammer on the floor beside it.">
5353
<img src="../assets/anvil-hero.webp" alt="A London-pattern forged anvil with a thick face block, tapered horn and broad flared foot on a hooped oak stand, a cross-peen hammer on the floor beside it." width="1280" height="720" fetchpriority="high" />
5454
</button>
@@ -139,7 +139,7 @@ <h3><a class="stretch" href="../wooden-barrel/">Wooden Barrel</a></h3>
139139
</article>
140140
</div>
141141
</section>
142-
<nav class="pager pager-foot" aria-label="Showcase pieces"><a rel="prev" href="../wheelbarrow/" aria-label="Previous showcase piece: wheelbarrow"><span aria-hidden="true">&larr;</span><span class="pager-label">wheelbarrow</span></a><span class="pager-pos hud">14 of 77 showcase pieces</span><a rel="next" href="../water-trough/" aria-label="Next showcase piece: water-trough"><span class="pager-label">water-trough</span><span aria-hidden="true">&rarr;</span></a></nav>
142+
<nav class="pager pager-foot" aria-label="Showcase pieces"><a rel="prev" href="../wheelbarrow/" aria-label="Previous showcase piece: wheelbarrow"><span aria-hidden="true">&larr;</span><span class="pager-label">wheelbarrow</span></a><span class="pager-pos hud">14 of 78 showcase pieces</span><a rel="next" href="../water-trough/" aria-label="Next showcase piece: water-trough"><span class="pager-label">water-trough</span><span aria-hidden="true">&rarr;</span></a></nav>
143143
</main>
144144
<dialog class="lightbox" id="lightbox" aria-label="Full-size render">
145145
<div class="lightbox-bar"><button class="lightbox-close" id="lightboxNative" type="button" aria-pressed="false">Actual size</button><button class="lightbox-close" id="lightboxClose" type="button" autofocus>Close</button></div>

‎docs/gallery/apothecary-shelf/index.html‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ <h1>Apothecary Shelf</h1>
4848
<p>A procedural apothecary shelf — housed shelves, gallery rails, a drawer bank and an arched crest, stocked with fifteen lathed bottles, flasks and glazed jars, each corked or lidded and labelled — carried through UVs, bake, LOD, convex collider, and Unity glTF, asserting recomputed budgets rather than an API contract.</p>
4949
</header>
5050
<main id="main">
51-
<nav class="pager" aria-label="Showcase pieces"><a rel="prev" href="../brazier/" aria-label="Previous showcase piece: brazier"><span aria-hidden="true">&larr;</span><span class="pager-label">brazier</span></a><span class="pager-pos hud">32 of 77 showcase pieces<span class="pager-keys"> &middot; <kbd>&larr;</kbd><kbd>&rarr;</kbd></span></span><a rel="next" href="../wooden-yoke/" aria-label="Next showcase piece: wooden-yoke"><span class="pager-label">wooden-yoke</span><span aria-hidden="true">&rarr;</span></a></nav>
51+
<nav class="pager" aria-label="Showcase pieces"><a rel="prev" href="../brazier/" aria-label="Previous showcase piece: brazier"><span aria-hidden="true">&larr;</span><span class="pager-label">brazier</span></a><span class="pager-pos hud">32 of 78 showcase pieces<span class="pager-keys"> &middot; <kbd>&larr;</kbd><kbd>&rarr;</kbd></span></span><a rel="next" href="../wooden-yoke/" aria-label="Next showcase piece: wooden-yoke"><span class="pager-label">wooden-yoke</span><span aria-hidden="true">&rarr;</span></a></nav>
5252
<button class="detail-hero" id="heroZoom" type="button" aria-label="View full size: A stained wooden shelf with an arched crest, gallery rails and three brass-knobbed drawers, stocked with labelled glass bottles and flasks and cream and blue glazed jars.">
5353
<img src="../assets/apothecary-shelf-hero.webp" alt="A stained wooden shelf with an arched crest, gallery rails and three brass-knobbed drawers, stocked with labelled glass bottles and flasks and cream and blue glazed jars." width="1280" height="720" fetchpriority="high" />
5454
</button>
@@ -144,7 +144,7 @@ <h3><a class="stretch" href="../wooden-barrel/">Wooden Barrel</a></h3>
144144
</article>
145145
</div>
146146
</section>
147-
<nav class="pager pager-foot" aria-label="Showcase pieces"><a rel="prev" href="../brazier/" aria-label="Previous showcase piece: brazier"><span aria-hidden="true">&larr;</span><span class="pager-label">brazier</span></a><span class="pager-pos hud">32 of 77 showcase pieces</span><a rel="next" href="../wooden-yoke/" aria-label="Next showcase piece: wooden-yoke"><span class="pager-label">wooden-yoke</span><span aria-hidden="true">&rarr;</span></a></nav>
147+
<nav class="pager pager-foot" aria-label="Showcase pieces"><a rel="prev" href="../brazier/" aria-label="Previous showcase piece: brazier"><span aria-hidden="true">&larr;</span><span class="pager-label">brazier</span></a><span class="pager-pos hud">32 of 78 showcase pieces</span><a rel="next" href="../wooden-yoke/" aria-label="Next showcase piece: wooden-yoke"><span class="pager-label">wooden-yoke</span><span aria-hidden="true">&rarr;</span></a></nav>
148148
</main>
149149
<dialog class="lightbox" id="lightbox" aria-label="Full-size render">
150150
<div class="lightbox-bar"><button class="lightbox-close" id="lightboxNative" type="button" aria-pressed="false">Actual size</button><button class="lightbox-close" id="lightboxClose" type="button" autofocus>Close</button></div>

‎docs/gallery/archery-target/index.html‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ <h1>Archery Target</h1>
4848
<p>A procedural archery range target on a turf patch — a 1.10 m compressed-straw boss coiled from rope courses that show on its back and round its edge, bound with doubled jute twine drawn tight over the crests; an 80 cm ten-zone World Archery face in aged inks with ring lines, an X ring and a printed X, held by four target pins; a timber easel leaning it back 12° on toe skids with knee braces, a ledge with a stop lip on a bolted rail and gussets, a numbered butt board, a strap hinge pinned to a rear leg in a steel ferrule and foot, and a splay chain between eye bolts; five carbon arrows in the face with cresting, nocks and three vanes, one glancing into the straw edge, one snapped with its fletched half on the grass, and a leather quiver of arrows lying among grass tufts — through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.</p>
4949
</header>
5050
<main id="main">
51-
<nav class="pager" aria-label="Showcase pieces"><a rel="prev" href="../cargo-loader/" aria-label="Previous showcase piece: cargo-loader"><span aria-hidden="true">&larr;</span><span class="pager-label">cargo-loader</span></a><span class="pager-pos hud">53 of 77 showcase pieces<span class="pager-keys"> &middot; <kbd>&larr;</kbd><kbd>&rarr;</kbd></span></span><a rel="next" href="../cactus-garden/" aria-label="Next showcase piece: cactus-garden"><span class="pager-label">cactus-garden</span><span aria-hidden="true">&rarr;</span></a></nav>
51+
<nav class="pager" aria-label="Showcase pieces"><a rel="prev" href="../cargo-loader/" aria-label="Previous showcase piece: cargo-loader"><span aria-hidden="true">&larr;</span><span class="pager-label">cargo-loader</span></a><span class="pager-pos hud">53 of 78 showcase pieces<span class="pager-keys"> &middot; <kbd>&larr;</kbd><kbd>&rarr;</kbd></span></span><a rel="next" href="../cactus-garden/" aria-label="Next showcase piece: cactus-garden"><span class="pager-label">cactus-garden</span><span aria-hidden="true">&rarr;</span></a></nav>
5252
<button class="detail-hero" id="heroZoom" type="button" aria-label="View full size: A straw archery boss with a gold, red, blue, black and white face and five arrows, leaning on a timber easel numbered 12, a quiver on the grass patch below.">
5353
<img src="../assets/archery-target-hero.webp" alt="A straw archery boss with a gold, red, blue, black and white face and five arrows, leaning on a timber easel numbered 12, a quiver on the grass patch below." width="1280" height="720" fetchpriority="high" />
5454
</button>
@@ -146,7 +146,7 @@ <h3><a class="stretch" href="../wooden-barrel/">Wooden Barrel</a></h3>
146146
</article>
147147
</div>
148148
</section>
149-
<nav class="pager pager-foot" aria-label="Showcase pieces"><a rel="prev" href="../cargo-loader/" aria-label="Previous showcase piece: cargo-loader"><span aria-hidden="true">&larr;</span><span class="pager-label">cargo-loader</span></a><span class="pager-pos hud">53 of 77 showcase pieces</span><a rel="next" href="../cactus-garden/" aria-label="Next showcase piece: cactus-garden"><span class="pager-label">cactus-garden</span><span aria-hidden="true">&rarr;</span></a></nav>
149+
<nav class="pager pager-foot" aria-label="Showcase pieces"><a rel="prev" href="../cargo-loader/" aria-label="Previous showcase piece: cargo-loader"><span aria-hidden="true">&larr;</span><span class="pager-label">cargo-loader</span></a><span class="pager-pos hud">53 of 78 showcase pieces</span><a rel="next" href="../cactus-garden/" aria-label="Next showcase piece: cactus-garden"><span class="pager-label">cactus-garden</span><span aria-hidden="true">&rarr;</span></a></nav>
150150
</main>
151151
<dialog class="lightbox" id="lightbox" aria-label="Full-size render">
152152
<div class="lightbox-bar"><button class="lightbox-close" id="lightboxNative" type="button" aria-pressed="false">Actual size</button><button class="lightbox-close" id="lightboxClose" type="button" autofocus>Close</button></div>
62.9 KB
Loading
16.5 KB
Loading

0 commit comments

Comments
 (0)