Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"examples/grease-pencil-rosette",
"examples/image-pixels-testcard",
"examples/parent-inverse-orrery",
"examples/png-exr-alpha",
"examples/shader-node-group",
"examples/shape-key-blend",
"examples/swatch-grid",
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/blender-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -338,3 +338,15 @@ jobs:
# non-zero on failure.
xvfb-run -a "$BLENDER" --background \
--python examples/uv-layer-grid/uv_layer_grid.py --

- name: Shipped example - png vs exr alpha (float PNG false unpremul)
run: |
set -euo pipefail
# Check only (no render): float_buffer=True Image.save() to PNG writes
# RGBA16 and unpremultiplies as if associated-alpha, so straight-authored
# dark values at low alpha clamp to white (closed-form err 0.98 at
# RGB 0.02 / a=1/255); OpenEXR round-trips within 1e-5; byte→PNG is
# straight RGBA8; EXR color_mode=RGB drops alpha to opaque. Exits
# non-zero on failure.
xvfb-run -a "$BLENDER" --background \
--python examples/png-exr-alpha/png_exr_alpha.py --
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ The content base (counts are CI-enforced against README.md and the manifest):
- 2 templates: `extension-addon-template` for Extensions Platform add-ons,
and `headless-batch-script-template` for unattended batch jobs.
- 17 snippets covering canonical patterns.
- 21 examples under `examples/<name>/`: runnable scripts that assert a real
- 22 examples under `examples/<name>/`: runnable scripts that assert a real
API contract with deterministic checks, exit non-zero on failure, and
optionally render a still via `--output`. Each is executed headless on
Blender 4.5 LTS and 5.1 by `blender-smoke.yml`; its render ships in the
Expand All @@ -42,7 +42,7 @@ Blender-Developer-Tools/
rules/<rule-name>.mdc # 6 rule files
templates/<template-name>/ # 2 starter templates
snippets/<snippet-name>.py # 17 standalone Python snippets
examples/<name>/ # 21 runnable smoke-gated examples (+ gallery.json)
examples/<name>/ # 22 runnable smoke-gated examples (+ gallery.json)
scripts/build_gallery.py # generates docs/gallery/ (stdlib only)
scripts/site/ # vendored landing-page build (build_site.py + template)
docs/gallery/ # committed generated gallery pages + hero assets
Expand Down
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ skills/<skill-name>/SKILL.md - AI workflow definitions, 12 total
rules/<rule-name>.mdc - Anti-pattern rules, 6 total
templates/<template-name>/ - Starter projects, 2 total
snippets/<snippet-name>.py - Standalone code patterns, 17 total
examples/<name>/ - Runnable smoke-gated examples, 21 total (+ gallery.json)
examples/<name>/ - Runnable smoke-gated examples, 22 total (+ gallery.json)
scripts/build_gallery.py - Regenerates docs/gallery/ from gallery.json (stdlib only)
scripts/site/ - Vendored landing-page build (Jinja2)
docs/gallery/ - Committed generated gallery pages + hero renders
Expand Down Expand Up @@ -80,11 +80,11 @@ v0.1.0: canonical object creation and deletion, depsgraph evaluated mesh, bmesh

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'`.

## Examples (21)
## Examples (22)

Runnable scripts at `examples/<name>/`, each asserting a real API contract with
deterministic checks (exit non-zero on failure) and optionally rendering a still via
`--output`. All twenty-one run headless on Blender 4.5 LTS and 5.1 in `blender-smoke.yml`;
`--output`. All twenty-two run headless on Blender 4.5 LTS and 5.1 in `blender-smoke.yml`;
their renders ship in the site gallery at `docs/gallery/`. `examples/gallery.json` is the
gallery's source of truth. When authoring a new one, copy the anatomy of
`examples/bmesh-gear/` (script structure, README shape, dark-studio render recipe) and
Expand Down
24 changes: 17 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</p>

<p align="center">
<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>21 examples</strong>
<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>22 examples</strong>
</p>

<p align="center">
Expand All @@ -36,7 +36,7 @@

## Overview

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

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.

Expand Down Expand Up @@ -85,7 +85,7 @@ or expand a category below.
</p>

<details>
<summary><strong>Materials, shading &amp; compositing</strong> — 5 examples</summary>
<summary><strong>Materials, shading &amp; compositing</strong> — 6 examples</summary>

<table>
<tr>
Expand Down Expand Up @@ -166,12 +166,22 @@ non-destructive path.

</td>
</tr>
</table>
<tr>
<td width="46%" valign="middle">
<a href="examples/png-exr-alpha/"><img src="examples/png-exr-alpha/preview.webp" alt="PNG vs EXR alpha: two easel panels on a dark studio floor — left float→PNG false-unpremul clamps dark mid-tones to white at low alpha, right the EXR-clean authored straight buffer with surviving red and green primaries" /></a>
</td>
<td valign="middle">

</details>
### [png-exr-alpha](examples/png-exr-alpha/)

<details>
<summary><strong>Mesh, curves &amp; text</strong> — 7 examples</summary>
`float_buffer=True` images saved to PNG are written as RGBA16 and unpremultiplied
as if associated-alpha — straight-authored dark values at low alpha clamp to white
(closed-form error **0.98** at `(0.02, a=1/255)`). OpenEXR preserves float RGBA;
byte images stay straight 8-bit. Also witnesses `EXR color_mode='RGB'` dropping alpha.

</td>
</tr>
</table>

<table>
<tr>
Expand Down
4 changes: 3 additions & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,10 @@ Not committed; target list for the next content version. (v0.3.0 shipped the smo
- Additional snippets for asset library scripting, EXR baking, multi-file extensions
- Gallery coverage follow-ups from the GPv3 review: light-linking, VSE sequences-to-strips witness (`grease-pencil-rosette`, `armature-bend`, `text-version-stamp`, and `image-pixels-testcard` shipped first)
- ~~UV-layer authoring witness~~ **SHIPPED** as `examples/uv-layer-grid/` — `create_grid(..., calc_uvs=True)` silent no-op without a pre-existing UV layer; closed-form UV fill + explicit assignment fallback; dual-panel render (flat texel (0,0) vs neon checker)
- Image save-format witness: float images saved to PNG with varying alpha suffer premultiply quantization (~0.98 worst-case round-trip error at 8-bit alpha extremes); EXR vs PNG storage contract
- ~~Image save-format witness~~ **SHIPPED** as `examples/png-exr-alpha/` — float→PNG is RGBA16 and false-unpremultiplies as if associated-alpha (closed-form err 0.98 at RGB 0.02 / a=1/255); OpenEXR preserves float RGBA; byte→PNG is straight RGBA8; `EXR color_mode='RGB'` drops alpha
- Attribute domain witness: writing a POINT-domain color attribute and reading it as if it were CORNER (or vice versa) silently shears colors across shared verts — companion to `color-attribute-wheel`
- Light-linking collection witness: object light linking / receiver collections so a key illuminates only the hero (common AI miss when staging multi-light studios)
- VSE sequences-to-strips witness: building a short cut list from `sequences.new_effect` / movie strips and asserting frame ranges survive reload

## Future (uncommitted)

Expand Down
Binary file added docs/gallery/assets/png-exr-alpha-hero.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions docs/gallery/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ <h1>Examples Gallery</h1>
</header>
<div class="chips" role="toolbar" aria-label="Filter examples by topic">
<button class="chip active" data-tag="" type="button">All</button>
<button class="chip" data-tag="alpha" type="button">alpha</button>
<button class="chip" data-tag="animation" type="button">animation</button>
<button class="chip" data-tag="armature" type="button">armature</button>
<button class="chip" data-tag="attributes" type="button">attributes</button>
Expand Down Expand Up @@ -423,6 +424,17 @@ <h2><a href="image-pixels-testcard/">image-pixels-testcard</a></h2>
<a class="card-link" href="image-pixels-testcard/">View example <span aria-hidden="true">&rarr;</span></a>
</div>
</article>
<article class="card" data-tags="images rendering alpha">
<a class="card-media" href="png-exr-alpha/" aria-label="png-exr-alpha example detail page">
<img src="assets/png-exr-alpha-hero.webp" alt="png-exr-alpha — Float-image PNG save trap — float_buffer=True Image.save() writes RGBA16 and unpremultiplies as if associated-alpha, clamping straight-authored dark values at…" loading="lazy" decoding="async" />
</a>
<div class="card-body">
<h2><a href="png-exr-alpha/">png-exr-alpha</a></h2>
<p class="teaches">Float-image PNG save trap — float_buffer=True Image.save() writes RGBA16 and unpremultiplies as if associated-alpha, clamping straight-authored dark values at low alpha to white (closed-form err 0.98 at RGB 0.02 / a=1/255).</p>
<p class="witnesses"><span class="tag">witnesses</span> float→PNG IHDR is RGBA16 and matches q16(min(1, c/q16(a))); OpenEXR round-trips within 1e-5; byte→PNG is straight RGBA8; EXR color_mode=RGB drops alpha to opaque.</p>
<a class="card-link" href="png-exr-alpha/">View example <span aria-hidden="true">&rarr;</span></a>
</div>
</article>
<article class="card" data-tags="mesh bmesh uv materials">
<a class="card-media" href="uv-layer-grid/" aria-label="uv-layer-grid example detail page">
<img src="assets/uv-layer-grid-hero.webp" alt="uv-layer-grid — The UV-layer authoring hazard — bmesh.ops.create_grid(..., calc_uvs=True) is a silent no-op unless a UV layer already exists; without one an Image Texture…" loading="lazy" decoding="async" />
Expand Down
Loading
Loading