Skip to content

Commit 6b2d0f8

Browse files
TMHSDigitalclaude
andauthored
feat: add text-version-stamp example (TextCurve solids + self-labeling renders) (#59)
The gallery covered mesh, curves-with-bevel, GPv3, and armatures but nothing exercised the TextCurve data API, which AI-generated code routinely gets wrong (parsing version_string as bare semver, expecting to_mesh results to outlive to_mesh_clear). The stamp's body is the live bpy.app.version_string, so every render self-documents which Blender produced it and CI artifacts become self-labeling. The check asserts the closed-form solids contract (evaluated z-extent = 2 x (extrude + bevel_depth), bevel widening the outline by 2 x bevel_depth), that flat text is filled but planar, that body edits regenerate geometry, that version_string starts with the dotted version tuple ("4.5.11 LTS" is not bare semver), and that a Mesh reference dies at to_mesh_clear(). Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 6ca003f commit 6b2d0f8

13 files changed

Lines changed: 909 additions & 8 deletions

File tree

‎.cursor-plugin/plugin.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"examples/shape-key-blend",
7676
"examples/swatch-grid",
7777
"examples/temp-override-join",
78+
"examples/text-version-stamp",
7879
"examples/turntable",
7980
"examples/wave-displace"
8081
]

‎.github/workflows/blender-smoke.yml‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,3 +298,16 @@ jobs:
298298
# Exits non-zero on failure.
299299
xvfb-run -a "$BLENDER" --background \
300300
--python examples/armature-bend/armature_bend.py --
301+
302+
- name: Shipped example - text version stamp (TextCurve solids + version string)
303+
run: |
304+
set -euo pipefail
305+
# Check only (no render): a TextCurve whose body is the live
306+
# bpy.app.version_string; asserts the Curve subclass and built-in
307+
# font contracts, that flat text is filled but planar, the closed
308+
# form z-extent = 2*(extrude+bevel_depth), body edits regenerating
309+
# geometry, that version_string starts with the dotted version tuple
310+
# ("4.5.11 LTS" is not bare semver), and that a Mesh reference dies
311+
# at to_mesh_clear(). Exits non-zero on failure.
312+
xvfb-run -a "$BLENDER" --background \
313+
--python examples/text-version-stamp/text_version_stamp.py --

‎AGENTS.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ The content base (counts are CI-enforced against README.md and the manifest):
2727
- 2 templates: `extension-addon-template` for Extensions Platform add-ons,
2828
and `headless-batch-script-template` for unattended batch jobs.
2929
- 17 snippets covering canonical patterns.
30-
- 18 examples under `examples/<name>/`: runnable scripts that assert a real
30+
- 19 examples under `examples/<name>/`: runnable scripts that assert a real
3131
API contract with deterministic checks, exit non-zero on failure, and
3232
optionally render a still via `--output`. Each is executed headless on
3333
Blender 4.5 LTS and 5.1 by `blender-smoke.yml`; its render ships in the
@@ -41,7 +41,7 @@ Blender-Developer-Tools/
4141
rules/<rule-name>.mdc # 6 rule files
4242
templates/<template-name>/ # 2 starter templates
4343
snippets/<snippet-name>.py # 17 standalone Python snippets
44-
examples/<name>/ # 18 runnable smoke-gated examples (+ gallery.json)
44+
examples/<name>/ # 19 runnable smoke-gated examples (+ gallery.json)
4545
scripts/build_gallery.py # generates docs/gallery/ (stdlib only)
4646
scripts/site/ # vendored landing-page build (build_site.py + template)
4747
docs/gallery/ # committed generated gallery pages + hero assets

‎CLAUDE.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ skills/<skill-name>/SKILL.md - AI workflow definitions, 12 total
1919
rules/<rule-name>.mdc - Anti-pattern rules, 6 total
2020
templates/<template-name>/ - Starter projects, 2 total
2121
snippets/<snippet-name>.py - Standalone code patterns, 17 total
22-
examples/<name>/ - Runnable smoke-gated examples, 18 total (+ gallery.json)
22+
examples/<name>/ - Runnable smoke-gated examples, 19 total (+ gallery.json)
2323
scripts/build_gallery.py - Regenerates docs/gallery/ from gallery.json (stdlib only)
2424
scripts/site/ - Vendored landing-page build (Jinja2)
2525
docs/gallery/ - Committed generated gallery pages + hero renders
@@ -80,11 +80,11 @@ v0.1.0: canonical object creation and deletion, depsgraph evaluated mesh, bmesh
8080

8181
v0.2.0: Principled BSDF material, driver-with-custom-function via `driver_namespace`, application handler registration, shader node group with cross-version `interface` API, `foreach_get` bulk vertex read, version-branch skeleton, and USD export with `evaluation_mode='RENDER'`.
8282

83-
## Examples (18)
83+
## Examples (19)
8484

8585
Runnable scripts at `examples/<name>/`, each asserting a real API contract with
8686
deterministic checks (exit non-zero on failure) and optionally rendering a still via
87-
`--output`. All eighteen run headless on Blender 4.5 LTS and 5.1 in `blender-smoke.yml`;
87+
`--output`. All nineteen run headless on Blender 4.5 LTS and 5.1 in `blender-smoke.yml`;
8888
their renders ship in the site gallery at `docs/gallery/`. `examples/gallery.json` is the
8989
gallery's source of truth. When authoring a new one, copy the anatomy of
9090
`examples/bmesh-gear/` (script structure, README shape, dark-studio render recipe) and

‎README.md‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@
1717
</p>
1818

1919
<p align="center">
20-
<strong>12 skills</strong> &nbsp;&bull;&nbsp; <strong>6 rules</strong> &nbsp;&bull;&nbsp; <strong>2 templates</strong> &nbsp;&bull;&nbsp; <strong>17 snippets</strong> &nbsp;&bull;&nbsp; <strong>18 examples</strong>
20+
<strong>12 skills</strong> &nbsp;&bull;&nbsp; <strong>6 rules</strong> &nbsp;&bull;&nbsp; <strong>2 templates</strong> &nbsp;&bull;&nbsp; <strong>17 snippets</strong> &nbsp;&bull;&nbsp; <strong>19 examples</strong>
2121
</p>
2222

2323
---
2424

2525
## Overview
2626

27-
This repository ships **12 skills, 6 rules, 2 templates, 17 snippets, and 18 runnable examples** for Blender Python development targeting Blender 5.1 (current stable) with Blender 4.5 LTS fallback support.
27+
This repository ships **12 skills, 6 rules, 2 templates, 17 snippets, and 19 runnable examples** for Blender Python development targeting Blender 5.1 (current stable) with Blender 4.5 LTS fallback support.
2828

2929
The content is consumed by AI coding agents (Cursor, Claude Code, any MCP-capable client) when working on Blender add-ons, geometry nodes scripts, batch pipelines, or animation tooling. There is no build step. Edit the markdown and Python files directly.
3030

@@ -314,6 +314,24 @@ linear blend skinning — every evaluated vertex equals
314314
Σ wᵢ · (`pose_bone.matrix` @ `bone.matrix_local.inverted()`) @ rest, with the root
315315
ring pinned and the tip deflected. A straight tube is a failure.
316316

317+
</td>
318+
</tr>
319+
<tr>
320+
<td width="46%" valign="middle">
321+
<a href="examples/text-version-stamp/"><img src="examples/text-version-stamp/preview.webp" alt="Text version stamp: beveled brass 5.1.2 numerals standing on a dark studio floor over a glowing teal underline, with a small steel BLENDER caption above — the body text is the live bpy.app.version_string" /></a>
322+
</td>
323+
<td valign="middle">
324+
325+
### [text-version-stamp](examples/text-version-stamp/)
326+
327+
A beveled 3D stamp of the running Blender version — a `TextCurve` whose `body` is the
328+
live `bpy.app.version_string`, so every render self-documents which Blender made it.
329+
Asserts the TextCurve solids closed form (evaluated z-extent = 2 × (extrude +
330+
bevel_depth), bevel widening the outline by 2 × bevel_depth), that flat text is filled
331+
but planar, that body edits regenerate geometry, that `version_string` is not bare
332+
semver on LTS builds (`"4.5.11 LTS"`), and that a Mesh reference dies at
333+
`to_mesh_clear()`.
334+
317335
</td>
318336
</tr>
319337
</table>

‎ROADMAP.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ Not committed; target list for the next content version. (v0.3.0 shipped the smo
9797
- Refresh the `slotted-actions-animation` skill against any 5.2 changes
9898
- Bump `blender_version_min` in the templates if 5.2 APIs are used
9999
- Additional snippets for asset library scripting, EXR baking, multi-file extensions
100-
- Gallery coverage follow-ups from the GPv3 review: `text-version-stamp` (TextCurve self-labeling renders); lower priority: light-linking, bulk `pixels.foreach_set`, VSE sequences-to-strips witness (`grease-pencil-rosette` and `armature-bend` shipped first)
100+
- Gallery coverage follow-ups from the GPv3 review: light-linking, bulk `pixels.foreach_set`, VSE sequences-to-strips witness (`grease-pencil-rosette`, `armature-bend`, and `text-version-stamp` shipped first)
101101

102102
## Future (uncommitted)
103103

17.5 KB
Loading

‎docs/gallery/index.html‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,17 @@ <h2><a href="armature-bend/">armature-bend</a></h2>
399399
<a class="card-link" href="armature-bend/">View example <span aria-hidden="true">&rarr;</span></a>
400400
</div>
401401
</article>
402+
<article class="card" data-tags="curves depsgraph rendering">
403+
<a class="card-media" href="text-version-stamp/" aria-label="text-version-stamp example detail page">
404+
<img src="assets/text-version-stamp-hero.webp" alt="text-version-stamp — The TextCurve data API — curves" loading="lazy" decoding="async" />
405+
</a>
406+
<div class="card-body">
407+
<h2><a href="text-version-stamp/">text-version-stamp</a></h2>
408+
<p class="teaches">The TextCurve data API — curves.new(type=&#x27;FONT&#x27;), live body text from bpy.app.version_string, extrude and bevel_depth solids, and evaluated-mesh conversion — so every render self-documents which Blender produced it.</p>
409+
<p class="witnesses"><span class="tag">witnesses</span> TextCurve solids are exactly predictable: evaluated z-extent = 2 × (extrude + bevel_depth), bevel widens the outline by 2 × bevel_depth, editing body regenerates geometry — and version_string is not bare semver on LTS (&quot;4.5.11 LTS&quot;), so parse bpy.app.version instead.</p>
410+
<a class="card-link" href="text-version-stamp/">View example <span aria-hidden="true">&rarr;</span></a>
411+
</div>
412+
</article>
402413
</div>
403414
</main>
404415
<footer>

0 commit comments

Comments
 (0)