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 @@ -80,6 +80,7 @@
"examples/text-version-stamp",
"examples/turntable",
"examples/uv-layer-grid",
"examples/vse-cut-list",
"examples/wave-displace"
]
}
19 changes: 19 additions & 0 deletions .github/workflows/blender-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -350,3 +350,22 @@ jobs:
# non-zero on failure.
xvfb-run -a "$BLENDER" --background \
--python examples/png-exr-alpha/png_exr_alpha.py --

- name: Shipped example - vse cut list (sequencer 4.5 vs 5.x rename)
run: |
set -euo pipefail
# Check only (no render): asserts the accessor rename (.sequences
# gone on 5.x, bridged on 4.5), the new_effect end-kwarg rename
# (frame_end on 4.5, length on 5.x — the wrong kwarg TypeErrors),
# closed-form spans on each version's canonical accessors
# (frame_final_* vs left_handle/right_handle/duration with the
# deprecation bridge), GC wiring and clamping, scene-strip span,
# and a save/reload round-trip. Exits non-zero on failure.
xvfb-run -a "$BLENDER" --background \
--python examples/vse-cut-list/vse_cut_list.py --
# Compositing witness on a tiny Cycles render: mosaic cells carry
# their strip colors, the cross cell is a true mid blend, and a
# consumed cross source never composites independently.
xvfb-run -a "$BLENDER" --background \
--python examples/vse-cut-list/vse_cut_list.py -- \
--check-pixels --engine cycles
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ a `.cursor-plugin/plugin.json` manifest so the ecosystem drift checker
classifies it as a `cursor-plugin`. This is content the AI loads when the user
asks Blender questions or works on Blender add-ons in Cursor or Claude Code.

The content base is 12 skills, 6 rules, 2 templates, 17 snippets, and 22
The content base is 12 skills, 6 rules, 2 templates, 17 snippets, and 23
examples (counts are CI-enforced against README.md and the manifest). The full
inventory tables and per-item purposes live in `CLAUDE.md`. Example anatomy
and authoring rules: copy `examples/bmesh-gear/`; the render look is specified
Expand All @@ -35,7 +35,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>/ # 22 runnable smoke-gated examples (+ gallery.json)
examples/<name>/ # 23 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 @@ -21,7 +21,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, 22 total (+ gallery.json)
examples/<name>/ - Runnable smoke-gated examples, 23 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 @@ -82,11 +82,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 (22)
## Examples (23)

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-two run headless on Blender 4.5 LTS and 5.1 in `blender-smoke.yml`;
`--output`. All twenty-three 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
17 changes: 16 additions & 1 deletion 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>22 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>23 examples</strong>
</p>

<p align="center">
Expand Down Expand Up @@ -285,6 +285,21 @@ A depsgraph-evaluated export — builds a cube with `SUBSURF`, measures the eval
`evaluated_get().to_mesh()` / `to_mesh_clear()`, and asserts `wm.obj_export` ships the
modifier-applied geometry (exported vertex count == evaluated > base).

</td>
</tr>
<tr>
<td width="46%" valign="middle">
<a href="examples/vse-cut-list/"><img src="examples/vse-cut-list/preview.webp" alt="VSE cut list: a two-by-two program wall in a dark studio — crimson, teal, and amber color strips plus the mid cross-blend cell, composited by the sequencer over a scene strip, with the span caption below" /></a>
</td>
<td valign="middle">

### [vse-cut-list](examples/vse-cut-list/)

The sequencer API rename from 4.5 LTS to 5.x — `strips` (never `.sequences`), `new_effect`
ending in `length=` vs `frame_end=`, and `left_handle`/`right_handle`/`duration` replacing
the deprecated `frame_final_*`. Asserts closed-form spans, GC wiring and clamping, the
consumed-input compositing contract, and a save/reload round-trip.

</td>
</tr>
</table>
Expand Down
6 changes: 4 additions & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,14 @@ Not committed; target list for the next content version. (v0.3.0 shipped the smo
- Refresh the `slotted-actions-animation` skill against any 5.2 changes
- Bump `blender_version_min` in the templates if 5.2 APIs are used
- 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)
- Gallery coverage follow-ups from the GPv3 review: light-linking (`grease-pencil-rosette`, `armature-bend`, `text-version-stamp`, `image-pixels-testcard`, and `vse-cut-list` 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~~ **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
- ~~VSE sequences-to-strips witness~~ **SHIPPED** as `examples/vse-cut-list/` — `.sequences` removed on 5.x (4.5 bridges to `.strips`), `new_effect` end kwarg `frame_end=` (4.5) vs `length=` (5.x), `frame_final_*` deprecated in favor of `left_handle`/`right_handle`/`duration`, TRANSFORM effect type removed, GAMMA_CROSS clamps to the source overlap, effect strips consume inputs only when stacked above them, same-scene scene strips render transparent; save/reload round-trip + tiny-render pixel witness
- GAMMA_CROSS blend-curve witness: the cross blend is not the naive linear mix (mid-cross measured (0.341, 0.349, 0.463) from crimson (0.85, 0.10, 0.22) and teal (0.06, 0.75, 0.80)) — derive and assert the gamma-space closed form per frame; follow-up to `vse-cut-list`
- Falsy `bpy_prop_collection` trap snippet: an empty collection is falsy, so `editor.strips or editor.sequences` silently falls through to the legacy accessor on an empty timeline — always branch on `hasattr`; likely generalizes across the API (found authoring `vse-cut-list`)

## Future (uncommitted)

Expand Down
Binary file added docs/gallery/assets/vse-cut-list-hero.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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 @@ -198,6 +198,7 @@ <h1>Examples Gallery</h1>
<button class="chip" data-tag="operators" type="button">operators</button>
<button class="chip" data-tag="performance" type="button">performance</button>
<button class="chip" data-tag="rendering" type="button">rendering</button>
<button class="chip" data-tag="sequencer" type="button">sequencer</button>
<button class="chip" data-tag="shape-keys" type="button">shape-keys</button>
<button class="chip" data-tag="transforms" type="button">transforms</button>
<button class="chip" data-tag="uv" type="button">uv</button>
Expand Down Expand Up @@ -446,6 +447,17 @@ <h2><a href="uv-layer-grid/">uv-layer-grid</a></h2>
<a class="card-link" href="uv-layer-grid/">View example <span aria-hidden="true">&rarr;</span></a>
</div>
</article>
<article class="card" data-tags="sequencer rendering">
<a class="card-media" href="vse-cut-list/" aria-label="vse-cut-list example detail page">
<img src="assets/vse-cut-list-hero.webp" alt="vse-cut-list — The sequencer API rename from 4.5 LTS to 5.x — strips (never .sequences), new_effect ending in length= vs frame_end=, and left_handle/right_handle/duration…" loading="lazy" decoding="async" />
</a>
<div class="card-body">
<h2><a href="vse-cut-list/">vse-cut-list</a></h2>
<p class="teaches">The sequencer API rename from 4.5 LTS to 5.x — strips (never .sequences), new_effect ending in length= vs frame_end=, and left_handle/right_handle/duration replacing the deprecated frame_final_*. A deterministic cut list — color programs, a clamped GAMMA_CROSS, a scene strip, a text strip — asserted before and after save/reload.</p>
<p class="witnesses"><span class="tag">witnesses</span> Each side hard-fails the other&#x27;s spelling: TypeError on the wrong end kwarg, AttributeError on .sequences. The cross clamps to the source overlap, effect strips consume their inputs only when stacked above them, and a same-scene scene strip renders transparent.</p>
<a class="card-link" href="vse-cut-list/">View example <span aria-hidden="true">&rarr;</span></a>
</div>
</article>
</div>
</main>
<footer>
Expand Down
Loading
Loading