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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,13 @@ Budget-conformance props. Not examples. Conventions: [`showcase/README.md`](show

[`hand-pump`](showcase/hand-pump/) — procedural cast-iron village hand pump through the same pipeline. Falsifier `--skip-decimate` exits 9.

[`signpost`](showcase/signpost/) — procedural timber fingerboard signpost through the same pipeline. Falsifier `--skip-decimate` exits 9.
[`signpost`](showcase/signpost/) — procedural timber fingerboard signpost through the same pipeline. Falsifiers `--skip-decimate` (9), `--stray-vert` (15), `--yaw-boards` (19).

[`chopping-block`](showcase/chopping-block/) — procedural hooped timber stump with an embedded axe through the same pipeline. Falsifier `--skip-decimate` exits 9.

[`wooden-bucket`](showcase/wooden-bucket/) — procedural coopered pail with a round bail through the ear rings through the same pipeline. Falsifier `--float-handle` exits 17.

[`wall-torch`](showcase/wall-torch/) — procedural wall-mounted torch sconce with a stone plaque, iron bracket, and flame through the same pipeline. Falsifier `--skip-decimate` exits 9.
[`wall-torch`](showcase/wall-torch/) — procedural wall-mounted torch sconce with a stone plaque, iron bracket, and flame through the same pipeline. Falsifiers `--skip-decimate` (9), `--stray-vert` (15), `--float-arm` (17).

[`tavern-stool`](showcase/tavern-stool/) — procedural tavern stool with turned legs, stretchers, and iron ferrules through the same pipeline. Falsifier `--skip-decimate` exits 9.

Expand Down
Binary file modified docs/gallery/assets/signpost-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/assets/signpost-preview.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/wall-torch-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/assets/wall-torch-preview.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions docs/gallery/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1090,7 +1090,7 @@ <h2><a href="hand-pump/">hand-pump</a></h2>
<div class="card-body">
<h2><a href="signpost/">signpost</a></h2>
<p class="teaches">A procedural timber fingerboard signpost through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.</p>
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 504 tris, three materials with 66 metal and 24 board faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.368×0.201×1.566 m, LOD ratios in band (5.2 COLLAPSE more aggressive on LOD2), convex collider 56 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.</p>
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 376 tris, three materials with 108 metal, 22 board and 60 wood faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.260×0.142×1.551 m at zmin 0, LOD ratios in band (5.2 COLLAPSE leaner on LOD1/LOD2), convex collider 52 tris, non-empty glTF. Hygiene all zero. Board-to-post gap 5 mm, strap gap 3 mm, board AABB Y 28 mm. --skip-decimate exits 9; --stray-vert 15; --lift-z / --short-shoe 16; --gap-board 17; --float-strap 18; --yaw-boards 19.</p>
<a class="card-link" href="signpost/">View example <span aria-hidden="true">&rarr;</span></a>
</div>
</article>
Expand Down Expand Up @@ -1123,7 +1123,7 @@ <h2><a href="wooden-bucket/">wooden-bucket</a></h2>
<div class="card-body">
<h2><a href="wall-torch/">wall-torch</a></h2>
<p class="teaches">A procedural wall-mounted torch sconce with a dressed stone plaque, iron bracket, wooden haft, and emissive flame through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.</p>
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 848 tris, four materials with 162 stone, 134 metal, and 44 flame faces, UVs in 0..1 with zero AABB overlap, outer AABB 0.384×0.360×0.670 m, LOD ratios in band (5.2 COLLAPSE 8 tris leaner on LOD2), convex collider 92 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.</p>
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 1528 tris, four materials with 540 stone, 228 metal and 78 flame faces, UVs in 0..1 with zero AABB overlap, outer AABB 0.304×0.293×0.424 m at zmin 0, LOD ratios in band, convex collider 60 tris, non-empty glTF. Hygiene all zero. Arm-to-cup gap 0.87 mm, plate-to-plaque gap 4 mm, plaque width 0.280 m. --skip-decimate exits 9; --stray-vert 15; --lift-z 16; --float-arm 17; --float-plate 18; --skinny-plaque 19.</p>
<a class="card-link" href="wall-torch/">View example <span aria-hidden="true">&rarr;</span></a>
</div>
</article>
Expand Down
693 changes: 478 additions & 215 deletions docs/gallery/signpost/index.html

Large diffs are not rendered by default.

730 changes: 502 additions & 228 deletions docs/gallery/wall-torch/index.html

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions showcase/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ entry in `showcase/gallery.json`, and a rendered still.
scatter is stones, not open crates; a per-shell face floor is the
budget that catches a cube leftover (exit 19). `--poke-rock` skips
the clamp and over-bites; `--float-rocks` seats above the host.
- **Orthogonal members (exit 19).** Boards, planks or arms that should
sit on a world axis assert their AABB secondary extent stays within a
named bound of the member thickness. A closed-form yaw of 0.12 rad
reads as an accident, not weathering. `--yaw-boards` is the
falsifier. Fingerboard tips are a wedge whose base is the board's own
thickness×height, bitten into the board so the base face is inside
it — not a 45° cube of a different size glued on the end.
- **Wall-mount zmin (exit 16).** A wall sconce plants the plaque bottom
at Z=0. Lifting every vert by a hanging height so the asset floats in
its own space is not the same as placing it on a wall in the engine.
- **Plumb and real-world size (exit 19).** Assert that the axis of a
turned or lofted body is vertical, by comparing the XY centroid of a
bottom slab against a top slab — not the exact `zmin` and `zmax`
Expand Down
4 changes: 2 additions & 2 deletions showcase/gallery.json
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@
"name": "signpost",
"dir": "showcase/signpost",
"teaches": "A procedural timber fingerboard signpost through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.",
"witnessesFix": "Recomputed: 504 tris, three materials with 66 metal and 24 board faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.368×0.201×1.566 m, LOD ratios in band (5.2 COLLAPSE more aggressive on LOD2), convex collider 56 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.",
"witnessesFix": "Recomputed: 376 tris, three materials with 108 metal, 22 board and 60 wood faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.260×0.142×1.551 m at zmin 0, LOD ratios in band (5.2 COLLAPSE leaner on LOD1/LOD2), convex collider 52 tris, non-empty glTF. Hygiene all zero. Board-to-post gap 5 mm, strap gap 3 mm, board AABB Y 28 mm. --skip-decimate exits 9; --stray-vert 15; --lift-z / --short-shoe 16; --gap-board 17; --float-strap 18; --yaw-boards 19.",
"hero": "docs/gallery/assets/signpost-hero.webp",
"preview": "showcase/signpost/preview.webp",
"tags": [
Expand Down Expand Up @@ -261,7 +261,7 @@
"name": "wall-torch",
"dir": "showcase/wall-torch",
"teaches": "A procedural wall-mounted torch sconce with a dressed stone plaque, iron bracket, wooden haft, and emissive flame through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.",
"witnessesFix": "Recomputed: 848 tris, four materials with 162 stone, 134 metal, and 44 flame faces, UVs in 0..1 with zero AABB overlap, outer AABB 0.384×0.360×0.670 m, LOD ratios in band (5.2 COLLAPSE 8 tris leaner on LOD2), convex collider 92 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.",
"witnessesFix": "Recomputed: 1528 tris, four materials with 540 stone, 228 metal and 78 flame faces, UVs in 0..1 with zero AABB overlap, outer AABB 0.304×0.293×0.424 m at zmin 0, LOD ratios in band, convex collider 60 tris, non-empty glTF. Hygiene all zero. Arm-to-cup gap 0.87 mm, plate-to-plaque gap 4 mm, plaque width 0.280 m. --skip-decimate exits 9; --stray-vert 15; --lift-z 16; --float-arm 17; --float-plate 18; --skinny-plaque 19.",
"hero": "docs/gallery/assets/wall-torch-hero.webp",
"preview": "showcase/wall-torch/preview.webp",
"tags": [
Expand Down
102 changes: 86 additions & 16 deletions showcase/signpost/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
# Signpost

A showcase piece, not an example. Procedural timber fingerboard
signpost (square post, collar and pyramidal cap, two painted planks
with diamond tips, iron shoe and straps) then the shipped pipeline:
unique-cell UVs, Cycles high-to-low normal bake, LOD chain, convex
collider, Unity glTF export.
signpost (square post, pyramidal cap from the post half plus overhang,
two axis-aligned painted boards with wedges cut from the board
section, iron shoe collar and U-wrap straps) then the shipped
pipeline: unique-cell UVs, Cycles high-to-low normal bake, LOD chain,
convex collider, Unity glTF export.

Boards are yaw 0. Finger tips are wedges whose base is the board's own
thickness×height, bitten into the board so the base face is inside it.
The cap is added after the post bevel. The post stays on the origin.
Hygiene family 15–19: `--stray-vert`, `--lift-z` / `--short-shoe`,
`--gap-board`, `--float-strap`, `--yaw-boards`.

It asserts **budget conformance** of the generated result. It does not
witness an API contract. "It rendered without error" is not a check.
Expand All @@ -14,6 +21,11 @@ witness an API contract. "It rendered without error" is not a check.
`bake_normal_high_to_low.py`, `setup_bake_target_image.py`,
`lod_chain.py` / `decimate_to_budget.py`, `convex_hull_collider.py`,
`export_preset_unity.py` (helpers copied, not imported as a package).
Hygiene combinatorics match `examples/mesh-hygiene-audit` (copied, not
imported).

Intended size: 1.48 m post, boards 0.62 m and 0.54 m, 0.118 m post
stock; outer AABB 1.260 × 0.142 × 1.551 m.

## Budgets

Expand All @@ -22,39 +34,92 @@ materials, UVs, evaluated LOD, collider, or export file.

| Axis | Declared | Measured (4.5.11 / 5.1.2 / 5.2.1) |
| --- | --- | --- |
| Base triangles | 430–580 | 504 / 504 / 504 |
| LOD1 ratio | 0.32–0.62 of base | 0.5000 / 0.5000 / 0.5000 |
| LOD2 ratio | 0.10–0.35 of base | 0.2183 / 0.2183 / 0.1746 |
| Materials | exactly 3 distinct, ≥24 metal and ≥12 board faces | 3 slots, 66 metal, 24 board |
| Base triangles | 320–480 | 376 / 376 / 376 |
| LOD1 ratio | 0.32–0.62 of base | 0.5000 / 0.5000 / 0.4681 |
| LOD2 ratio | 0.10–0.35 of base | 0.2181 / 0.2181 / 0.1649 |
| Materials | exactly 3 distinct, ≥24 metal, ≥12 board, ≥12 wood | 3 slots, 108 metal, 22 board, 60 wood |
| UVs | in `0..1`, AABB overlap ≤ 1e-5 | in range, overlap 0 |
| Outer AABB | (1.368, 0.201, 1.566) m ± 0.01 | (1.3679, 0.2014, 1.5660), zmin 0 |
| Collider tris | ≤ 140 | 56 |
| Export | written, size > 0 | 45164 / 45164 / 45152 bytes |
| Outer AABB | (1.260, 0.142, 1.551) m ± 0.015 | (1.2600, 0.1420, 1.5510), zmin 0 |
| Collider tris | ≤ 180 | 52 |
| Export | written, size > 0 | 35688 / 35688 / 35676 bytes |

Base triangles dropped from **504 to 376** in the quality pass: glued
diamond cubes and a solid shoe block became wedges and a four-plate
collar. Outer AABB tightened from 1.368 × 0.201 × 1.566 m.

DECIMATE COLLAPSE triangle counts are **not** identical across series —
5.2.1 is more aggressive on LOD2. The gate is a ratio band, not an
5.2.1 is leaner on LOD1 and LOD2. The gate is a ratio band, not an
exact count. Bake pixels are stochastic; the gate is `has_data` plus
operator `FINISHED`, not byte-identity. Construction uses no RNG.
Export byte counts differ by 12 B on 5.2.1 (glTF serializer), not a
gated axis.

`--skip-decimate` skips the LOD DECIMATE stage so LOD1 ratio is 1.0 and
exit 9 fires. That is the named budget the falsifier violates.
### Hygiene

Recomputed from the generated mesh, not asserted about the script.

| Axis | Declared | Measured (all three) |
| --- | --- | --- |
| Non-manifold edges | 0 | 0 |
| Loose verts / edges | 0 / 0 | 0 / 0 |
| Doubles merged at 1e-5 | 0 | 0 |
| Zero-area faces | 0 | 0 |
| N-gons | 0 | 0 |
| Coplanar disjoint face pairs | 0 | 0 |
| Grounded: `zmin` | within 1e-4 of 0 | 0.0000 |
| Named shoe plates | ≥1, each `zmin` ≤ 0.002 | 4, 0.00000 |

### Joint fit and orthogonal boards

| Axis | Declared | Measured (all three) |
| --- | --- | --- |
| Board-to-post BVH gap | ≤ 0.008 m | 0.00500 |
| Strap-to-post BVH gap | ≤ 0.008 m | 0.00300 |
| Board AABB Y (axis-aligned) | ≤ 0.055 m | 0.0280 |

### Falsifiers

Each violates one named budget. All were run on 4.5.11, 5.1.2 and 5.2.1
and returned the same code on each.

| Flag | Budget violated | Exit |
| --- | --- | --- |
| `--skip-decimate` | LOD1 ratio band | 9 |
| `--stray-vert` | loose vertex count is 0 | 15 |
| `--lift-z` | bounding box `zmin` is 0 | 16 |
| `--short-shoe` | named shoes plant at z=0 | 16 |
| `--gap-board` | board-to-post BVH gap | 17 |
| `--float-strap` | strap-to-post BVH gap | 18 |
| `--yaw-boards` | board AABB Y (orthogonal) | 19 |

`--short-shoe` lifts only the iron shoe plates. After zmin snap the
post is the AABB `zmin`, so the AABB gate would still pass; the named
shoe stations fail. `--gap-board` moves the board inner station outside
the post. `--float-strap` adds Y offset to the U-wrap so it no longer
bites. `--yaw-boards` restores a 0.12 rad yaw; the AABB secondary
extent exceeds the thickness bound.

## Run

```bash
blender --background --python signpost.py --
blender --background --python signpost.py -- --skip-decimate
blender --background --python signpost.py -- --stray-vert
blender --background --python signpost.py -- --lift-z
blender --background --python signpost.py -- --short-shoe
blender --background --python signpost.py -- --gap-board
blender --background --python signpost.py -- --float-strap
blender --background --python signpost.py -- --yaw-boards
blender --background --python signpost.py -- --output signpost.png
```

Smoke does not pass `--output` or `--skip-decimate`.
Smoke passes no flags.

## Exit codes

File-local. `9` is a valid check code. `10` is reserved for
`gallery_framing.check_framing` on the `--output` path.
`gallery_framing.check_framing` on the `--output` path. `15`–`19` are the
hygiene and joint-fit family.

| Code | Meaning |
| --- | --- |
Expand All @@ -73,3 +138,8 @@ File-local. `9` is a valid check code. `10` is reserved for
| 12 | Bake did not finish or image has no data |
| 13 | Export file missing or empty |
| 14 | `--output` produced no file |
| 15 | Hygiene (`--stray-vert` lands here) |
| 16 | Grounded zmin / named shoes (`--lift-z`, `--short-shoe`) |
| 17 | Board-to-post gap (`--gap-board`) |
| 18 | Strap-to-post gap (`--float-strap`) |
| 19 | Board yaw / AABB Y (`--yaw-boards`) |
Binary file modified showcase/signpost/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