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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -393,14 +393,14 @@ the Z span matches the amplitude, and a probe vertex matches the closed-form wav
</tr>
<tr>
<td width="46%" valign="middle">
<a href="examples/shape-key-blend/"><img src="examples/shape-key-blend/preview.webp" alt="Shape-key blend: three violet blocks on a dark studio floor showing a relative Tall shape key at values 0, 0.25, and 0.5 - plain cube to lifted, flared truncated pyramid, left to right" /></a>
<a href="examples/shape-key-blend/"><img src="examples/shape-key-blend/preview.webp" alt="Shape-key blend: three cobalt-glazed ceramic vases with an ochre band on a dark studio floor - the same vase at Tall shape-key values 0, 0.5 and 1, squat jar to amphora to flared trumpet vase, left to right, with thin pale rings of the jar's belly around the tallest" /></a>
</td>
<td valign="middle">

### [shape-key-blend](examples/shape-key-blend/)

A relative Tall shape key that lifts and flares the top face — authored through
`shape_key_add` / `key_blocks` / `.value`. Witnesses that shape keys do not rewrite
A relative Tall shape key that turns a squat ceramic jar into a trumpet vase,
lifting and flaring the rim — authored through `shape_key_add` / `key_blocks` / `.value`. Witnesses that shape keys do not rewrite
`mesh.vertices`: every evaluated vert matches `basis + value × (key − basis)`.

</td>
Expand Down
2 changes: 1 addition & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ not measurable by the floors (curve/GP data, no mesh hero). Re-survey after
any example remodel.

- naming (default datablock names): gltf-skin-roundtrip (3 parts), gn-sdf-remesh (`Torus`), turntable (`Suzanne`)
- materials (multi-part, single material): armature-bend (3 parts/1 mat — vertex-color weight bands are the honest display), degenerate-bevel-weld (2/1), driver-wave (16/1, also edge90 1.0), shape-key-blend (3/1, also edge90 1.0)
- materials (multi-part, single material): armature-bend (3 parts/1 mat — vertex-color weight bands are the honest display), degenerate-bevel-weld (2/1), driver-wave (16/1, also edge90 1.0)
- edge90 (raw right angles, 1.0): depsgraph-export (also naming + materials), image-pixels-testcard, png-exr-alpha, temp-override-join, text-version-stamp, vse-cut-list; vse-gamma-cross at 0.92
- reference: gallery best-modeled measure collision-hull-proxy 0.044, custom-normals-shade 0.288, vertex-weight-limit 0.150, lod-decimate-chain 0.019; calibration details in `docs/VISUAL-STYLE.md` § Asset quality

Expand Down
Binary file added docs/gallery/asset-sheets/shape-key-blend.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/gallery/assets/shape-key-blend-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.
6 changes: 3 additions & 3 deletions docs/gallery/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -464,12 +464,12 @@ <h2><a href="gn-modifier-inputs/">gn-modifier-inputs</a></h2>
</article>
<article class="card" data-tags="mesh shape-keys">
<a class="card-media" href="shape-key-blend/" tabindex="-1" aria-hidden="true">
<img src="assets/shape-key-blend-hero.webp" alt="Three purple boxes flaring wider at the top by increasing amounts; the rightmost sits inside a pale wire cage of its full shape key, halfway to it." loading="lazy" decoding="async" />
<img src="assets/shape-key-blend-hero.webp" alt="One cobalt vase with an ochre band at shape-key values 0, 0.5 and 1: squat jar, amphora, tall trumpet vase, with pale rings of the jar&#x27;s belly around the tallest." loading="lazy" decoding="async" />
</a>
<div class="card-body">
<h2><a href="shape-key-blend/">shape-key-blend</a></h2>
<p class="teaches">A relative Tall shape key that lifts and flares the top face — authored via shape_key_add / key_blocks / .value — read back from the depsgraph-evaluated mesh.</p>
<p class="witnesses"><span class="tag">witnesses</span> Shape keys do not rewrite mesh.vertices: every evaluated vert matches basis + value × (key − basis), including the flared top half-extent.</p>
<p class="teaches">A relative Tall shape key that turns a squat ceramic jar into a trumpet vase — lifting and flaring the rim — authored via shape_key_add / key_blocks / .value and read back from the depsgraph-evaluated mesh.</p>
<p class="witnesses"><span class="tag">witnesses</span> Shape keys do not rewrite mesh.vertices: every evaluated vert matches basis + value × (key − basis), including the lifted, flared rim ring.</p>
<a class="card-link" href="shape-key-blend/">View example<span class="sr-only"> shape-key-blend</span> <span aria-hidden="true">&rarr;</span></a>
</div>
</article>
Expand Down
470 changes: 320 additions & 150 deletions docs/gallery/shape-key-blend/index.html

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions examples/gallery.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@
{
"name": "shape-key-blend",
"dir": "examples/shape-key-blend",
"teaches": "A relative Tall shape key that lifts and flares the top face — authored via shape_key_add / key_blocks / .value — read back from the depsgraph-evaluated mesh.",
"alt": "Three purple boxes flaring wider at the top by increasing amounts; the rightmost sits inside a pale wire cage of its full shape key, halfway to it.",
"witnessesFix": "Shape keys do not rewrite mesh.vertices: every evaluated vert matches basis + value × (key − basis), including the flared top half-extent.",
"teaches": "A relative Tall shape key that turns a squat ceramic jar into a trumpet vase — lifting and flaring the rim — authored via shape_key_add / key_blocks / .value and read back from the depsgraph-evaluated mesh.",
"alt": "One cobalt vase with an ochre band at shape-key values 0, 0.5 and 1: squat jar, amphora, tall trumpet vase, with pale rings of the jar's belly around the tallest.",
"witnessesFix": "Shape keys do not rewrite mesh.vertices: every evaluated vert matches basis + value × (key − basis), including the lifted, flared rim ring.",
"hero": "docs/gallery/assets/shape-key-blend-hero.webp",
"preview": "examples/shape-key-blend/preview.webp",
"tags": [
Expand Down
33 changes: 24 additions & 9 deletions examples/shape-key-blend/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
# Shape-Key Blend

A runnable example that authors a relative shape key entirely through the data
API — `shape_key_add`, per-vertex `key_blocks["Tall"].data[i].co`, and
`.value` — then reads the blend back from the depsgraph-evaluated mesh. The Tall
key both lifts and flares the top face, so the silhouette is a truncated pyramid.
API — `shape_key_add`, `key_blocks["Tall"].data` (bulk `foreach_get` /
`foreach_set` on the key's `co`), and `.value` — then reads the blend back from
the depsgraph-evaluated mesh. The subject is a lathe-turned ceramic vase: its
Basis is a squat jar, and the Tall key lifts the rim (stretching the neck),
flares the lip into a trumpet, and slims the belly.

**What it witnesses:** shape keys do not rewrite `mesh.vertices`. The undeformed
mesh stays at Basis; every evaluated vertex matches the closed-form blend
`co = basis + value × (key − basis)`. The check also asserts the flared top half-extent
(`0.5 + value × flare`) so a uniform-scale mistake cannot pass.
mesh stays at Basis (every vertex, plus the rim ring at `z = 1.0`, `r = 0.335`);
every evaluated vertex matches the closed-form blend
`co = basis + value × (key − basis)`. The check also pins the rim ring — lifted
to `1.0 + value × 1.5` and flared to `0.335 + value × 0.38` — with the foot
still on the floor, so a uniform scale or a lift without the flare cannot pass.

## The render

The same vase at `Tall.value` 0, 0.5 (the checked object) and 1, left to right:
squat jar, amphora, trumpet vase. The ochre band is part of the lathe profile,
so it rides the key — thin on the jar's shoulder, stretched tall and higher on
the full key. Around the full-key vase, three thin pale rings are read straight
from the `Basis` key block: the jar's belly it was blended from. If the blend
broke, the three vases would render as three identical jars.

## Run

Expand All @@ -27,7 +40,7 @@ blender --background --python shape_key_blend.py -- --output blend.png --engine
## Exit codes

Per-script sequential checks. `9` is a valid check code; there is no rule
against it.
against it. `10` and `11` are the shared render-path gates' own codes.

| Code | Meaning |
| --- | --- |
Expand All @@ -40,8 +53,10 @@ against it.
| 6 | Undeformed `mesh.vertices` not at Basis |
| 7 | Evaluated vert off closed-form blend |
| 8 | Evaluated Z span off closed form |
| 9 | Top flare off closed form |
| 10 | `--output` produced no file |
| 9 | Rim radius (flare) off closed form |
| 10 | Framing gate (`gallery_framing`, `--output` only) |
| 11 | Asset-quality gate (`gallery_asset_quality`, `--output` only) |
| 12 | `--output` produced no file |

The `blender-smoke` workflow runs the check on Blender 5.2 LTS and 4.5 LTS
(5.1 on the weekly cron, the `needs-5.1` PR label, or manual dispatch).
Expand Down
Binary file modified examples/shape-key-blend/preview.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading