Skip to content

fix: wheelbarrow and gltf-skin-roundtrip quality pass - #249

Merged
TMHSDigital merged 3 commits into
mainfrom
fix/wheelbarrow-gltf-skin-quality-pass
Sep 25, 2026
Merged

TMHSDigital merged 3 commits into
mainfrom
fix/wheelbarrow-gltf-skin-quality-pass

Conversation

@TMHSDigital

Copy link
Copy Markdown
Owner

A quality pass on two items, both taken from the last run's (#248) list of weakest remaining content:

  • wheelbarrow (Track A, showcase)
  • gltf-skin-roundtrip (Track B, gallery example)

Binaries:

  • .scratch/blender-4.5.11-windows-x64 (reports Blender 4.5.11 LTS)
  • blender-5.1.2-windows-x64 (Blender 5.1.2)
  • blender-5.2.1-windows-x64 (Blender 5.2.1 LTS)

The heroes were rendered on 5.2.1 through scripts/render_hero.py. The inspection renders stayed in .scratch/.

wheelbarrow (Track A)

Inspection sheet: six orthographic views, two three-quarter views, clay, wireframe, six joint close-ups and a ground-contact view.

Defects (round 0):

  1. The frame was three sticks. Each shaft was three separate boxes: a handle that stopped at the tray's rear corner, a level run at 0.255 m from the centreline, and a fork from the tray's front corner. The level run sat exactly under the tray's side wall, which was also at 0.255 m, so it was hidden. From outside, the tray carried everything and the barrow read as a crate on legs. Revealed by the front and top orthos, the three-quarter views and the code.
  2. Box tray. The sides were vertical and the front square (end orthos, three-quarter views).
  3. Abrupt fork. The fork turned in a 50° V over 0.18 m to reach the hub (top ortho).
  4. Spreader inside the wheel. The spreader between the forks stood inside the wheel's disc and touched neither fork arm: it spanned ±0.038 m at x = 0.44, where the arms are 0.21 m out (joint_wheel_axle).
  5. Strap tabs. The iron straps ran 12 mm above the wall tops (joint_tray_corner, joint_tray_floor, the nubs in ortho_top). They were sized from the floor bottom plus the wall height, but each wall sits WALL_SEAT into the floor.

Generator changes, and why each is structural:

  1. Shafts. Each shaft is one mitred sweep through the grip, the tray's rear, its front and the axle, so it reads as one timber.
    • Its plan narrows the whole way: 0.27 m at the grips, 0.19 m and 0.15 m under the tray, 0.038 m at the hub. It therefore shows beneath the tray.
    • The legs, their stretcher, and a bearer under the tray front all hang from it. The bearer's ends are positioned on the shafts' own centrelines, so it replaces the spreader (4).
    • This also fixes the fork (3): the convergence is spread over the whole shaft instead of one short V.
  2. Hopper tray. The tray is built from a bottom outline and a top outline: sides flared 15°, the front raked 30° out over the wheel for tipping, the low rear leaning back 12°.
    • Each wall is the planar band between its two edges, so a board's corners follow the geometry.
    • The end boards are housed half a board into the sides, and the sides run past the ends' outer faces.
  3. Straps follow the flared wall's outer face and stop 10 mm below its top (5).
  4. Audits rebuilt for leaning boards. A leaning board's outer face sits lower than its inner one, so AABB-based tests lie: a Z seam reads negative and a zmin seat reads the outer edge.
    • Seams are now measured along each wall's own up direction, and the seat on each wall's lowest board's inner face.
    • Both directions are taken from the boards' own faces, not the build constants, so the vertical-wall falsifier still reaches its own gate.
  5. WALL_SEAT 12 → 8 mm. A raked board's outer bottom edge sits WALL_T·sin(RAKE) = 11 mm below its inner one, so a 12 mm seat would break through the 22 mm floor's underside.

Removed budget: the handle-join budget is gone, because the handle no longer joins anything; it is the shaft. The shaft-run budget replaces it.

New budgets. Every value is identical on 4.5.11, 5.1.2 and 5.2.1:

Budget Declared Measured
Shaft runs: wood shells unbroken from behind the tray to past its front exactly 2 2
Tray flare / rake, from the boards' faces ≥ 10° / ≥ 20° 15.00° / 30.00°

Existing budgets, re-measured:

  • Hygiene is 0 on every axis.
  • Named shoe and tyre supports: z 0.
  • Spoke clearance: 52.1 mm.
  • Wall-floor seat: 8.0 mm.
  • Metal-wood gap: 0.
  • Wall boards: 2 / 2 / 2, with seams of 2.07–2.31 mm.
  • Tread aspect: 5.111.

Re-fitted:

  • Outer AABB: (1.558, 0.630, 0.574) → (1.563, 0.594, 0.577) m.
  • Tray size: (0.720, 0.532, 0.220) → (0.939, 0.578, 0.225) m. The tray is now measured at its flared top edge.

Triangles: base 2536 → 2440, inside the unchanged 2300–2800 band. The collider went from 90 to 80.

Falsifiers. Each new one violates only its own new budget:

  • --split-shafts builds the three boxes again: 0 shaft runs.
  • --box-tray stands every wall vertical on the flared tray's top outline, so the envelope and tray size stay put: 0° / 0°.

Because exit 17 covers several joint gates, I checked that each 17 falsifier fails on its own gate's message.

default --skip-decimate --stray-vert --lift-z --short-legs --fat-spokes --float-walls --pipe-rim --wide-seams --split-shafts --box-tray --output
4.5.11 0 9 15 16 16 17 17 18 17 20 21 0
5.1.2 0 9 15 16 16 17 17 18 17 20 21 0
5.2.1 0 9 15 16 16 17 17 18 17 20 21 0

Inspection rounds: 1 for geometry. The round-1 sheet showed the flared hopper, the shafts running unbroken under the tray, and every joint closed. The hero read as a wheelbarrow with no further change.

Framing: fill 0.728, minimum margin 0.067, with no deviation=.

Determinism: the default and --output runs on 5.2.1 report identical measured lines. Across binaries, only the LOD2 decimation count (inside its ratio band) and the export byte count differ, as before.

Contact sheet: wheelbarrow.

before after
luma 0.172 0.171
stage 0.165 0.164
warmth +0.068 +0.055
sat 0.132 0.130

It sits inside the band and is legible at card size.

Asset sheet: wheelbarrow. Verdict: passes clearly. The piece is rendered alone and neutrally beside the four pinned asset references. The flared, strapped, raked tray with per-board tone puts it among the more designed objects in the lineup, level with the hydrant.

Convention changes (their own commit, in showcase/README.md):

  • "A bent bar is one sweep" now also covers timber that carries a load end to end.
  • New: "A tray that tips is a hopper, not a box".
  • New: "Measure a leaning board in its own plane".

gltf-skin-roundtrip (Track B)

Defect: the camera looked at both scorpions head-on. The tail curls in each rig's own Y-Z plane, so it was seen end-on: it stood straight up behind the body like a chimney, and the pair read as boxy robots in cone hats.

Not changed, because it is the contract:

  • The upright, blocky body is deliberate: a rearing mech scorpion on a base plate.
  • Its vertices, weights and posed deformation are what the check asserts, so the mesh is untouched.
  • The dark legs are the same asserted mesh.

Presentation change: both armatures are yawed −50° about their own origins and set 1.0 m either side of centre (they were 1.1 m). The tail now arcs over the head in profile, with the claws forward and the legs down the flanks.

  • The yaw is composed into each world matrix. The glTF importer leaves its armature in quaternion mode, and my first try, setting rotation_euler, turned only the authored rig.
  • It took three rounds: the yaw, the quaternion fix, then the spacing to bring width fill from 0.913 back into band.
  • Out-of-band framing: fill 0.828, minimum margin 0.066.

Contract confirmation: the contract, assertions and exit codes are unchanged. I diffed every measured-value line across all 9 runs against the pre-change baseline logs, and there are no differences.

default --no-skins --output
before, 4.5.11 / 5.1.2 / 5.2.1 0 / 0 / 0 5 / 5 / 5 0 / 0 / 0
after, 4.5.11 / 5.1.2 / 5.2.1 0 / 0 / 0 5 / 5 / 5 0 / 0 / 0

Contact sheet: gltf-skin-roundtrip.

before after
luma 0.202 0.200
stage 0.193 0.194
warmth +0.245 +0.217
sat 0.130 0.136

The existing alt text ("…with curled tails and glowing cyan stingers…") now matches what the still shows.

Checks

Run locally and passing:

  • check_exit_code_readme.py
  • check_gallery_images.py
  • check_falsifier_targets.py (229 falsifiers across 28 pieces)

build_gallery.py was run last. I read the generated alt text in docs/gallery/index.html and on the wheelbarrow detail page.

🤖 Generated with Claude Code

TMHSDigital and others added 3 commits September 25, 2026 07:21
…pper tray

The barrow read as a crate on legs. Each shaft was three boxes: a handle
stopping at the tray's rear corner, a level run hidden exactly under the
side wall, and a fork turning in a 50-degree V to the hub. The tray was a
square box, a spreader stood inside the wheel touching neither fork, and
the iron straps ran 12 mm above the wall tops.
- Each shaft is one mitred sweep grip -> tray rear -> tray front -> axle,
  narrowing in plan the whole way, legs and a bearer hung from it.
- The tray is a hopper between a bottom and a top outline: sides flared
  15 deg, front raked 30 deg over the wheel, rear leaning 12 deg; end
  boards housed into the sides; straps follow the wall and stop below it.
- Seams and seats are measured in each wall's own plane, taken from the
  boards' faces; AABB tests lie on leaning boards.
New budgets: shaft runs = 2 (exit 20, --split-shafts), flare >= 10 deg and
rake >= 20 deg (exit 21, --box-tray, same top outline). The handle-join
budget is gone: the handle is the shaft. Outer AABB and tray size re-fitted.
Tris 2536 -> 2440. Same codes on 4.5.11, 5.1.2 and 5.2.1. Asset sheet added.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
…hoppers

Extends "A bent bar is one sweep" to timber that carries a load end to end,
and adds two conventions from the wheelbarrow pass: a tray emptied by tipping
is built as a hopper with a flare floor (falsifier keeps the top outline), and
a leaning board is measured in its own plane, from its own faces.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
The tail curls in each rig's Y-Z plane, and the camera looked at both
scorpions head-on, so the curl was seen end-on and the tail stood straight
up like a chimney: a boxy robot, not a scorpion. Both armatures are now
yawed -50 deg about their own origins, composed into the world matrix
because the glTF importer leaves its armature in quaternion mode, and set
1.0 m either side of centre. Render path only. Exit codes unchanged on
4.5.11, 5.1.2 and 5.2.1 (default 0, --no-skins 5, --output 0) and every
measured line matches the baseline. Shared gallery index rides here.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
@TMHSDigital TMHSDigital added the needs-5.1 Opt-in Blender 5.1 smoke on this PR. Default matrix stays 4.5 + 5.2. Auto-label will not apply this. label Sep 25, 2026
@github-actions github-actions Bot added examples Runnable smoke-gated examples under examples/ showcase Budget-conformance props under showcase/ documentation Improvements or additions to documentation labels Sep 25, 2026
@TMHSDigital
TMHSDigital merged commit 5683805 into main Sep 25, 2026
14 checks passed
@TMHSDigital
TMHSDigital deleted the fix/wheelbarrow-gltf-skin-quality-pass branch September 25, 2026 11:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation examples Runnable smoke-gated examples under examples/ needs-5.1 Opt-in Blender 5.1 smoke on this PR. Default matrix stays 4.5 + 5.2. Auto-label will not apply this. showcase Budget-conformance props under showcase/

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant