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 @@ -82,6 +82,7 @@
"examples/light-link-studio",
"examples/lod-decimate-chain",
"examples/mesh-hygiene-audit",
"examples/modular-kit-snap",
"examples/parent-inverse-orrery",
"examples/png-exr-alpha",
"examples/prop-origin-transform",
Expand Down
13 changes: 13 additions & 0 deletions .github/workflows/blender-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -566,3 +566,16 @@ jobs:
# Exits non-zero on failure.
xvfb-run -a "$BLENDER" --background \
--python examples/degenerate-bevel-weld/degenerate_bevel_weld.py --

- name: Shipped example - modular kit snap (tile boundary contract)
run: |
set -euo pipefail
# Check only (no render): a 4x3x3 corridor segment; asserts 16
# boundary verts on x in {0, TILE} within 1e-6, end-ring coincidence
# within 1e-6, a linked duplicate's joint positions matching within
# 1e-6, shell bbox == declared tile (dev 0), manifold shell except
# the 16 open-end edges, watertight detail parts contained inside
# the tile, and reuse hygiene (identity scales, kit names, pivot
# origins). Exits non-zero on failure.
xvfb-run -a "$BLENDER" --background \
--python examples/modular-kit-snap/modular_kit_snap.py --
22 changes: 21 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>40 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>41 examples</strong>
</p>

<p align="center">
Expand Down Expand Up @@ -780,6 +780,26 @@ welds their loops. Companion to
check first caught the weld) and [`mesh-hygiene-audit`](examples/mesh-hygiene-audit/)
(topology gates). Seam markers are placed from live mesh data.

</td>
</tr>
<tr>
<td width="46%" valign="middle">
<a href="examples/modular-kit-snap/"><img src="examples/modular-kit-snap/preview.webp" alt="Modular kit snap: a corridor run of four tiling segments — dark steel walls with blue-gray panels, orange trim rails, and ceiling light strips converging on a glowing amber doorway, with every joint seamless because the boundary verts snap exactly to the tile grid" /></a>
</td>
<td valign="middle">

### [modular-kit-snap](examples/modular-kit-snap/)

A tiling corridor kit where the snap is the contract. **16 boundary verts**
on `x ∈ {0, 4}` within **1e-6 m**, opposing end loops coincident under the
tile offset, and a linked duplicate's joint positions matching within 1e-6 —
zero gap, zero overlap. Shell bbox equals the declared tile exactly, the
tube is manifold except its two open ends, and all twelve detail parts are
contained inside the tile. The unsnapped probe (3 mm skew) fails with the
measured error printed. Companion to
[`prop-origin-transform`](examples/prop-origin-transform/) (pivot discipline)
and [`mesh-hygiene-audit`](examples/mesh-hygiene-audit/) (topology gates).

</td>
</tr>
</table>
Expand Down
4 changes: 2 additions & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ 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 (`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~~ **SHIPPED** as `examples/attribute-domain-shear/` — POINT vs CORNER semantics on an 8-wedge pinwheel with one shared hub: CORNER authoring exact (hub corners disagree by face, err ≤ 1e-6), naive per-wedge POINT loop shears to the last write at hub + ring verts, measured deviation == palette closed form (0.751031); byte-identical on 4.5.11 and 5.1.2; crisp-vs-smeared dual pinwheel still — companion to `color-attribute-wheel`
Expand All @@ -108,8 +107,9 @@ Not committed; target list for the next content version. (v0.3.0 shipped the smo
- ~~Vertex weight limit witness~~ **SHIPPED** as `examples/vertex-weight-limit/` — the 4-influence engine cap enforced via the data API (`v.groups` + `VertexGroup.remove` + renormalize); unit sums (measured 3e-8), pose preserved (4.9e-3), exact LBS from the mesh's own deform layer (2.7e-7), Root mount pinned
- ~~Triangulate + tangent-space witness~~ **SHIPPED** as `examples/triangulate-tangents/` — `calc_tangents` aborts on any ngon (back cap must be an explicit fan); mikktspace matches the edge/UV-delta formula within welding tolerance on smooth fields (2.3e-6 measured); planar UVs on a cylindrical wall collapse tangents onto normals (dot 0.998); `MeshUVLoopLayer` handle dangles across `calc_tangents()` on 4.5 (471 phantom flips, silent exit 0) while the mikktspace math is byte-identical on 4.5.11 and 5.1.2
- UV-handle lifetime snippet: re-fetch attribute/UV layers by name after any CustomData-reallocating call (`calc_tangents`, `VertexGroup.add`, modifier edits) — held handles dangle silently on 4.5, survive by luck on 5.1 (found authoring `triangulate-tangents`)
- glTF skinned-mesh export witness: follow-up to `gltf-export-roundtrip` + `vertex-weight-limit` **SHIPPED** as `examples/gltf-skin-roundtrip/` — `skins[0].joints` names every bone, JOINTS_0/WEIGHTS_0 with unit sums (3e-8), weights bit-exact, rest matrices to 2.4e-07, deformation to 4.8e-07; exporter welds duplicate loops (sorted-multiset comparisons mispair — compare by rest-key); unparented skinned meshes make the exporter bind an armature by name
- ~~glTF skinned-mesh export witness: follow-up to `gltf-export-roundtrip` + `vertex-weight-limit`~~ **SHIPPED** as `examples/gltf-skin-roundtrip/` — `skins[0].joints` names every bone, JOINTS_0/WEIGHTS_0 with unit sums (3e-8), weights bit-exact, rest matrices to 2.4e-07, deformation to 4.8e-07; exporter welds duplicate loops (sorted-multiset comparisons mispair — compare by rest-key); unparented skinned meshes make the exporter bind an armature by name
- ~~Degenerate-bevel weld hazard~~ **SHIPPED** as `examples/degenerate-bevel-weld/` — at `offset == min_dim/2` the bevel band collapses to exactly 12 zero-area faces (4 min-axis edges × 3 segments) with 16 coincident verts (4 × (segments+1)) and min_area down 3.2e5×; a stdlib GLB re-parse counts **32 degenerate triangles crossing the export boundary** (MEASURED regression constant) versus 0 for the safe mesh — the loops an engine merge-by-distance welds; byte-identical on 4.5.11 and 5.1.2
- ~~Modular kit snap witness~~ **SHIPPED** as `examples/modular-kit-snap/` — tiling corridor segment: 16 boundary verts on `x ∈ {0, TILE}` within 1e-6 m, end rings coincident under the tile offset (nearest-key match), linked-duplicate joint deviation 0.0, shell bbox == declared tile (dev 0.0), manifold except the 16 open-end edges, 12 detail parts contained inside the tile; unsnapped probe (3 mm skew, 2 mm nudge) fails at exits 3/4 with measured errors; sorted-zip ring matching mispairs displaced verts — match by nearest key (authoring hazard, fixed); byte-identical on 4.5.11 and 5.1.2
- ~~GAMMA_CROSS blend-curve witness~~ **SHIPPED** as `examples/vse-gamma-cross/` — the cross blends in a gamma-0.5 space: `((1-t)·√A + t·√B)²` with `t = (frame − start)/duration`, never 1 inside the effect; mid-cross dips 0.115 below the sRGB lerp from crimson/teal (closed form (0.341, 0.349, 0.463) confirmed per frame); AgX-default sampling poisons the fit (0.146 red-channel error, `view_transform='Standard'` mandatory); deleting a consumed input orphans-and-deletes the effect — 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`)
- ~~Collision compound witness~~ **SHIPPED** as `examples/collision-hull-proxy/` — game-prop collision as a compound of convex pieces, each a `bmesh.ops.convex_hull` of a coarse `sec(π/n)`-inflated cage (containment 4.4e-08, watertight, positive signed volume, Euler 2, per-piece 255-face budget: body 70, caps 60×3, compound 250); a hull of the dense render mesh measures 380 faces — over budget — which is why pipelines hull cages; proud details cost cage rows, concave grooves are free; byte-identical on 4.5.11 and 5.1.2
Expand Down
Binary file added docs/gallery/assets/modular-kit-snap-hero.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 added docs/gallery/contact-sheets/modular-kit-snap.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 12 additions & 1 deletion docs/gallery/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ <h1>Examples Gallery</h1>
autocomplete="off" spellcheck="false" aria-label="Search examples" />
<button class="q-clear" id="qClear" type="button" aria-label="Clear search" hidden>&times;</button>
</div>
<span class="count" id="count" role="status" aria-live="polite">40 examples</span>
<span class="count" id="count" role="status" aria-live="polite">41 examples</span>
<div class="density" role="group" aria-label="Card density">
<button class="density-btn" data-density="compact" type="button" aria-pressed="false">Compact</button>
<button class="density-btn" data-density="detailed" type="button" aria-pressed="false">Detailed</button>
Expand Down Expand Up @@ -762,6 +762,17 @@ <h2><a href="degenerate-bevel-weld/">degenerate-bevel-weld</a></h2>
<a class="card-link" href="degenerate-bevel-weld/">View example <span aria-hidden="true">&rarr;</span></a>
</div>
</article>
<article class="card" data-tags="mesh bmesh game-pipeline instancing">
<a class="card-media" href="modular-kit-snap/" aria-label="modular-kit-snap example detail page">
<img src="assets/modular-kit-snap-hero.webp" alt="modular-kit-snap — A tiling corridor kit whose open-end boundary verts snap to the tile grid, so instances at 4 m multiples join with zero gap or overlap." loading="lazy" decoding="async" />
</a>
<div class="card-body">
<h2><a href="modular-kit-snap/">modular-kit-snap</a></h2>
<p class="teaches">A tiling corridor kit whose open-end boundary verts snap to the tile grid, so instances at 4 m multiples join with zero gap or overlap.</p>
<p class="witnesses"><span class="tag">witnesses</span> 16 boundary verts on x∈{0,4} within 1e-6 m, linked-duplicate joint deviation 0.0, bbox == declared tile; unsnapped probe fails at 3e-3 m.</p>
<a class="card-link" href="modular-kit-snap/">View example <span aria-hidden="true">&rarr;</span></a>
</div>
</article>
</div>
<p class="noresults" id="noResults" hidden>No examples match the current filters.
<button class="chip" id="resetFilters" type="button">Clear search and tags</button></p>
Expand Down
Loading
Loading