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
Binary file modified docs/gallery/assets/market-stall-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 modified docs/gallery/assets/watchtower-hero.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 @@ -936,7 +936,7 @@ <h2><a href="campfire/">campfire</a></h2>
<div class="card-body">
<h2><a href="market-stall/">market-stall</a></h2>
<p class="teaches">A procedural timber market stall 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: 4404 tris, three materials with 48 faces per awning stripe slot, UVs in 0..1 with zero AABB overlap, outer AABB 1.392×0.966×1.743 m, LOD ratios in band, convex collider 46 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.</p>
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 4324 tris, three materials with 34 faces per awning stripe slot, UVs in 0..1 with zero AABB overlap, outer AABB 1.389×1.011×1.740 m, grounded zmin, 4 wrap feet, brace-counter overlap 0, awning seat 4 mm, post plumb 0, LOD ratios in band, convex collider 58 tris, non-empty glTF. Hygiene all zero. --skip-decimate exits 9; --stray-vert 15; --lift-z/--short-feet 16; --low-brace 17; --float-awning 18; --rake-posts 19.</p>
<a class="card-link" href="market-stall/">View example <span aria-hidden="true">&rarr;</span></a>
</div>
</article>
Expand Down Expand Up @@ -991,7 +991,7 @@ <h2><a href="fence-kit/">fence-kit</a></h2>
<div class="card-body">
<h2><a href="watchtower/">watchtower</a></h2>
<p class="teaches">A procedural timber watchtower 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: 5220 tris, three materials with 84 metal and 126 roof faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.434×1.434×1.982 m, LOD ratios in band, 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: 6408 tris, three materials with 300 metal and 126 roof faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.594×1.594×2.973 m, grounded zmin, 4 iron shoes, rail engage 18 mm, collar standoff 2 mm, post plumb 0, LOD ratios in band (5.2 COLLAPSE leaner on LOD2), convex collider 150 tris, non-empty glTF. Hygiene all zero. --skip-decimate exits 9; --stray-vert 15; --lift-z/--short-shoes 16; --short-rails 17; --float-band 18; --rake-posts 19.</p>
<a class="card-link" href="watchtower/">View example <span aria-hidden="true">&rarr;</span></a>
</div>
</article>
Expand Down
793 changes: 630 additions & 163 deletions docs/gallery/market-stall/index.html

Large diffs are not rendered by default.

736 changes: 586 additions & 150 deletions docs/gallery/watchtower/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions showcase/gallery.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"name": "market-stall",
"dir": "showcase/market-stall",
"teaches": "A procedural timber market stall through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.",
"witnessesFix": "Recomputed: 4404 tris, three materials with 48 faces per awning stripe slot, UVs in 0..1 with zero AABB overlap, outer AABB 1.392×0.966×1.743 m, LOD ratios in band, convex collider 46 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.",
"witnessesFix": "Recomputed: 4324 tris, three materials with 34 faces per awning stripe slot, UVs in 0..1 with zero AABB overlap, outer AABB 1.389×1.011×1.740 m, grounded zmin, 4 wrap feet, brace-counter overlap 0, awning seat 4 mm, post plumb 0, LOD ratios in band, convex collider 58 tris, non-empty glTF. Hygiene all zero. --skip-decimate exits 9; --stray-vert 15; --lift-z/--short-feet 16; --low-brace 17; --float-awning 18; --rake-posts 19.",
"hero": "docs/gallery/assets/market-stall-hero.webp",
"preview": "showcase/market-stall/preview.webp",
"tags": [
Expand Down Expand Up @@ -117,7 +117,7 @@
"name": "watchtower",
"dir": "showcase/watchtower",
"teaches": "A procedural timber watchtower through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.",
"witnessesFix": "Recomputed: 5220 tris, three materials with 84 metal and 126 roof faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.434×1.434×1.982 m, LOD ratios in band, convex collider 56 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.",
"witnessesFix": "Recomputed: 6408 tris, three materials with 300 metal and 126 roof faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.594×1.594×2.973 m, grounded zmin, 4 iron shoes, rail engage 18 mm, collar standoff 2 mm, post plumb 0, LOD ratios in band (5.2 COLLAPSE leaner on LOD2), convex collider 150 tris, non-empty glTF. Hygiene all zero. --skip-decimate exits 9; --stray-vert 15; --lift-z/--short-shoes 16; --short-rails 17; --float-band 18; --rake-posts 19.",
"hero": "docs/gallery/assets/watchtower-hero.webp",
"preview": "showcase/watchtower/preview.webp",
"tags": [
Expand Down
94 changes: 74 additions & 20 deletions showcase/market-stall/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
# Market stall

A showcase piece, not an example. Procedural timber stall (posts with feet,
slanted rafters, slatted counter and shelf, back-wall planks, eave fascia,
striped awning and valance) then the shipped pipeline: unique-cell UVs,
Cycles high-to-low normal bake, LOD chain, convex collider, Unity glTF
export.
A showcase piece, not an example. Procedural timber stall (corner posts
with wrap plinths, slatted counter and shelf, back-wall planks, side
braces that sit in the post bay, striped awning with a front roller and
hanging valance) then the shipped pipeline: unique-cell UVs, Cycles
high-to-low normal bake, LOD chain, convex collider, Unity glTF export.

The old piece used capped foot cubes coplanar with the post bottoms and
counter-leg pads coplanar with the legs, which z-fought at Z=0. Wrap
plates stand off the post; counter legs go to Z=0 without a second
bottom face.

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 @@ -22,38 +27,82 @@ materials, UVs, evaluated LOD, collider, or export file.

| Axis | Declared | Measured (4.5.11 / 5.1.2 / 5.2.1) |
| --- | --- | --- |
| Base triangles | 4280–4550 | 4404 / 4404 / 4404 |
| Base triangles | 3900–5200 | 4324 / 4324 / 4324 |
| LOD1 ratio | 0.32–0.62 of base | 0.5000 / 0.5000 / 0.5000 |
| LOD2 ratio | 0.10–0.35 of base | 0.2198 / 0.2198 / 0.2198 |
| Materials | exactly 3 distinct, ≥16 faces per stripe slot | 3 slots, 48 / 48 stripe faces |
| LOD2 ratio | 0.10–0.35 of base | 0.2197 / 0.2197 / 0.2197 |
| Materials | exactly 3 distinct; ≥16 faces per stripe slot | 3 slots; 34 / 34 stripe faces |
| UVs | in `0..1`, AABB overlap ≤ 1e-5 | in range, overlap 0 |
| Outer AABB | (1.392, 0.966, 1.743) m ± 0.01 | (1.3915, 0.9659, 1.7430), zmin 0 |
| Collider tris | ≤ 80 | 46 |
| Export | written, size > 0 | 316748 / 316748 / 316724 bytes |
| Outer AABB | (1.389, 1.011, 1.740) m ± 0.01 | (1.3892, 1.0107, 1.7402), zmin 0 |
| Collider tris | ≤ 80 | 58 |
| Export | written, size > 0 | 312752 / 312752 / 312728 bytes |

### Hygiene

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

DECIMATE COLLAPSE triangle counts are **not** guaranteed identical across
series — the gate is a ratio band, not an exact count. This mesh happened
to match on 4.5.11 / 5.1.2 / 5.2.1. Bake pixels are stochastic; the gate
is `has_data` plus operator `FINISHED`, not byte-identity. Construction
uses no RNG. glTF byte size differs by a few bytes across series.
| 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 supports: 4 wrap feet | each `zmin` ≤ 1e-3 | 4, foot_z 0.00000 |
| Frame plan | 1.36 × 0.92 m ± 0.04 | 1.3600 × 0.9200 |

### Joint fit and seat

`--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.
| Axis | Declared | Measured (all three) |
| --- | --- | --- |
| Brace-vs-counter overlap | ≤ 1e-6 m³ | 0.000000 |
| Header-post tenon engage | ≥ 0.4 × tenon | 0.0595 |
| Awning-on-header seat | −0.002–0.010 m | 0.00378 |
| Post plumb (XY drift) | ≤ 0.008 m | 0.00000 |

DECIMATE COLLAPSE triangle counts are **not** identical across series —
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
24 B on 5.2.1 (glTF serializer), not a gated axis.

### Falsifiers

Each violates one named budget. All eight 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-feet` | named wrap-foot supports at Z=0 | 16 |
| `--low-brace` | brace-vs-counter overlap | 17 |
| `--float-awning` | awning-on-header seat | 18 |
| `--rake-posts` | post plumb | 19 |

## Run

```bash
blender --background --python market_stall.py --
blender --background --python market_stall.py -- --skip-decimate
blender --background --python market_stall.py -- --stray-vert
blender --background --python market_stall.py -- --lift-z
blender --background --python market_stall.py -- --short-feet
blender --background --python market_stall.py -- --low-brace
blender --background --python market_stall.py -- --float-awning
blender --background --python market_stall.py -- --rake-posts
blender --background --python market_stall.py -- --output stall.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 @@ -72,3 +121,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 | Mesh hygiene: loose, non-manifold, zero-area, doubles, n-gons, z-fight |
| 16 | Not grounded: bounding box `zmin` off 0, or a named wrap foot floats |
| 17 | Joint fit: brace occupying the counter volume |
| 18 | Seat: awning-on-header gap |
| 19 | Post plumb or frame plan off the stated real-world size |
Loading
Loading