Shipping Crate

showcase/shipping-crate/

A procedural shipping crate through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.

Rendered headless by the showcase piece itself. Select it to enlarge.

witnesses Recomputed: 3388 tris, two materials with 1170 wood and 904 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.146×0.726×0.612 m, grounded zmin, 3 skids, handle-end and slat-post join 0, mesh hygiene all zero, LOD ratios in band (5.2 COLLAPSE leaner on LOD2), convex collider 100 tris, non-empty glTF. --skip-decimate exits 9; --stray-vert 15; --lift-z/--short-skids 16; --float-handle 17; --omit-slats 18.

category Village

tags mesh export showcase

blender --background --python showcase/shipping-crate/shipping_crate.py --

A showcase piece, not an example. Procedural crate (skids under the posts, corner posts with tenoned slats and seeded width jitter, bottom sills, nailed single-shell L-straps, filleted iron bail handles through mounting plates seated on one end board each) then the shipped pipeline: unique-cell UVs, Cycles high-to-low normal bake, LOD chain, convex collider, Unity glTF export.

Skids sit under the posts so the outer corner is a mortise, not a cave. Handle bails use quarter-circle corners so a 90-degree loft cannot sit the bar on the plate.

It asserts budget conformance of the generated result. It does not witness an API contract. "It rendered without error" is not a check.

Composes skills mesh-editing-and-bmesh, bake-high-to-low, depsgraph-and-evaluated-data, engine-export-presets, and snippets 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).

Budgets#

Declared as named constants; every gate recomputes from the mesh, materials, UVs, evaluated LOD, collider, or export file.

AxisDeclaredMeasured (4.5.11 / 5.1.2 / 5.2.1)
Base triangles2900–39003388 / 3388 / 3388
LOD1 ratio0.32–0.62 of base0.5000 / 0.5000 / 0.5000
LOD2 ratio0.10–0.35 of base0.2196 / 0.2196 / 0.2196
Materialsexactly 2 distinct; ≥900 wood, ≥600 metal faces2 slots; 1170 / 904
UVsin 0..1, AABB overlap ≤ 1e-5in range, overlap 0
Outer AABB(1.146, 0.726, 0.612) m ± 0.015(1.1460, 0.7260, 0.6120), zmin 0
Collider tris≤ 220100
Exportwritten, size > 0273124 / 273196 / 273188 bytes (4.5.11 / 5.1.2 / 5.2.1)

Base triangles rose from 624 to 2508 in the quality pass: the old beveled cube with glued-on slats became a post-and-slat crate with tenons, sills, L-straps, and pipe handles. The second pass took them to 3388: single-shell chamfered straps, 24 nails, chamfered mounting plates.

DECIMATE COLLAPSE triangle counts are not guaranteed identical across series; on this mesh they happen to match (LOD2 744 on all three). 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. Slat-width jitter uses fixed seed 17. Export byte counts differ by 16 B on 5.2.1 (glTF serializer), not a gated axis.

Hygiene#

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

AxisDeclaredMeasured (all three)
Non-manifold edges00
Loose verts / edges0 / 00 / 0
Doubles merged at 1e-500
Zero-area faces00
N-gons00
Coplanar disjoint face pairs00
Grounded: zminwithin 1e-4 of 00.0000
Named supports: 3 skidseach zmin ≤ 1e-33, skid_z 0.00000
Body plan1.056 × 0.716 m ± 0.051.0560 × 0.7160

Joint fit and seat#

AxisDeclaredMeasured (all three)
Handle-end BVH gap≤ 0.008 m0.00000
Slat-post BVH gap≤ 0.006 m0.00000
Nail seat24 nails; bite 0.3–1.0 mm into the strap, head ≥ 1.0 mm proud24; 0.60 mm; 1.80 mm
Handle plates on one boardeach plate inside a single end board with ≥ 4 mm clearance at both edges4 plates; 32.4 mm

Second pass (straps, nails, handle placement, surface)#

The inspection sheet found the iron and the handles built the way crate-stack used to build them:

The right-angle-edge budget from crate-stack is not applied here: the handle bail's pipe ends are square discs buried in the mounting plates, so "every box is chamfered" does not hold for this piece.

Third pass (stencil, hero angle)#

The crate read as a plain plank box: nothing on it said what it was for. Its front long side (-Y) now carries stencilled cargo marks, PORT ROYAL over NO 17. They are surface only: a 5x7 bitmap font painted into a small image covering the side in object space, cubic-filtered and thresholded into rounded stencil strokes, bitten by a fine overspray noise, and masked to the -Y faces. Each line is centred on one long slat, replayed from the same seeded _span_layout that places the slats, and its 64 mm cap height fits inside the board, so the baseline runs along the board. The first cut let both lines straddle a gap, which in perspective read as lettering sloping across the slats. The image node is deselected so the normal bake never targets it. Geometry, triangles, material face counts and every budget are unchanged; the glTF grows by about 800 bytes.

The hero turned the crate -48 degrees, which put the long side edge-on. The camera sits at about -51 degrees azimuth, so the crate now turns +15 degrees: the stencilled side is 24 degrees off the view axis and the handle end 66 degrees, a three-quarter view led by the lettering. An intermediate -20 degrees left the side 59 degrees off-axis, where the stencil foreshortened into a steep italic. The key is brighter and the stage is 60 m (the 14 m grid could show its edge).

Falsifiers#

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

FlagBudget violatedExit
--skip-decimateLOD1 ratio band9
--stray-vertloose vertex count is 015
--lift-zbounding box zmin is 016
--short-skidsnamed skid supports at Z=016
--float-handlehandle-end gap17
--omit-slatsslat-post seat18
--float-nailsnail seat band (heads lifted 1.5 mm off the straps)18
--straddle-handlehandle plates on one end board20

Run#

blender --background --python shipping_crate.py --
blender --background --python shipping_crate.py -- --skip-decimate
blender --background --python shipping_crate.py -- --stray-vert
blender --background --python shipping_crate.py -- --lift-z
blender --background --python shipping_crate.py -- --short-skids
blender --background --python shipping_crate.py -- --float-handle
blender --background --python shipping_crate.py -- --omit-slats
blender --background --python shipping_crate.py -- --float-nails
blender --background --python shipping_crate.py -- --straddle-handle
blender --background --python shipping_crate.py -- --output crate.png

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. 15–19 are the hygiene and joint-fit family.

CodeMeaning
0Success
1Uncaught exception (FATAL wrapper)
2argparse / usage
3Mesh did not build / no UV layer
4Base triangle count outside range
5Material count ≠ 2 distinct slots, or a face-count floor missed
6UVs outside 0..1
7UV AABB overlap above tolerance
8World AABB off declared outer size
9LOD ratio band (--skip-decimate lands here)
10Framing gate (render path only)
11Collider triangle count above ceiling
12Bake did not finish or image has no data
13Export file missing or empty
14--output produced no file
15Mesh hygiene: loose, non-manifold, zero-area, doubles, n-gons, z-fight
16Not grounded: bounding box zmin off 0, or a named skid floats
17Joint fit: handle-end gap
18Seat: slat-post gap, or a nail head off its strap seat band (--float-nails)
19Body plan off the stated real-world size
20A handle mounting plate not seated on a single end board (--straddle-handle)
21Gallery asset-quality violation (render path; the floors' 11 is remapped here)

Source

showcase/shipping-crate/shipping_crate.py View the script on GitHub →
A grained wooden shipping crate in three-quarter view, PORT ROYAL and NO 17 stencilled along its side slats, with nailed iron corner straps and a bail handle on one end.