From ef837ff3dc46e348f05b027b598963a5e5e343ff Mon Sep 17 00:00:00 2001 From: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Date: Tue, 15 Sep 2026 21:21:12 -0400 Subject: [PATCH 1/3] fix: rebuild stone-well so the joints meet and the bucket opens Quality pass on the stone-well generator after an inspection-sheet review found the curb floating above the masonry, windlass stubs buried in the posts, a crank that was a capped stub, an open pit at the roof peak, a sealed bucket with hoops that ignored the taper, a bail handle floating off the rim, and a rope that ended above the handle. Structural fixes in the generator: curb Z derived from the masonry top, windlass lengthened to pass through both posts, a real crank arm and grip, a peak cap, a manifold open bucket with tapered walls and hoops that follow it, bail legs pinned at the rim, rope terminated at the bail bar. Deterministic per-stone jitter, bevels on structural wood, noise/wear on all three materials, cap_tris everywhere to kill n-gons. New budgets: hygiene (loose/non-manifold/zero-area/doubles/ngons all zero, exit 15), grounded zmin (exit 16, --lift-z falsifier), BVH material-island gaps (exit 17), per-material face floors (exit 5) that catch the materials.clear() index-wipe class. Slot assignment is now index-preserving. Hero re-rendered; framing gate passes. Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Cursor --- docs/gallery/assets/stone-well-hero.webp | Bin 27758 -> 30904 bytes docs/gallery/stone-well/index.html | 473 +++++++++++++++++++---- showcase/stone-well/README.md | 24 +- showcase/stone-well/preview.webp | Bin 25266 -> 30904 bytes showcase/stone-well/stone_well.py | 462 ++++++++++++++++++---- 5 files changed, 811 insertions(+), 148 deletions(-) diff --git a/docs/gallery/assets/stone-well-hero.webp b/docs/gallery/assets/stone-well-hero.webp index c043ede4968d5cfdbce057025369d35343a4095f..da5018941da7294e43f85a4d348c14168deee3d8 100644 GIT binary patch literal 30904 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 z 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 stone-well render

Rendered headless by the example itself — click to zoom.

-
witnesses Recomputed: 8388 tris, three materials, UVs in 0..1 with zero AABB overlap, outer AABB 1.640×1.640×1.688 m, LOD ratios in band, convex collider 230 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.
+
witnesses Recomputed: 9380 tris, three materials with face floors, UVs in 0..1 with zero AABB overlap, outer AABB 1.640×1.640×1.761 m, LOD ratios in band, convex collider 306 tris, hygiene zero (loose, non-manifold, doubles, n-gons), grounded zmin, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget; --lift-z exits 16 on the grounded budget.
blender --background --python showcase/stone-well/stone_well.py --
@@ -264,17 +264,18 @@

stone-well

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.

-

| Axis | Declared | Measured (4.5.11 / 5.1.2 / 5.2.1) | | --- | --- | --- | | Base triangles | 8280–8500 | 8388 / 8388 / 8388 | | 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 | 3 | | UVs | in 0..1, AABB overlap ≤ 1e-5 | in range, overlap 0 | | Outer AABB | (1.640, 1.640, 1.688) m ± 0.01 | (1.6400, 1.6400, 1.6882), zmin 0 | | Collider tris | ≤ 260 | 230 | | Export | written, size > 0 | 601028 / 601092 / 601372 bytes |

+

| Axis | Declared | Measured (4.5.11 / 5.1.2 / 5.2.1) | | --- | --- | --- | | Base triangles | 8280–9500 | 9380 / 9380 / 9380 | | 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 | 3 | | Material faces | stone ≥ 3000, wood ≥ 600, metal ≥ 100 | all above | | UVs | in 0..1, AABB overlap ≤ 1e-5 | in range, overlap 0 | | Outer AABB | (1.640, 1.640, 1.761) m ± 0.01 | (1.6400, 1.6400, 1.7606) | | Grounded | bbox min Z within 1e-4 of 0 | 0.0000 / 0.0000 / 0.0000 | | Hygiene | loose V/E, non-manifold, zero-area, doubles @1e-5, n-gons: all 0 | 0 / 0 / 0 on every axis | | Material-island gap | stone↔wood and metal↔wood min distance ≤ 0.008 m | 0.00000 / 0.00000 / 0.00000 | | Collider tris | ≤ 320 | 306 | | Export | written, size > 0 | 686672 / 686736 / 686724 bytes |

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 hundred bytes across series.

-

--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.

+

--skip-decimate skips the LOD DECIMATE stage so LOD1 ratio is 1.0 and exit 9 fires. --lift-z raises the finished mesh 0.05 m so the grounded budget fails and exit 16 fires. Those are the named budgets the two falsifiers violate.

Run

blender --background --python stone_well.py --
 blender --background --python stone_well.py -- --skip-decimate
+blender --background --python stone_well.py -- --lift-z
 blender --background --python stone_well.py -- --output well.png
-

Smoke does not pass --output or --skip-decimate.

+

Smoke does not pass --output, --skip-decimate, or --lift-z.

Exit codes

File-local. 9 is a valid check code. 10 is reserved for gallery_framing.check_framing on the --output path.

-

| Code | Meaning | | --- | --- | | 0 | Success | | 1 | Uncaught exception (FATAL wrapper) | | 2 | argparse / usage | | 3 | Mesh did not build / no UV layer | | 4 | Base triangle count outside range | | 5 | Material count ≠ 3 distinct slots | | 6 | UVs outside 0..1 | | 7 | UV AABB overlap above tolerance | | 8 | World AABB off declared outer size | | 9 | LOD ratio band (--skip-decimate lands here) | | 10 | Framing gate (render path only) | | 11 | Collider triangle count above ceiling | | 12 | Bake did not finish or image has no data | | 13 | Export file missing or empty | | 14 | --output produced no file |

+

| Code | Meaning | | --- | --- | | 0 | Success | | 1 | Uncaught exception (FATAL wrapper) | | 2 | argparse / usage | | 3 | Mesh did not build / no UV layer | | 4 | Base triangle count outside range | | 5 | Material count ≠ 3 distinct slots, or a material face floor missed | | 6 | UVs outside 0..1 | | 7 | UV AABB overlap above tolerance | | 8 | World AABB off declared outer size | | 9 | LOD ratio band (--skip-decimate lands here) | | 10 | Framing gate (render path only) | | 11 | Collider triangle count above ceiling | | 12 | Bake did not finish or image has no data | | 13 | Export file missing or empty | | 14 | --output produced no file | | 15 | Hygiene: loose geometry, non-manifold, zero-area, doubles, or n-gons | | 16 | Bbox min Z not grounded (--lift-z lands here) | | 17 | Material-island gap above tolerance (parts meant to touch) |

Source

@@ -290,14 +291,16 @@

Source

Budgets are declared below and recomputed from the generated result. They are not API-contract witnesses. ``--skip-decimate`` skips the LOD -DECIMATE stage so the LOD-ratio budget fails. +DECIMATE stage so the LOD-ratio budget fails. ``--lift-z`` raises the +mesh so the grounded-zmin hygiene budget fails. -No RNG. Construction is closed-form. DECIMATE COLLAPSE triangle counts -are not byte-identical across Blender versions — the LOD gate is a -ratio band, not an exact count. +No RNG. Construction is closed-form (per-stone jitter is a deterministic +hash). DECIMATE COLLAPSE triangle counts are not byte-identical across +Blender versions — the LOD gate is a ratio band, not an exact count. blender --background --python stone_well.py -- blender --background --python stone_well.py -- --skip-decimate + blender --background --python stone_well.py -- --lift-z blender --background --python stone_well.py -- --output well.png """ import argparse @@ -310,6 +313,7 @@

Source

import bmesh import bpy from mathutils import Euler, Vector +from mathutils.bvhtree import BVHTree # Showcase lives at repo-root/showcase/, not under examples/. The framing # helper is the repo's only shared import and lives next to the examples; @@ -331,12 +335,17 @@

Source

R_MID = (R_INNER + R_OUTER) / 2.0 WALL_H = 0.72 STONE_H = WALL_H / N_ROWS +STONE_FACE_H = STONE_H * 0.90 +# Top of the masonry is the top of the last course, not the nominal WALL_H: +# the curb seats on the measured course top so no daylight shows at the rim. +MASONRY_TOP = STONE_FACE_H + (N_ROWS - 1) * STONE_H CURB_H = 0.065 CURB_OUT = 0.045 +CURB_Z = MASONRY_TOP + CURB_H / 2.0 POST_S = 0.068 POST_R = 0.55 POST_H = 0.58 -POST_BOTTOM = WALL_H + CURB_H +POST_BOTTOM = MASONRY_TOP + CURB_H POST_TOP = POST_BOTTOM + POST_H EAVE_OVERHANG = 0.22 EAVE_HALF = POST_R + POST_S / 2.0 + EAVE_OVERHANG @@ -345,18 +354,31 @@

Source

PEAK_Z = EAVE_Z + ROOF_RISE SHINGLE_T = 0.016 WINDLASS_R = 0.045 -BUCKET_R = 0.10 +# The windlass is the axle the posts are the bearings for: it passes through +# both posts and protrudes so the crank has something to attach to. +WINDLASS_END = POST_R + POST_S / 2.0 + 0.015 +WINDLASS_LEN = 2.0 * WINDLASS_END +BUCKET_R_TOP = 0.105 +BUCKET_R_BOT = 0.088 +BUCKET_WALL_T = 0.008 BUCKET_H = 0.14 BUCKET_Z = 0.68 +BUCKET_RIM_Z = BUCKET_Z + BUCKET_H / 2.0 +HANDLE_BAR_Z = BUCKET_RIM_Z + 0.03 ROPE_R = 0.016 BBOX_TOL = 0.01 # Fitted to the generated AABB after locking geometry. Recomputed from bound_box. -OUTER_SIZE = (1.640, 1.640, 1.688) +OUTER_SIZE = (1.640, 1.640, 1.761) # Measured after locking geometry. DECIMATE COLLAPSE ratios diverge across # series — bands, not exact counts. Tightened after the first 4.5/5.1/5.2 run. BASE_TRIS_MIN = 8280 -BASE_TRIS_MAX = 8500 +BASE_TRIS_MAX = 9500 +ZMIN_EPS = 1e-4 +DOUBLES_EPS = 1e-5 +AREA_EPS = 1e-10 +GAP_MAX = 0.008 +LIFT_Z = 0.05 LOD1_RATIO_MIN = 0.32 LOD1_RATIO_MAX = 0.62 LOD2_RATIO_MIN = 0.10 @@ -364,9 +386,12 @@

Source

LOD1_TARGET = 0.50 LOD2_TARGET = 0.22 MATERIAL_COUNT = 3 +STONE_FACES_MIN = 3000 +WOOD_FACES_MIN = 600 +METAL_FACES_MIN = 100 UV_EPS = 1e-4 UV_OVERLAP_MAX = 1e-5 -COLLIDER_TRIS_MAX = 260 +COLLIDER_TRIS_MAX = 320 BAKE_RES = 256 CAGE_EXTRUSION = 0.06 @@ -415,11 +440,14 @@

Source

return verts -def add_cone(bm, loc, radius1, radius2, depth, segments, mat_idx, euler=(0.0, 0.0, 0.0)): +def add_cone( + bm, loc, radius1, radius2, depth, segments, mat_idx, + euler=(0.0, 0.0, 0.0), cap_ends=True, +): geo = bmesh.ops.create_cone( bm, - cap_ends=True, - cap_tris=False, + cap_ends=cap_ends, + cap_tris=True, segments=segments, radius1=radius1, radius2=radius2, @@ -483,23 +511,81 @@

Source

) +def hash01(a, b, c): + # Deterministic per-stone jitter. Closed-form, no RNG state. + return math.sin(a * 127.1 + b * 311.7 + c * 74.7) * 43758.5453 % 1.0 + + +def ring_verts(verts, z, eps=1e-6): + return sorted( + (v for v in verts if abs(v.co.z - z) < eps), + key=lambda v: math.atan2(v.co.y, v.co.x), + ) + + +def add_open_bucket(bm, loc, r_bot, r_top, wall_t, depth, segments, mat_idx): + """Open-topped tapered bucket: outer wall, inner wall, rim ring, floor. + + Manifold single shell. The bottom slab has real thickness: the inner + floor sits FLOOR_T above the outer bottom disc, so every edge has + exactly two faces. + """ + floor_t = 0.012 + z0 = loc[2] - depth / 2.0 + z1 = loc[2] + depth / 2.0 + outer = add_cone( + bm, loc, r_bot, r_top, depth, segments, mat_idx, cap_ends=False, + ) + inner_loc = (loc[0], loc[1], loc[2] + floor_t / 2.0) + inner = add_cone( + bm, inner_loc, r_bot - wall_t, r_top - wall_t, depth - floor_t, + segments, mat_idx, cap_ends=False, + ) + ob = ring_verts(outer, z0) + ot = ring_verts(outer, z1) + ib = ring_verts(inner, z0 + floor_t) + it = ring_verts(inner, z1) + n = segments + for i in range(n): + j = (i + 1) % n + f = bm.faces.new((ot[i], ot[j], it[j], it[i])) + f.material_index = mat_idx + # Inner floor faces up into the hollow; outer bottom disc faces down. + ci = bm.verts.new((loc[0], loc[1], z0 + floor_t)) + co = bm.verts.new((loc[0], loc[1], z0)) + for i in range(n): + j = (i + 1) % n + f = bm.faces.new((ci, ib[i], ib[j])) + f.material_index = mat_idx + f = bm.faces.new((co, ob[j], ob[i])) + f.material_index = mat_idx + + def build_well_mesh(name, bevel_offset, bevel_segments): bm = bmesh.new() stone_verts = [] + wood_bevel_verts = [] try: - stone_w = 2.0 * R_MID * math.tan(math.pi / N_AROUND) * 0.88 - actual_h = STONE_H * 0.90 for row in range(N_ROWS): - z = actual_h / 2.0 + row * STONE_H + z = STONE_FACE_H / 2.0 + row * STONE_H rot_off = (row % 2) * (math.pi / N_AROUND) for i in range(N_AROUND): ang = 2.0 * math.pi * i / N_AROUND + rot_off - loc = (R_MID * math.cos(ang), R_MID * math.sin(ang), z) + # Seeded jitter: width and radial seat vary per stone, course + # tops stay level so the curb seats flat. + wj = 0.88 + 0.10 * (hash01(row, i, 0) - 0.5) + rj = (hash01(row, i, 1) - 0.5) * 0.008 + stone_w = 2.0 * R_MID * math.tan(math.pi / N_AROUND) * wj + loc = ( + (R_MID + rj) * math.cos(ang), + (R_MID + rj) * math.sin(ang), + z, + ) stone_verts.extend( add_box( bm, loc, - (STONE_D, stone_w, actual_h), + (STONE_D, stone_w, STONE_FACE_H), STONE_IDX, euler=(0.0, 0.0, ang), ) @@ -507,10 +593,9 @@

Source

curb_r = R_OUTER + CURB_OUT / 2.0 curb_w = 2.0 * curb_r * math.tan(math.pi / N_AROUND) * 0.90 - curb_z = WALL_H + CURB_H / 2.0 for i in range(N_AROUND): ang = 2.0 * math.pi * i / N_AROUND - loc = (curb_r * math.cos(ang), curb_r * math.sin(ang), curb_z) + loc = (curb_r * math.cos(ang), curb_r * math.sin(ang), CURB_Z) stone_verts.extend( add_box( bm, @@ -540,30 +625,44 @@

Source

POST_R * math.sin(ang), POST_BOTTOM + POST_H / 2.0, ) - add_box(bm, loc, (POST_S, POST_S, POST_H), WOOD_IDX) + wood_bevel_verts.extend( + add_box(bm, loc, (POST_S, POST_S, POST_H), WOOD_IDX) + ) beam_z = POST_TOP - 0.05 - add_box( - bm, - (0.0, 0.0, beam_z), - (POST_R * 2.0 - POST_S, POST_S * 0.85, POST_S * 0.85), - WOOD_IDX, + wood_bevel_verts.extend( + add_box( + bm, + (0.0, 0.0, beam_z), + (POST_R * 2.0 - POST_S, POST_S * 0.85, POST_S * 0.85), + WOOD_IDX, + ) ) add_cylinder( bm, (0.0, 0.0, beam_z), WINDLASS_R, - POST_R * 2.0 - POST_S * 1.4, + WINDLASS_LEN, 12, WOOD_IDX, euler=(0.0, math.pi / 2.0, 0.0), ) + # Crank: arm pinned to the protruding windlass end, grip parallel to + # the windlass axis at the arm's lower end. add_box( bm, - (POST_R - POST_S * 0.2, 0.0, beam_z), - (0.018, 0.12, 0.018), + (WINDLASS_END + 0.004, 0.0, beam_z - 0.055), + (0.020, 0.022, 0.13), METAL_IDX, - euler=(0.0, 0.0, math.radians(25.0)), + ) + add_cylinder( + bm, + (WINDLASS_END + 0.055, 0.0, beam_z - 0.12), + 0.014, + 0.10, + 10, + METAL_IDX, + euler=(0.0, math.pi / 2.0, 0.0), ) pitch = math.atan(ROOF_RISE / EAVE_HALF) @@ -578,6 +677,17 @@

Source

WOOD_IDX, euler=(0.0, 0.0, math.pi / 4.0), ) + # Cap the open pit where the four shingle courses meet at the peak. + add_cone( + bm, + (0.0, 0.0, PEAK_Z + 0.035), + 0.075, + 0.015, + 0.11, + 4, + WOOD_IDX, + euler=(0.0, 0.0, math.pi / 4.0), + ) nrm_local = Vector((0.0, ROOF_RISE, EAVE_HALF)).normalized() def add_course(yaw, t0, t1): @@ -623,27 +733,49 @@

Source

add_course(yaw, t0, t1) fascia_h = 0.045 fascia_t = 0.032 + # Butt joints: the X-running boards span the full eave; the Y-running + # boards embed 2 mm into them. An exact flush butt lands board end + # verts on the other board's corner verts (doubles at 1e-5). for side in range(4): yaw = side * (math.pi / 2.0) fx = EAVE_HALF * math.sin(yaw) fy = EAVE_HALF * math.cos(yaw) if side % 2 == 0: - add_box( - bm, - (0.0, fy, EAVE_Z - fascia_h / 2.0), - (2.0 * EAVE_HALF + fascia_t, fascia_t, fascia_h), - WOOD_IDX, + wood_bevel_verts.extend( + add_box( + bm, + (0.0, fy, EAVE_Z - fascia_h / 2.0), + (2.0 * EAVE_HALF + fascia_t, fascia_t, fascia_h), + WOOD_IDX, + ) ) else: - add_box( - bm, - (fx, 0.0, EAVE_Z - fascia_h / 2.0), - (fascia_t, 2.0 * EAVE_HALF + fascia_t, fascia_h), - WOOD_IDX, + wood_bevel_verts.extend( + add_box( + bm, + (fx, 0.0, EAVE_Z - fascia_h / 2.0), + (fascia_t, 2.0 * EAVE_HALF - fascia_t + 0.004, fascia_h), + WOOD_IDX, + ) ) + if bevel_offset > 0.0: + edges = list({e for v in wood_bevel_verts for e in v.link_edges}) + ret = bmesh.ops.bevel( + bm, + geom=edges, + offset=min(bevel_offset, 0.006), + segments=bevel_segments, + profile=0.5, + affect="EDGES", + clamp_overlap=True, + ) + for f in ret.get("faces") or []: + f.material_index = WOOD_IDX + + # Rope ties off at the bail handle bar, not mid-air above the bucket. rope_top = beam_z - WINDLASS_R - rope_bot = BUCKET_Z + BUCKET_H / 2.0 + rope_bot = HANDLE_BAR_Z rope_h = rope_top - rope_bot add_cylinder( bm, @@ -653,32 +785,42 @@

Source

8, WOOD_IDX, ) - add_cylinder(bm, (0.0, 0.0, BUCKET_Z), BUCKET_R, BUCKET_H, 12, WOOD_IDX) + add_open_bucket( + bm, + (0.0, 0.0, BUCKET_Z), + BUCKET_R_BOT, + BUCKET_R_TOP, + BUCKET_WALL_T, + BUCKET_H, + 12, + WOOD_IDX, + ) + + def bucket_r_at(z): + t = (z - (BUCKET_Z - BUCKET_H / 2.0)) / BUCKET_H + return BUCKET_R_BOT + t * (BUCKET_R_TOP - BUCKET_R_BOT) + for hz in (-BUCKET_H * 0.28, BUCKET_H * 0.28): add_cylinder( bm, (0.0, 0.0, BUCKET_Z + hz), - BUCKET_R + 0.008, + bucket_r_at(BUCKET_Z + hz) + 0.004, 0.018, 12, METAL_IDX, ) + # Bail handle: legs pinned to the outside of the rim, bar across. + for xs in (-1.0, 1.0): + add_box( + bm, + (xs * (BUCKET_R_TOP + 0.006), 0.0, BUCKET_RIM_Z - 0.015), + (0.014, 0.014, 0.09), + METAL_IDX, + ) add_box( bm, - (0.0, 0.0, BUCKET_Z + BUCKET_H / 2.0 + 0.04), - (BUCKET_R * 1.6, 0.014, 0.014), - METAL_IDX, - ) - add_box( - bm, - (-BUCKET_R * 0.72, 0.0, BUCKET_Z + BUCKET_H / 2.0 + 0.02), - (0.014, 0.014, 0.05), - METAL_IDX, - ) - add_box( - bm, - (BUCKET_R * 0.72, 0.0, BUCKET_Z + BUCKET_H / 2.0 + 0.02), - (0.014, 0.014, 0.05), + (0.0, 0.0, HANDLE_BAR_Z), + (2.0 * (BUCKET_R_TOP + 0.020), 0.014, 0.014), METAL_IDX, ) @@ -701,21 +843,48 @@

Source

return obj -def principled(name, color, metallic, roughness): +def principled(name, color, metallic, roughness, noise_scale=0.0, wear=None): mat = bpy.data.materials.new(name) mat.use_nodes = True - bsdf = mat.node_tree.nodes["Principled BSDF"] + nt = mat.node_tree + bsdf = nt.nodes["Principled BSDF"] bsdf.inputs["Base Color"].default_value = color bsdf.inputs["Metallic"].default_value = metallic bsdf.inputs["Roughness"].default_value = roughness + if noise_scale > 0.0 and wear is not None: + tex = nt.nodes.new("ShaderNodeTexNoise") + tex.inputs["Scale"].default_value = noise_scale + tex.inputs["Detail"].default_value = 8.0 + tex.inputs["Roughness"].default_value = 0.55 + mix = nt.nodes.new("ShaderNodeMix") + mix.data_type = "RGBA" + mix.inputs["A"].default_value = color + mix.inputs["B"].default_value = wear + fac = mix.inputs.get("Factor") or mix.inputs.get("Fac") + nt.links.new(tex.outputs["Fac"], fac) + nt.links.new(mix.outputs["Result"], bsdf.inputs["Base Color"]) + rmix = nt.nodes.new("ShaderNodeMix") + rmix.data_type = "FLOAT" + rmix.inputs["A"].default_value = roughness + rmix.inputs["B"].default_value = min(1.0, roughness + 0.18) + rfac = rmix.inputs.get("Factor") or rmix.inputs.get("Fac") + nt.links.new(tex.outputs["Fac"], rfac) + nt.links.new(rmix.outputs["Result"], bsdf.inputs["Roughness"]) return mat def assign_slots(obj, stone, wood, metal): - obj.data.materials.clear() - obj.data.materials.append(stone) - obj.data.materials.append(wood) - obj.data.materials.append(metal) + # Index-preserving: materials.clear() resets every polygon's + # material_index to 0 (the piece would render all-stone). Assign by + # slot position instead; the per-material face-count budgets in check() + # prove the indices survive. + mats = obj.data.materials + wanted = (stone, wood, metal) + for i, mat in enumerate(wanted): + if i < len(mats): + mats[i] = mat + else: + mats.append(mat) def world_bbox(obj): @@ -751,6 +920,84 @@

Source

return min(us), min(vs), max(us), max(vs), overlap, len(aabbs) +def face_area(me, poly): + vs = [me.vertices[i].co for i in poly.vertices] + if len(vs) < 3: + return 0.0 + v0 = vs[0] + area = 0.0 + for i in range(1, len(vs) - 1): + area += (vs[i] - v0).cross(vs[i + 1] - v0).length * 0.5 + return area + + +def hygiene_audit(me): + # Combinatorics match examples/mesh-hygiene-audit.audit (copied, not imported). + nv, ne, nf = len(me.vertices), len(me.edges), len(me.polygons) + ngons = sum(1 for p in me.polygons if len(p.vertices) > 4) + areas = [face_area(me, p) for p in me.polygons] + zero_area = sum(1 for a in areas if a <= AREA_EPS) + bm = bmesh.new() + try: + bm.from_mesh(me) + bm.verts.ensure_lookup_table() + bm.edges.ensure_lookup_table() + loose_v = sum(1 for v in bm.verts if len(v.link_edges) == 0) + loose_e = sum(1 for e in bm.edges if len(e.link_faces) == 0) + nonman = sum(1 for e in bm.edges if not e.is_manifold) + ret = bmesh.ops.find_doubles(bm, verts=list(bm.verts), dist=DOUBLES_EPS) + doubles = len(ret.get("targetmap") or {}) + finally: + bm.free() + return { + "nv": nv, + "ne": ne, + "nf": nf, + "ngons": ngons, + "loose_v": loose_v, + "loose_e": loose_e, + "nonman": nonman, + "zero_area": zero_area, + "doubles": doubles, + "euler": nv - ne + nf, + } + + +def min_mat_distance(me, ia, ib): + """Closest surface distance between two material islands via BVH. + + Vert-vert distance is the wrong metric for thin parts: a face interior + can touch while its corner verts sit a radius apart. + """ + bm_a = bmesh.new() + bm_b = bmesh.new() + try: + bm_a.from_mesh(me) + bm_b.from_mesh(me) + bm_a.faces.ensure_lookup_table() + bm_b.faces.ensure_lookup_table() + drop_a = [f for f in bm_a.faces if f.material_index != ia] + drop_b = [f for f in bm_b.faces if f.material_index != ib] + if drop_a: + bmesh.ops.delete(bm_a, geom=drop_a, context="FACES") + if drop_b: + bmesh.ops.delete(bm_b, geom=drop_b, context="FACES") + if not bm_a.faces or not bm_b.faces: + return 1e9 + tree = BVHTree.FromBMesh(bm_b) + best = 1e9 + for src in list(bm_a.verts) + list(bm_a.faces): + co = src.co if hasattr(src, "co") else src.calc_center_median() + hit = tree.find_nearest(co) + if hit[0] is None: + continue + best = min(best, hit[3]) + return best + finally: + bm_a.free() + bm_b.free() + + def make_lod(obj, name, ratio, skip_decimate): mesh = obj.data.copy() lod = bpy.data.objects.new(name, mesh) @@ -843,15 +1090,28 @@

Source

) -def check(skip_decimate): +def check(skip_decimate, lift_z=False): bpy.ops.wm.read_factory_settings(use_empty=True) low = build_well_mesh("WellLow", bevel_offset=0.010, bevel_segments=2) high = build_well_mesh("WellHigh", bevel_offset=0.010, bevel_segments=4) - stone = principled("WellStone", (0.40, 0.42, 0.46, 1.0), 0.0, 0.84) - wood = principled("WellWood", (0.48, 0.22, 0.07, 1.0), 0.0, 0.50) - metal = principled("WellMetal", (0.62, 0.58, 0.48, 1.0), 1.0, 0.25) + stone = principled( + "WellStone", (0.40, 0.42, 0.46, 1.0), 0.0, 0.84, + noise_scale=9.0, wear=(0.29, 0.30, 0.33, 1.0), + ) + wood = principled( + "WellWood", (0.48, 0.22, 0.07, 1.0), 0.0, 0.50, + noise_scale=7.0, wear=(0.30, 0.13, 0.04, 1.0), + ) + metal = principled( + "WellMetal", (0.62, 0.58, 0.48, 1.0), 1.0, 0.30, + noise_scale=5.0, wear=(0.34, 0.32, 0.27, 1.0), + ) assign_slots(low, stone, wood, metal) assign_slots(high, stone, wood, metal) + if lift_z: + for v in low.data.vertices: + v.co.z += LIFT_Z + low.data.update() if low.data is None or len(low.data.polygons) < 6: return fail("well mesh did not build", 3), None, None, None, None, None @@ -860,6 +1120,10 @@

Source

mats = [s for s in low.data.materials if s is not None] nmat = len(mats) distinct_mats = len({id(s) for s in mats}) + idx_counts = {} + for poly in low.data.polygons: + idx_counts[poly.material_index] = idx_counts.get(poly.material_index, 0) + 1 + print(f"measured mat_index_counts={idx_counts}") u0, v0, u1, v1, overlap, nfaces = uv_stats(low.data) bb = world_bbox(low) size_x = bb[3] - bb[0] @@ -910,6 +1174,15 @@

Source

f"measured collider_tris={col_tris} bake={bake_result} " f"bake_has_data={img.has_data} export_bytes={export_size}" ) + hyg = hygiene_audit(low.data) + gap_sw = min_mat_distance(low.data, STONE_IDX, WOOD_IDX) + gap_mw = min_mat_distance(low.data, METAL_IDX, WOOD_IDX) + print( + f"measured hygiene loose_v={hyg['loose_v']} loose_e={hyg['loose_e']} " + f"nonman={hyg['nonman']} zero_area={hyg['zero_area']} " + f"doubles={hyg['doubles']} ngons={hyg['ngons']} euler={hyg['euler']}" + ) + print(f"measured gap_stone_wood={gap_sw:.5f} gap_metal_wood={gap_mw:.5f}") if not (BASE_TRIS_MIN <= base_tris <= BASE_TRIS_MAX): return fail( @@ -921,6 +1194,21 @@

Source

f"material slots {nmat} distinct {distinct_mats} != {MATERIAL_COUNT}", 5, ), None, None, None, None, None + if idx_counts.get(STONE_IDX, 0) < STONE_FACES_MIN: + return fail( + f"stone faces {idx_counts.get(STONE_IDX, 0)} < {STONE_FACES_MIN}", + 5, + ), None, None, None, None, None + if idx_counts.get(WOOD_IDX, 0) < WOOD_FACES_MIN: + return fail( + f"wood faces {idx_counts.get(WOOD_IDX, 0)} < {WOOD_FACES_MIN}", + 5, + ), None, None, None, None, None + if idx_counts.get(METAL_IDX, 0) < METAL_FACES_MIN: + return fail( + f"metal faces {idx_counts.get(METAL_IDX, 0)} < {METAL_FACES_MIN}", + 5, + ), None, None, None, None, None if u0 < -UV_EPS or v0 < -UV_EPS or u1 > 1.0 + UV_EPS or v1 > 1.0 + UV_EPS: return fail( f"UVs outside 0..1: ({u0:.4f},{v0:.4f})-({u1:.4f},{v1:.4f})", @@ -964,6 +1252,38 @@

Source

), None, None, None, None, None if export_size <= 0: return fail("export file missing or empty", 13), None, None, None, None, None + if ( + hyg["loose_v"] + or hyg["loose_e"] + or hyg["nonman"] + or hyg["zero_area"] + or hyg["doubles"] + or hyg["ngons"] + ): + return fail( + f"hygiene loose_v={hyg['loose_v']} loose_e={hyg['loose_e']} " + f"nonman={hyg['nonman']} zero_area={hyg['zero_area']} " + f"doubles={hyg['doubles']} ngons={hyg['ngons']}", + 15, + ), None, None, None, None, None + if abs(bb[2]) > ZMIN_EPS: + return fail( + f"zmin {bb[2]:.6f} not within {ZMIN_EPS} of 0 " + "(--lift-z is the designed fail)", + 16, + ), None, None, None, None, None + if gap_sw > GAP_MAX: + return fail( + f"stone-wood gap {gap_sw:.5f} > {GAP_MAX} " + "(posts must seat on the curb)", + 17, + ), None, None, None, None, None + if gap_mw > GAP_MAX: + return fail( + f"metal-wood gap {gap_mw:.5f} > {GAP_MAX} " + "(crank, hoops, and bail must touch the wood they mount to)", + 17, + ), None, None, None, None, None return 0, low, high, stone, tex, collider @@ -1034,7 +1354,7 @@

Source

cam.location = (3.10, -4.45, 2.12) scene.collection.objects.link(cam) aim = bpy.data.objects.new("Aim", None) - aim.location = (0.0, 0.0, OUTER_SIZE[2] / 2.0 + 0.04) + aim.location = (0.0, 0.0, OUTER_SIZE[2] / 2.0) scene.collection.objects.link(aim) con = cam.constraints.new("TRACK_TO") con.target = aim @@ -1082,9 +1402,16 @@

Source

action="store_true", help="falsification: skip the LOD DECIMATE stage", ) + p.add_argument( + "--lift-z", + action="store_true", + help="falsification: lift the mesh so zmin fails the grounded budget", + ) args = p.parse_args(argv) - code, low, _high, stone, tex, _col = check(args.skip_decimate) + code, low, _high, stone, tex, _col = check( + args.skip_decimate, lift_z=args.lift_z + ) if code: return code if args.output: diff --git a/showcase/stone-well/README.md b/showcase/stone-well/README.md index 189421d..c951bc2 100644 --- a/showcase/stone-well/README.md +++ b/showcase/stone-well/README.md @@ -21,14 +21,18 @@ materials, UVs, evaluated LOD, collider, or export file. | Axis | Declared | Measured (4.5.11 / 5.1.2 / 5.2.1) | | --- | --- | --- | -| Base triangles | 8280–8500 | 8388 / 8388 / 8388 | +| Base triangles | 8280–9500 | 9380 / 9380 / 9380 | | 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 | 3 | +| Material faces | stone ≥ 3000, wood ≥ 600, metal ≥ 100 | all above | | UVs | in `0..1`, AABB overlap ≤ 1e-5 | in range, overlap 0 | -| Outer AABB | (1.640, 1.640, 1.688) m ± 0.01 | (1.6400, 1.6400, 1.6882), zmin 0 | -| Collider tris | ≤ 260 | 230 | -| Export | written, size > 0 | 601028 / 601092 / 601372 bytes | +| Outer AABB | (1.640, 1.640, 1.761) m ± 0.01 | (1.6400, 1.6400, 1.7606) | +| Grounded | bbox min Z within 1e-4 of 0 | 0.0000 / 0.0000 / 0.0000 | +| Hygiene | loose V/E, non-manifold, zero-area, doubles @1e-5, n-gons: all 0 | 0 / 0 / 0 on every axis | +| Material-island gap | stone↔wood and metal↔wood min distance ≤ 0.008 m | 0.00000 / 0.00000 / 0.00000 | +| Collider tris | ≤ 320 | 306 | +| Export | written, size > 0 | 686672 / 686736 / 686724 bytes | DECIMATE COLLAPSE triangle counts are **not** guaranteed identical across series — the gate is a ratio band, not an exact count. This mesh happened @@ -37,17 +41,20 @@ is `has_data` plus operator `FINISHED`, not byte-identity. Construction uses no RNG. glTF byte size differs by a few hundred bytes across series. `--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. +exit 9 fires. `--lift-z` raises the finished mesh 0.05 m so the grounded +budget fails and exit 16 fires. Those are the named budgets the two +falsifiers violate. ## Run ```bash blender --background --python stone_well.py -- blender --background --python stone_well.py -- --skip-decimate +blender --background --python stone_well.py -- --lift-z blender --background --python stone_well.py -- --output well.png ``` -Smoke does not pass `--output` or `--skip-decimate`. +Smoke does not pass `--output`, `--skip-decimate`, or `--lift-z`. ## Exit codes @@ -61,7 +68,7 @@ File-local. `9` is a valid check code. `10` is reserved for | 2 | argparse / usage | | 3 | Mesh did not build / no UV layer | | 4 | Base triangle count outside range | -| 5 | Material count ≠ 3 distinct slots | +| 5 | Material count ≠ 3 distinct slots, or a material face floor missed | | 6 | UVs outside 0..1 | | 7 | UV AABB overlap above tolerance | | 8 | World AABB off declared outer size | @@ -71,3 +78,6 @@ 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: loose geometry, non-manifold, zero-area, doubles, or n-gons | +| 16 | Bbox min Z not grounded (`--lift-z` lands here) | +| 17 | Material-island gap above tolerance (parts meant to touch) | diff --git a/showcase/stone-well/preview.webp b/showcase/stone-well/preview.webp index 62ae041558eae2b33ffa538b8877bc2fb01b0d91..da5018941da7294e43f85a4d348c14168deee3d8 100644 GIT binary patch literal 30904 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 z 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 0.0: + edges = list({e for v in wood_bevel_verts for e in v.link_edges}) + ret = bmesh.ops.bevel( + bm, + geom=edges, + offset=min(bevel_offset, 0.006), + segments=bevel_segments, + profile=0.5, + affect="EDGES", + clamp_overlap=True, + ) + for f in ret.get("faces") or []: + f.material_index = WOOD_IDX + + # Rope ties off at the bail handle bar, not mid-air above the bucket. rope_top = beam_z - WINDLASS_R - rope_bot = BUCKET_Z + BUCKET_H / 2.0 + rope_bot = HANDLE_BAR_Z rope_h = rope_top - rope_bot add_cylinder( bm, @@ -369,32 +500,42 @@ def pt(t, s): 8, WOOD_IDX, ) - add_cylinder(bm, (0.0, 0.0, BUCKET_Z), BUCKET_R, BUCKET_H, 12, WOOD_IDX) + add_open_bucket( + bm, + (0.0, 0.0, BUCKET_Z), + BUCKET_R_BOT, + BUCKET_R_TOP, + BUCKET_WALL_T, + BUCKET_H, + 12, + WOOD_IDX, + ) + + def bucket_r_at(z): + t = (z - (BUCKET_Z - BUCKET_H / 2.0)) / BUCKET_H + return BUCKET_R_BOT + t * (BUCKET_R_TOP - BUCKET_R_BOT) + for hz in (-BUCKET_H * 0.28, BUCKET_H * 0.28): add_cylinder( bm, (0.0, 0.0, BUCKET_Z + hz), - BUCKET_R + 0.008, + bucket_r_at(BUCKET_Z + hz) + 0.004, 0.018, 12, METAL_IDX, ) + # Bail handle: legs pinned to the outside of the rim, bar across. + for xs in (-1.0, 1.0): + add_box( + bm, + (xs * (BUCKET_R_TOP + 0.006), 0.0, BUCKET_RIM_Z - 0.015), + (0.014, 0.014, 0.09), + METAL_IDX, + ) add_box( bm, - (0.0, 0.0, BUCKET_Z + BUCKET_H / 2.0 + 0.04), - (BUCKET_R * 1.6, 0.014, 0.014), - METAL_IDX, - ) - add_box( - bm, - (-BUCKET_R * 0.72, 0.0, BUCKET_Z + BUCKET_H / 2.0 + 0.02), - (0.014, 0.014, 0.05), - METAL_IDX, - ) - add_box( - bm, - (BUCKET_R * 0.72, 0.0, BUCKET_Z + BUCKET_H / 2.0 + 0.02), - (0.014, 0.014, 0.05), + (0.0, 0.0, HANDLE_BAR_Z), + (2.0 * (BUCKET_R_TOP + 0.020), 0.014, 0.014), METAL_IDX, ) @@ -417,21 +558,48 @@ def pt(t, s): return obj -def principled(name, color, metallic, roughness): +def principled(name, color, metallic, roughness, noise_scale=0.0, wear=None): mat = bpy.data.materials.new(name) mat.use_nodes = True - bsdf = mat.node_tree.nodes["Principled BSDF"] + nt = mat.node_tree + bsdf = nt.nodes["Principled BSDF"] bsdf.inputs["Base Color"].default_value = color bsdf.inputs["Metallic"].default_value = metallic bsdf.inputs["Roughness"].default_value = roughness + if noise_scale > 0.0 and wear is not None: + tex = nt.nodes.new("ShaderNodeTexNoise") + tex.inputs["Scale"].default_value = noise_scale + tex.inputs["Detail"].default_value = 8.0 + tex.inputs["Roughness"].default_value = 0.55 + mix = nt.nodes.new("ShaderNodeMix") + mix.data_type = "RGBA" + mix.inputs["A"].default_value = color + mix.inputs["B"].default_value = wear + fac = mix.inputs.get("Factor") or mix.inputs.get("Fac") + nt.links.new(tex.outputs["Fac"], fac) + nt.links.new(mix.outputs["Result"], bsdf.inputs["Base Color"]) + rmix = nt.nodes.new("ShaderNodeMix") + rmix.data_type = "FLOAT" + rmix.inputs["A"].default_value = roughness + rmix.inputs["B"].default_value = min(1.0, roughness + 0.18) + rfac = rmix.inputs.get("Factor") or rmix.inputs.get("Fac") + nt.links.new(tex.outputs["Fac"], rfac) + nt.links.new(rmix.outputs["Result"], bsdf.inputs["Roughness"]) return mat def assign_slots(obj, stone, wood, metal): - obj.data.materials.clear() - obj.data.materials.append(stone) - obj.data.materials.append(wood) - obj.data.materials.append(metal) + # Index-preserving: materials.clear() resets every polygon's + # material_index to 0 (the piece would render all-stone). Assign by + # slot position instead; the per-material face-count budgets in check() + # prove the indices survive. + mats = obj.data.materials + wanted = (stone, wood, metal) + for i, mat in enumerate(wanted): + if i < len(mats): + mats[i] = mat + else: + mats.append(mat) def world_bbox(obj): @@ -467,6 +635,84 @@ def uv_stats(mesh): return min(us), min(vs), max(us), max(vs), overlap, len(aabbs) +def face_area(me, poly): + vs = [me.vertices[i].co for i in poly.vertices] + if len(vs) < 3: + return 0.0 + v0 = vs[0] + area = 0.0 + for i in range(1, len(vs) - 1): + area += (vs[i] - v0).cross(vs[i + 1] - v0).length * 0.5 + return area + + +def hygiene_audit(me): + # Combinatorics match examples/mesh-hygiene-audit.audit (copied, not imported). + nv, ne, nf = len(me.vertices), len(me.edges), len(me.polygons) + ngons = sum(1 for p in me.polygons if len(p.vertices) > 4) + areas = [face_area(me, p) for p in me.polygons] + zero_area = sum(1 for a in areas if a <= AREA_EPS) + bm = bmesh.new() + try: + bm.from_mesh(me) + bm.verts.ensure_lookup_table() + bm.edges.ensure_lookup_table() + loose_v = sum(1 for v in bm.verts if len(v.link_edges) == 0) + loose_e = sum(1 for e in bm.edges if len(e.link_faces) == 0) + nonman = sum(1 for e in bm.edges if not e.is_manifold) + ret = bmesh.ops.find_doubles(bm, verts=list(bm.verts), dist=DOUBLES_EPS) + doubles = len(ret.get("targetmap") or {}) + finally: + bm.free() + return { + "nv": nv, + "ne": ne, + "nf": nf, + "ngons": ngons, + "loose_v": loose_v, + "loose_e": loose_e, + "nonman": nonman, + "zero_area": zero_area, + "doubles": doubles, + "euler": nv - ne + nf, + } + + +def min_mat_distance(me, ia, ib): + """Closest surface distance between two material islands via BVH. + + Vert-vert distance is the wrong metric for thin parts: a face interior + can touch while its corner verts sit a radius apart. + """ + bm_a = bmesh.new() + bm_b = bmesh.new() + try: + bm_a.from_mesh(me) + bm_b.from_mesh(me) + bm_a.faces.ensure_lookup_table() + bm_b.faces.ensure_lookup_table() + drop_a = [f for f in bm_a.faces if f.material_index != ia] + drop_b = [f for f in bm_b.faces if f.material_index != ib] + if drop_a: + bmesh.ops.delete(bm_a, geom=drop_a, context="FACES") + if drop_b: + bmesh.ops.delete(bm_b, geom=drop_b, context="FACES") + if not bm_a.faces or not bm_b.faces: + return 1e9 + tree = BVHTree.FromBMesh(bm_b) + best = 1e9 + for src in list(bm_a.verts) + list(bm_a.faces): + co = src.co if hasattr(src, "co") else src.calc_center_median() + hit = tree.find_nearest(co) + if hit[0] is None: + continue + best = min(best, hit[3]) + return best + finally: + bm_a.free() + bm_b.free() + + def make_lod(obj, name, ratio, skip_decimate): mesh = obj.data.copy() lod = bpy.data.objects.new(name, mesh) @@ -559,15 +805,28 @@ def export_unity(path, objects): ) -def check(skip_decimate): +def check(skip_decimate, lift_z=False): bpy.ops.wm.read_factory_settings(use_empty=True) low = build_well_mesh("WellLow", bevel_offset=0.010, bevel_segments=2) high = build_well_mesh("WellHigh", bevel_offset=0.010, bevel_segments=4) - stone = principled("WellStone", (0.40, 0.42, 0.46, 1.0), 0.0, 0.84) - wood = principled("WellWood", (0.48, 0.22, 0.07, 1.0), 0.0, 0.50) - metal = principled("WellMetal", (0.62, 0.58, 0.48, 1.0), 1.0, 0.25) + stone = principled( + "WellStone", (0.40, 0.42, 0.46, 1.0), 0.0, 0.84, + noise_scale=9.0, wear=(0.29, 0.30, 0.33, 1.0), + ) + wood = principled( + "WellWood", (0.48, 0.22, 0.07, 1.0), 0.0, 0.50, + noise_scale=7.0, wear=(0.30, 0.13, 0.04, 1.0), + ) + metal = principled( + "WellMetal", (0.62, 0.58, 0.48, 1.0), 1.0, 0.30, + noise_scale=5.0, wear=(0.34, 0.32, 0.27, 1.0), + ) assign_slots(low, stone, wood, metal) assign_slots(high, stone, wood, metal) + if lift_z: + for v in low.data.vertices: + v.co.z += LIFT_Z + low.data.update() if low.data is None or len(low.data.polygons) < 6: return fail("well mesh did not build", 3), None, None, None, None, None @@ -576,6 +835,10 @@ def check(skip_decimate): mats = [s for s in low.data.materials if s is not None] nmat = len(mats) distinct_mats = len({id(s) for s in mats}) + idx_counts = {} + for poly in low.data.polygons: + idx_counts[poly.material_index] = idx_counts.get(poly.material_index, 0) + 1 + print(f"measured mat_index_counts={idx_counts}") u0, v0, u1, v1, overlap, nfaces = uv_stats(low.data) bb = world_bbox(low) size_x = bb[3] - bb[0] @@ -626,6 +889,15 @@ def check(skip_decimate): f"measured collider_tris={col_tris} bake={bake_result} " f"bake_has_data={img.has_data} export_bytes={export_size}" ) + hyg = hygiene_audit(low.data) + gap_sw = min_mat_distance(low.data, STONE_IDX, WOOD_IDX) + gap_mw = min_mat_distance(low.data, METAL_IDX, WOOD_IDX) + print( + f"measured hygiene loose_v={hyg['loose_v']} loose_e={hyg['loose_e']} " + f"nonman={hyg['nonman']} zero_area={hyg['zero_area']} " + f"doubles={hyg['doubles']} ngons={hyg['ngons']} euler={hyg['euler']}" + ) + print(f"measured gap_stone_wood={gap_sw:.5f} gap_metal_wood={gap_mw:.5f}") if not (BASE_TRIS_MIN <= base_tris <= BASE_TRIS_MAX): return fail( @@ -637,6 +909,21 @@ def check(skip_decimate): f"material slots {nmat} distinct {distinct_mats} != {MATERIAL_COUNT}", 5, ), None, None, None, None, None + if idx_counts.get(STONE_IDX, 0) < STONE_FACES_MIN: + return fail( + f"stone faces {idx_counts.get(STONE_IDX, 0)} < {STONE_FACES_MIN}", + 5, + ), None, None, None, None, None + if idx_counts.get(WOOD_IDX, 0) < WOOD_FACES_MIN: + return fail( + f"wood faces {idx_counts.get(WOOD_IDX, 0)} < {WOOD_FACES_MIN}", + 5, + ), None, None, None, None, None + if idx_counts.get(METAL_IDX, 0) < METAL_FACES_MIN: + return fail( + f"metal faces {idx_counts.get(METAL_IDX, 0)} < {METAL_FACES_MIN}", + 5, + ), None, None, None, None, None if u0 < -UV_EPS or v0 < -UV_EPS or u1 > 1.0 + UV_EPS or v1 > 1.0 + UV_EPS: return fail( f"UVs outside 0..1: ({u0:.4f},{v0:.4f})-({u1:.4f},{v1:.4f})", @@ -680,6 +967,38 @@ def check(skip_decimate): ), None, None, None, None, None if export_size <= 0: return fail("export file missing or empty", 13), None, None, None, None, None + if ( + hyg["loose_v"] + or hyg["loose_e"] + or hyg["nonman"] + or hyg["zero_area"] + or hyg["doubles"] + or hyg["ngons"] + ): + return fail( + f"hygiene loose_v={hyg['loose_v']} loose_e={hyg['loose_e']} " + f"nonman={hyg['nonman']} zero_area={hyg['zero_area']} " + f"doubles={hyg['doubles']} ngons={hyg['ngons']}", + 15, + ), None, None, None, None, None + if abs(bb[2]) > ZMIN_EPS: + return fail( + f"zmin {bb[2]:.6f} not within {ZMIN_EPS} of 0 " + "(--lift-z is the designed fail)", + 16, + ), None, None, None, None, None + if gap_sw > GAP_MAX: + return fail( + f"stone-wood gap {gap_sw:.5f} > {GAP_MAX} " + "(posts must seat on the curb)", + 17, + ), None, None, None, None, None + if gap_mw > GAP_MAX: + return fail( + f"metal-wood gap {gap_mw:.5f} > {GAP_MAX} " + "(crank, hoops, and bail must touch the wood they mount to)", + 17, + ), None, None, None, None, None return 0, low, high, stone, tex, collider @@ -750,7 +1069,7 @@ def light(name, loc, energy, size, col, rot): cam.location = (3.10, -4.45, 2.12) scene.collection.objects.link(cam) aim = bpy.data.objects.new("Aim", None) - aim.location = (0.0, 0.0, OUTER_SIZE[2] / 2.0 + 0.04) + aim.location = (0.0, 0.0, OUTER_SIZE[2] / 2.0) scene.collection.objects.link(aim) con = cam.constraints.new("TRACK_TO") con.target = aim @@ -798,9 +1117,16 @@ def main(): action="store_true", help="falsification: skip the LOD DECIMATE stage", ) + p.add_argument( + "--lift-z", + action="store_true", + help="falsification: lift the mesh so zmin fails the grounded budget", + ) args = p.parse_args(argv) - code, low, _high, stone, tex, _col = check(args.skip_decimate) + code, low, _high, stone, tex, _col = check( + args.skip_decimate, lift_z=args.lift_z + ) if code: return code if args.output: From a9b38a2ddb9ef248fa76b177534364952498bfd0 Mon Sep 17 00:00:00 2001 From: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Date: Tue, 15 Sep 2026 21:21:23 -0400 Subject: [PATCH 2/3] fix: rebuild cart so the axle carries the bed and the wheels read Quality pass on the cart generator after an inspection-sheet review found the axle interpenetrating the bed floor, shafts poking through the bed, corner plates buried inside the wall corners, shaft straps floating off the bed, inconsistent wall heights, torus-profile wheels with round pipe treads, and spokes floating at both ends. Structural fixes in the generator: bed Z derived from the axle top via real bolster beams, shafts dropped to run beside the bed edge and angle down, corner plates moved onto the bed top, straps aligned to the bed bottom, a lower tailgate, flat-tread felloes and iron tyres built as rings, spokes embedded at hub and felloe. Noise/wear on both materials, cap_tris everywhere to kill n-gons. New budgets: hygiene (loose/non-manifold/zero-area/doubles/ngons all zero, exit 15), grounded zmin (exit 16, --lift-z falsifier), BVH metal-wood gap (exit 17), wood face floor (exit 5). Hero re-rendered; framing gate passes. Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Cursor --- docs/gallery/assets/cart-hero.webp | Bin 47524 -> 25924 bytes docs/gallery/cart/index.html | 324 +++++++++++++++++++++++------ showcase/cart/README.md | 25 ++- showcase/cart/cart.py | 313 +++++++++++++++++++++++----- showcase/cart/preview.webp | Bin 19774 -> 25924 bytes 5 files changed, 543 insertions(+), 119 deletions(-) diff --git a/docs/gallery/assets/cart-hero.webp b/docs/gallery/assets/cart-hero.webp index 891b2756d5ea41dbb61357f19611587dbccbca0b..33e7fcfe604a40c6c36556cb7934e59adda4dc6f 100644 GIT binary patch literal 25924 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 literal 47524 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 QqFAP0TTi_a6<7cO07AtzLjV8( diff --git a/docs/gallery/cart/index.html b/docs/gallery/cart/index.html index 2441c4b..a097213 100644 --- a/docs/gallery/cart/index.html +++ b/docs/gallery/cart/index.html @@ -253,7 +253,7 @@

cart

cart render

Rendered headless by the example itself — click to zoom.

-
witnesses Recomputed: 2572 tris, two materials with 100 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.547×0.749×0.656 m, LOD ratios in band, convex collider 306 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.
+
witnesses Recomputed: 2600 tris, two materials with metal and wood face floors, UVs in 0..1 with zero AABB overlap, outer AABB 1.539×0.749×0.640 m, LOD ratios in band, convex collider 122 tris, hygiene zero (loose, non-manifold, doubles, n-gons), grounded zmin, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget; --lift-z exits 16 on the grounded budget.
blender --background --python showcase/cart/cart.py --
@@ -264,17 +264,18 @@

cart

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.

-

| Axis | Declared | Measured (4.5.11 / 5.1.2 / 5.2.1) | | --- | --- | --- | | Base triangles | 2470–2680 | 2572 / 2572 / 2572 | | LOD1 ratio | 0.32–0.62 of base | 0.5000 / 0.5000 / 0.5000 | | LOD2 ratio | 0.10–0.35 of base | 0.2193 / 0.2193 / 0.2146 | | Materials | exactly 2 distinct, ≥24 metal faces | 2 slots, 100 metal | | UVs | in 0..1, AABB overlap ≤ 1e-5 | in range, overlap 0 | | Outer AABB | (1.547, 0.749, 0.656) m ± 0.01 | (1.5473, 0.7486, 0.6560), zmin 0 | | Collider tris | ≤ 360 | 306 | | Export | written, size > 0 | 202500 / 202500 / 202492 bytes |

+

| Axis | Declared | Measured (4.5.11 / 5.1.2 / 5.2.1) | | --- | --- | --- | | Base triangles | 2470–2900 | 2600 / 2600 / 2600 | | LOD1 ratio | 0.32–0.62 of base | 0.5000 / 0.5000 / 0.5000 | | LOD2 ratio | 0.10–0.35 of base | 0.2200 / 0.2200 / 0.2154 | | Materials | exactly 2 distinct, metal ≥ 24, wood ≥ 800 faces | 2 slots, floors met | | UVs | in 0..1, AABB overlap ≤ 1e-5 | in range, overlap 0 | | Outer AABB | (1.539, 0.749, 0.640) m ± 0.01 | (1.5393, 0.7486, 0.6400) | | Grounded | bbox min Z within 1e-4 of 0 | 0.0000 / 0.0000 / 0.0000 | | Hygiene | loose V/E, non-manifold, zero-area, doubles @1e-5, n-gons: all 0 | 0 / 0 / 0 on every axis | | Material-island gap | metal↔wood min distance ≤ 0.008 m | 0.00000 / 0.00000 / 0.00000 | | Collider tris | ≤ 360 | 122 | | Export | written, size > 0 | 201048 / 201048 / 201032 bytes |

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 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 8 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.

+

--skip-decimate skips the LOD DECIMATE stage so LOD1 ratio is 1.0 and exit 9 fires. --lift-z raises the finished mesh 0.05 m so the grounded budget fails and exit 16 fires. Those are the named budgets the two falsifiers violate.

Run

blender --background --python cart.py --
 blender --background --python cart.py -- --skip-decimate
+blender --background --python cart.py -- --lift-z
 blender --background --python cart.py -- --output cart.png
-

Smoke does not pass --output or --skip-decimate.

+

Smoke does not pass --output, --skip-decimate, or --lift-z.

Exit codes

File-local. 9 is a valid check code. 10 is reserved for gallery_framing.check_framing on the --output path.

-

| Code | Meaning | | --- | --- | | 0 | Success | | 1 | Uncaught exception (FATAL wrapper) | | 2 | argparse / usage | | 3 | Mesh did not build / no UV layer | | 4 | Base triangle count outside range | | 5 | Material count ≠ 2 distinct slots, or metal faces missing | | 6 | UVs outside 0..1 | | 7 | UV AABB overlap above tolerance | | 8 | World AABB off declared outer size | | 9 | LOD ratio band (--skip-decimate lands here) | | 10 | Framing gate (render path only) | | 11 | Collider triangle count above ceiling | | 12 | Bake did not finish or image has no data | | 13 | Export file missing or empty | | 14 | --output produced no file |

+

| Code | Meaning | | --- | --- | | 0 | Success | | 1 | Uncaught exception (FATAL wrapper) | | 2 | argparse / usage | | 3 | Mesh did not build / no UV layer | | 4 | Base triangle count outside range | | 5 | Material count ≠ 2 distinct slots, or metal faces missing | | 6 | UVs outside 0..1 | | 7 | UV AABB overlap above tolerance | | 8 | World AABB off declared outer size | | 9 | LOD ratio band (--skip-decimate lands here) | | 10 | Framing gate (render path only) | | 11 | Collider triangle count above ceiling | | 12 | Bake did not finish or image has no data | | 13 | Export file missing or empty | | 14 | --output produced no file | | 15 | Hygiene: loose geometry, non-manifold, zero-area, doubles, or n-gons | | 16 | Bbox min Z not grounded (--lift-z lands here) | | 17 | Material-island gap above tolerance (parts meant to touch) |

Source

@@ -292,7 +293,8 @@

Source

Budgets are declared below and recomputed from the generated result. They are not API-contract witnesses. ``--skip-decimate`` skips the LOD -DECIMATE stage so the LOD-ratio budget fails. +DECIMATE stage so the LOD-ratio budget fails. ``--lift-z`` raises the +mesh so the grounded-zmin hygiene budget fails. No RNG. Construction is closed-form. DECIMATE COLLAPSE triangle counts are not byte-identical across Blender versions — the LOD gate is a @@ -300,6 +302,7 @@

Source

blender --background --python cart.py -- blender --background --python cart.py -- --skip-decimate + blender --background --python cart.py -- --lift-z blender --background --python cart.py -- --output cart.png """ import argparse @@ -312,6 +315,7 @@

Source

import bmesh import bpy from mathutils import Euler, Vector +from mathutils.bvhtree import BVHTree _REPO = os.path.abspath( os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir, os.pardir) @@ -321,9 +325,15 @@

Source

import gallery_framing # noqa: E402 RIM_MAJOR = 0.30 -RIM_MINOR = 0.028 +# Felloe ring: flat-tread box section, not a round tube — round torus rims +# read as bicycle wheels. The iron tyre wraps the tread. +RIM_RADIAL = 0.012 +RIM_W = 0.036 +TYRE_T = 0.008 +TYRE_W = 0.040 TRACK = 0.68 AXLE_X = -0.16 +AXLE_R = 0.020 HUB_R = 0.052 HUB_W = 0.046 N_SPOKES = 8 @@ -333,15 +343,23 @@

Source

BED_T = 0.038 WALL_H = 0.16 WALL_T = 0.032 +TAILGATE_H = 0.10 SHAFT_L = 0.58 SHAFT_T = 0.034 +SHAFT_PITCH = math.radians(7.0) N_SLATS = 6 IRON_T = 0.014 +BOLSTER_H = 0.044 BBOX_TOL = 0.01 -OUTER_SIZE = (1.547, 0.749, 0.656) +OUTER_SIZE = (1.539, 0.749, 0.640) BASE_TRIS_MIN = 2470 -BASE_TRIS_MAX = 2680 +BASE_TRIS_MAX = 2900 +ZMIN_EPS = 1e-4 +DOUBLES_EPS = 1e-5 +AREA_EPS = 1e-10 +GAP_MAX = 0.008 +LIFT_Z = 0.05 LOD1_RATIO_MIN = 0.32 LOD1_RATIO_MAX = 0.62 LOD2_RATIO_MIN = 0.10 @@ -355,6 +373,7 @@

Source

BAKE_RES = 256 CAGE_EXTRUSION = 0.08 METAL_FACES_MIN = 24 +WOOD_FACES_MIN = 800 WOOD_IDX = 0 METAL_IDX = 1 @@ -410,7 +429,7 @@

Source

geo = bmesh.ops.create_cone( bm, cap_ends=True, - cap_tris=False, + cap_tris=True, segments=segments, radius1=radius, radius2=radius, @@ -427,28 +446,39 @@

Source

return verts -def add_rim(bm, loc, major, minor, mat_idx, euler=(0.0, 0.0, 0.0)): - n_major = 16 - n_minor = 8 +def add_ring(bm, loc, r_mid, radial_t, width, segments, mat_idx, euler=(0.0, 0.0, 0.0)): + """Flat-sided ring with a box cross-section (felloe / tyre profile). + + Manifold: outer tread, inner surface, and two side annuli, all quads. + Built in the XY plane, width along Z, then rotated/translated. + """ + r_in = r_mid - radial_t + r_out = r_mid + radial_t + hw = width / 2.0 rings = [] - for i in range(n_major): - u = i * (2.0 * math.pi / n_major) - ring = [] - for j in range(n_minor): - v = j * (2.0 * math.pi / n_minor) - x = (major + minor * math.cos(v)) * math.cos(u) - y = (major + minor * math.cos(v)) * math.sin(u) - z = minor * math.sin(v) - ring.append(bm.verts.new((x, y, z))) - rings.append(ring) - bm.verts.ensure_lookup_table() - for i in range(n_major): - i2 = (i + 1) % n_major - for j in range(n_minor): - j2 = (j + 1) % n_minor - face = bm.faces.new( - (rings[i][j], rings[i2][j], rings[i2][j2], rings[i][j2]) - ) + for i in range(segments): + u = i * (2.0 * math.pi / segments) + cu = math.cos(u) + su = math.sin(u) + rings.append( + [ + bm.verts.new((r_in * cu, r_in * su, -hw)), + bm.verts.new((r_out * cu, r_out * su, -hw)), + bm.verts.new((r_out * cu, r_out * su, hw)), + bm.verts.new((r_in * cu, r_in * su, hw)), + ] + ) + for i in range(segments): + i2 = (i + 1) % segments + a = rings[i] + b = rings[i2] + for quad in ( + (a[1], b[1], b[2], a[2]), + (a[3], b[3], b[0], a[0]), + (a[2], b[2], b[3], a[3]), + (a[0], b[0], b[1], a[1]), + ): + face = bm.faces.new(quad) face.material_index = mat_idx verts = [v for ring in rings for v in ring] rot = Euler(euler).to_matrix() @@ -503,7 +533,17 @@

Source

def add_wheel(bm, loc, wood, metal): wood.extend( - add_rim(bm, loc, RIM_MAJOR, RIM_MINOR, WOOD_IDX, euler=(math.pi / 2.0, 0.0, 0.0)) + add_ring( + bm, loc, RIM_MAJOR, RIM_RADIAL, RIM_W, 16, WOOD_IDX, + euler=(math.pi / 2.0, 0.0, 0.0), + ) + ) + metal.extend( + add_ring( + bm, loc, RIM_MAJOR + RIM_RADIAL + TYRE_T / 2.0, TYRE_T / 2.0, + TYRE_W, 16, METAL_IDX, + euler=(math.pi / 2.0, 0.0, 0.0), + ) ) wood.extend( add_cyl( @@ -516,8 +556,10 @@

Source

euler=(math.pi / 2.0, 0.0, 0.0), ) ) - inner = HUB_R + 0.008 - outer = RIM_MAJOR - RIM_MINOR * 0.55 + # Spokes root inside the hub and embed into the felloe ring — no + # floating ends hidden by the hub band. + inner = HUB_R * 0.4 + outer = RIM_MAJOR - RIM_RADIAL + 0.008 mid_r = 0.5 * (inner + outer) slen = outer - inner for i in range(N_SPOKES): @@ -567,7 +609,10 @@

Source

wood_wheels = [] metal = [] axle_z = RIM_MAJOR - bed_z = axle_z + 0.10 + # The bed rides on the axle through a bolster: axle top -> bolster -> + # bed bottom. Never let the axle interpenetrate the slats. + bed_z = axle_z + AXLE_R + BOLSTER_H + BED_T / 2.0 + bed_bottom = bed_z - BED_T / 2.0 bed_cx = 0.06 add_wheel(bm, (AXLE_X, TRACK / 2.0, axle_z), wood_wheels, metal) @@ -577,7 +622,7 @@

Source

add_cyl( bm, (AXLE_X, 0.0, axle_z), - 0.020, + AXLE_R, TRACK + 0.06, 10, METAL_IDX, @@ -597,6 +642,8 @@

Source

WOOD_IDX, ) ) + # Side walls and the front board finish flush at WALL_H; the back + # board is a deliberately lower tailgate. for ysign in (-1.0, 1.0): body.extend( add_box( @@ -609,32 +656,37 @@

Source

body.extend( add_box( bm, - (bed_cx + BED_L / 2.0 - WALL_T / 2.0, 0.0, bed_z + WALL_H / 2.0 + 0.02), - (WALL_T, BED_W + WALL_T * 2.0, WALL_H + 0.04), + (bed_cx + BED_L / 2.0 - WALL_T / 2.0, 0.0, bed_z + WALL_H / 2.0), + (WALL_T, BED_W + WALL_T * 2.0, WALL_H), WOOD_IDX, ) ) body.extend( add_box( bm, - (bed_cx - BED_L / 2.0 + WALL_T / 2.0, 0.0, bed_z + 0.06), - (WALL_T, BED_W + WALL_T, 0.12), + (bed_cx - BED_L / 2.0 + WALL_T / 2.0, 0.0, bed_z + TAILGATE_H / 2.0), + (WALL_T, BED_W + WALL_T * 2.0, TAILGATE_H), WOOD_IDX, ) ) - for xj in (bed_cx - BED_L * 0.32, bed_cx + BED_L * 0.28): + # Bolsters: one sits on the axle, one forward; both carry the bed. + for xj in (AXLE_X, bed_cx + BED_L * 0.28): body.extend( add_box( bm, - (xj, 0.0, bed_z - BED_T / 2.0 - 0.022), - (0.055, BED_W * 0.92, 0.044), + (xj, 0.0, axle_z + AXLE_R + BOLSTER_H / 2.0), + (0.055, BED_W * 0.92, BOLSTER_H), WOOD_IDX, ) ) + # Shafts hang under the bed front: the back end embeds 6 mm into the + # slat bottom and never pokes through the bed floor. shaft_x = bed_cx + BED_L / 2.0 + SHAFT_L / 2.0 - 0.04 - shaft_z = bed_z - 0.02 - pitch = math.radians(7.0) + shaft_z = ( + bed_bottom + 0.006 - SHAFT_T / 2.0 + - math.sin(SHAFT_PITCH) * (SHAFT_L / 2.0) + ) for ysign in (-1.0, 1.0): body.extend( add_box( @@ -642,28 +694,30 @@

Source

(shaft_x, ysign * 0.12, shaft_z), (SHAFT_L, SHAFT_T, SHAFT_T), WOOD_IDX, - euler=(0.0, pitch, 0.0), + euler=(0.0, SHAFT_PITCH, 0.0), ) ) metal.extend( add_box( bm, - (bed_cx + BED_L / 2.0 - 0.02, ysign * 0.12, bed_z - 0.01), + (bed_cx + BED_L / 2.0 - 0.02, ysign * 0.12, bed_bottom - IRON_T / 2.0), (0.05, 0.042, IRON_T), METAL_IDX, ) ) + # Tie-down plates sit on top of the bed floor, fully inboard of the + # walls — visible, not buried inside the slats. for sx, sy in ( - (bed_cx - BED_L / 2.0 + 0.04, -BED_W / 2.0), - (bed_cx - BED_L / 2.0 + 0.04, BED_W / 2.0), - (bed_cx + BED_L / 2.0 - 0.04, -BED_W / 2.0), - (bed_cx + BED_L / 2.0 - 0.04, BED_W / 2.0), + (bed_cx - BED_L / 2.0 + 0.055, -BED_W / 2.0 + 0.055), + (bed_cx - BED_L / 2.0 + 0.055, BED_W / 2.0 - 0.055), + (bed_cx + BED_L / 2.0 - 0.055, -BED_W / 2.0 + 0.055), + (bed_cx + BED_L / 2.0 - 0.055, BED_W / 2.0 - 0.055), ): metal.extend( add_box( bm, - (sx, sy, bed_z + 0.01), + (sx, sy, bed_z + BED_T / 2.0 + IRON_T / 2.0), (0.055, 0.055, IRON_T), METAL_IDX, ) @@ -712,13 +766,33 @@

Source

return out -def principled(name, color, metallic, roughness): +def principled(name, color, metallic, roughness, noise_scale=0.0, wear=None): mat = bpy.data.materials.new(name) mat.use_nodes = True - bsdf = mat.node_tree.nodes["Principled BSDF"] + nt = mat.node_tree + bsdf = nt.nodes["Principled BSDF"] bsdf.inputs["Base Color"].default_value = color bsdf.inputs["Metallic"].default_value = metallic bsdf.inputs["Roughness"].default_value = roughness + if noise_scale > 0.0 and wear is not None: + tex = nt.nodes.new("ShaderNodeTexNoise") + tex.inputs["Scale"].default_value = noise_scale + tex.inputs["Detail"].default_value = 8.0 + tex.inputs["Roughness"].default_value = 0.55 + mix = nt.nodes.new("ShaderNodeMix") + mix.data_type = "RGBA" + mix.inputs["A"].default_value = color + mix.inputs["B"].default_value = wear + fac = mix.inputs.get("Factor") or mix.inputs.get("Fac") + nt.links.new(tex.outputs["Fac"], fac) + nt.links.new(mix.outputs["Result"], bsdf.inputs["Base Color"]) + rmix = nt.nodes.new("ShaderNodeMix") + rmix.data_type = "FLOAT" + rmix.inputs["A"].default_value = roughness + rmix.inputs["B"].default_value = min(1.0, roughness + 0.18) + rfac = rmix.inputs.get("Factor") or rmix.inputs.get("Fac") + nt.links.new(tex.outputs["Fac"], rfac) + nt.links.new(rmix.outputs["Result"], bsdf.inputs["Roughness"]) return mat @@ -765,6 +839,84 @@

Source

return min(us), min(vs), max(us), max(vs), overlap, len(aabbs) +def face_area(me, poly): + vs = [me.vertices[i].co for i in poly.vertices] + if len(vs) < 3: + return 0.0 + v0 = vs[0] + area = 0.0 + for i in range(1, len(vs) - 1): + area += (vs[i] - v0).cross(vs[i + 1] - v0).length * 0.5 + return area + + +def hygiene_audit(me): + # Combinatorics match examples/mesh-hygiene-audit.audit (copied, not imported). + nv, ne, nf = len(me.vertices), len(me.edges), len(me.polygons) + ngons = sum(1 for p in me.polygons if len(p.vertices) > 4) + areas = [face_area(me, p) for p in me.polygons] + zero_area = sum(1 for a in areas if a <= AREA_EPS) + bm = bmesh.new() + try: + bm.from_mesh(me) + bm.verts.ensure_lookup_table() + bm.edges.ensure_lookup_table() + loose_v = sum(1 for v in bm.verts if len(v.link_edges) == 0) + loose_e = sum(1 for e in bm.edges if len(e.link_faces) == 0) + nonman = sum(1 for e in bm.edges if not e.is_manifold) + ret = bmesh.ops.find_doubles(bm, verts=list(bm.verts), dist=DOUBLES_EPS) + doubles = len(ret.get("targetmap") or {}) + finally: + bm.free() + return { + "nv": nv, + "ne": ne, + "nf": nf, + "ngons": ngons, + "loose_v": loose_v, + "loose_e": loose_e, + "nonman": nonman, + "zero_area": zero_area, + "doubles": doubles, + "euler": nv - ne + nf, + } + + +def min_mat_distance(me, ia, ib): + """Closest surface distance between two material islands via BVH. + + Vert-vert distance is the wrong metric for thin parts: a face interior + can touch while its corner verts sit a radius apart. + """ + bm_a = bmesh.new() + bm_b = bmesh.new() + try: + bm_a.from_mesh(me) + bm_b.from_mesh(me) + bm_a.faces.ensure_lookup_table() + bm_b.faces.ensure_lookup_table() + drop_a = [f for f in bm_a.faces if f.material_index != ia] + drop_b = [f for f in bm_b.faces if f.material_index != ib] + if drop_a: + bmesh.ops.delete(bm_a, geom=drop_a, context="FACES") + if drop_b: + bmesh.ops.delete(bm_b, geom=drop_b, context="FACES") + if not bm_a.faces or not bm_b.faces: + return 1e9 + tree = BVHTree.FromBMesh(bm_b) + best = 1e9 + for src in list(bm_a.verts) + list(bm_a.faces): + co = src.co if hasattr(src, "co") else src.calc_center_median() + hit = tree.find_nearest(co) + if hit[0] is None: + continue + best = min(best, hit[3]) + return best + finally: + bm_a.free() + bm_b.free() + + def make_lod(obj, name, ratio, skip_decimate): mesh = obj.data.copy() lod = bpy.data.objects.new(name, mesh) @@ -851,14 +1003,24 @@

Source

) -def check(skip_decimate): +def check(skip_decimate, lift_z=False): bpy.ops.wm.read_factory_settings(use_empty=True) low = build_cart_mesh("CartLow", bevel_offset=0.005, bevel_segments=2) high = build_cart_mesh("CartHigh", bevel_offset=0.005, bevel_segments=4) - wood = principled("CartWood", (0.42, 0.22, 0.08, 1.0), 0.0, 0.58) - metal = principled("CartIron", (0.13, 0.135, 0.15, 1.0), 1.0, 0.32) + wood = principled( + "CartWood", (0.42, 0.22, 0.08, 1.0), 0.0, 0.58, + noise_scale=7.0, wear=(0.26, 0.12, 0.04, 1.0), + ) + metal = principled( + "CartIron", (0.13, 0.135, 0.15, 1.0), 1.0, 0.32, + noise_scale=5.0, wear=(0.05, 0.05, 0.06, 1.0), + ) assign_slots(low, wood, metal) assign_slots(high, wood, metal) + if lift_z: + for v in low.data.vertices: + v.co.z += LIFT_Z + low.data.update() if low.data is None or len(low.data.polygons) < 6: return fail("cart mesh did not build", 3), None, None, None, None, None @@ -921,6 +1083,14 @@

Source

f"measured collider_tris={col_tris} bake={bake_result} " f"bake_has_data={img.has_data} export_bytes={export_size}" ) + hyg = hygiene_audit(low.data) + gap_mw = min_mat_distance(low.data, METAL_IDX, WOOD_IDX) + print( + f"measured hygiene loose_v={hyg['loose_v']} loose_e={hyg['loose_e']} " + f"nonman={hyg['nonman']} zero_area={hyg['zero_area']} " + f"doubles={hyg['doubles']} ngons={hyg['ngons']} euler={hyg['euler']}" + ) + print(f"measured gap_metal_wood={gap_mw:.5f}") if not (BASE_TRIS_MIN <= base_tris <= BASE_TRIS_MAX): return fail( @@ -937,6 +1107,11 @@

Source

f"metal faces {idx_counts.get(METAL_IDX, 0)} < {METAL_FACES_MIN}", 5, ), None, None, None, None, None + if idx_counts.get(WOOD_IDX, 0) < WOOD_FACES_MIN: + return fail( + f"wood faces {idx_counts.get(WOOD_IDX, 0)} < {WOOD_FACES_MIN}", + 5, + ), None, None, None, None, None if u0 < -UV_EPS or v0 < -UV_EPS or u1 > 1.0 + UV_EPS or v1 > 1.0 + UV_EPS: return fail( f"UVs outside 0..1: ({u0:.4f},{v0:.4f})-({u1:.4f},{v1:.4f})", @@ -980,6 +1155,32 @@

Source

), None, None, None, None, None if export_size <= 0: return fail("export file missing or empty", 13), None, None, None, None, None + if ( + hyg["loose_v"] + or hyg["loose_e"] + or hyg["nonman"] + or hyg["zero_area"] + or hyg["doubles"] + or hyg["ngons"] + ): + return fail( + f"hygiene loose_v={hyg['loose_v']} loose_e={hyg['loose_e']} " + f"nonman={hyg['nonman']} zero_area={hyg['zero_area']} " + f"doubles={hyg['doubles']} ngons={hyg['ngons']}", + 15, + ), None, None, None, None, None + if abs(bb[2]) > ZMIN_EPS: + return fail( + f"zmin {bb[2]:.6f} not within {ZMIN_EPS} of 0 " + "(--lift-z is the designed fail)", + 16, + ), None, None, None, None, None + if gap_mw > GAP_MAX: + return fail( + f"metal-wood gap {gap_mw:.5f} > {GAP_MAX} " + "(tyres, hubs, straps, and plates must touch the wood they mount to)", + 17, + ), None, None, None, None, None return 0, low, high, wood, tex, collider @@ -1098,9 +1299,16 @@

Source

action="store_true", help="falsification: skip the LOD DECIMATE stage", ) + p.add_argument( + "--lift-z", + action="store_true", + help="falsification: lift the mesh so zmin fails the grounded budget", + ) args = p.parse_args(argv) - code, low, _high, wood, tex, _col = check(args.skip_decimate) + code, low, _high, wood, tex, _col = check( + args.skip_decimate, lift_z=args.lift_z + ) if code: return code if args.output: diff --git a/showcase/cart/README.md b/showcase/cart/README.md index 424a48a..b6c013f 100644 --- a/showcase/cart/README.md +++ b/showcase/cart/README.md @@ -21,14 +21,17 @@ materials, UVs, evaluated LOD, collider, or export file. | Axis | Declared | Measured (4.5.11 / 5.1.2 / 5.2.1) | | --- | --- | --- | -| Base triangles | 2470–2680 | 2572 / 2572 / 2572 | +| Base triangles | 2470–2900 | 2600 / 2600 / 2600 | | LOD1 ratio | 0.32–0.62 of base | 0.5000 / 0.5000 / 0.5000 | -| LOD2 ratio | 0.10–0.35 of base | 0.2193 / 0.2193 / 0.2146 | -| Materials | exactly 2 distinct, ≥24 metal faces | 2 slots, 100 metal | +| LOD2 ratio | 0.10–0.35 of base | 0.2200 / 0.2200 / 0.2154 | +| Materials | exactly 2 distinct, metal ≥ 24, wood ≥ 800 faces | 2 slots, floors met | | UVs | in `0..1`, AABB overlap ≤ 1e-5 | in range, overlap 0 | -| Outer AABB | (1.547, 0.749, 0.656) m ± 0.01 | (1.5473, 0.7486, 0.6560), zmin 0 | -| Collider tris | ≤ 360 | 306 | -| Export | written, size > 0 | 202500 / 202500 / 202492 bytes | +| Outer AABB | (1.539, 0.749, 0.640) m ± 0.01 | (1.5393, 0.7486, 0.6400) | +| Grounded | bbox min Z within 1e-4 of 0 | 0.0000 / 0.0000 / 0.0000 | +| Hygiene | loose V/E, non-manifold, zero-area, doubles @1e-5, n-gons: all 0 | 0 / 0 / 0 on every axis | +| Material-island gap | metal↔wood min distance ≤ 0.008 m | 0.00000 / 0.00000 / 0.00000 | +| Collider tris | ≤ 360 | 122 | +| Export | written, size > 0 | 201048 / 201048 / 201032 bytes | 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 @@ -38,17 +41,20 @@ Export byte counts differ by 8 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. +exit 9 fires. `--lift-z` raises the finished mesh 0.05 m so the grounded +budget fails and exit 16 fires. Those are the named budgets the two +falsifiers violate. ## Run ```bash blender --background --python cart.py -- blender --background --python cart.py -- --skip-decimate +blender --background --python cart.py -- --lift-z blender --background --python cart.py -- --output cart.png ``` -Smoke does not pass `--output` or `--skip-decimate`. +Smoke does not pass `--output`, `--skip-decimate`, or `--lift-z`. ## Exit codes @@ -72,3 +78,6 @@ 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: loose geometry, non-manifold, zero-area, doubles, or n-gons | +| 16 | Bbox min Z not grounded (`--lift-z` lands here) | +| 17 | Material-island gap above tolerance (parts meant to touch) | diff --git a/showcase/cart/cart.py b/showcase/cart/cart.py index cb7f36e..e7e06df 100644 --- a/showcase/cart/cart.py +++ b/showcase/cart/cart.py @@ -8,7 +8,8 @@ Budgets are declared below and recomputed from the generated result. They are not API-contract witnesses. ``--skip-decimate`` skips the LOD -DECIMATE stage so the LOD-ratio budget fails. +DECIMATE stage so the LOD-ratio budget fails. ``--lift-z`` raises the +mesh so the grounded-zmin hygiene budget fails. No RNG. Construction is closed-form. DECIMATE COLLAPSE triangle counts are not byte-identical across Blender versions — the LOD gate is a @@ -16,6 +17,7 @@ blender --background --python cart.py -- blender --background --python cart.py -- --skip-decimate + blender --background --python cart.py -- --lift-z blender --background --python cart.py -- --output cart.png """ import argparse @@ -28,6 +30,7 @@ import bmesh import bpy from mathutils import Euler, Vector +from mathutils.bvhtree import BVHTree _REPO = os.path.abspath( os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir, os.pardir) @@ -37,9 +40,15 @@ import gallery_framing # noqa: E402 RIM_MAJOR = 0.30 -RIM_MINOR = 0.028 +# Felloe ring: flat-tread box section, not a round tube — round torus rims +# read as bicycle wheels. The iron tyre wraps the tread. +RIM_RADIAL = 0.012 +RIM_W = 0.036 +TYRE_T = 0.008 +TYRE_W = 0.040 TRACK = 0.68 AXLE_X = -0.16 +AXLE_R = 0.020 HUB_R = 0.052 HUB_W = 0.046 N_SPOKES = 8 @@ -49,15 +58,23 @@ BED_T = 0.038 WALL_H = 0.16 WALL_T = 0.032 +TAILGATE_H = 0.10 SHAFT_L = 0.58 SHAFT_T = 0.034 +SHAFT_PITCH = math.radians(7.0) N_SLATS = 6 IRON_T = 0.014 +BOLSTER_H = 0.044 BBOX_TOL = 0.01 -OUTER_SIZE = (1.547, 0.749, 0.656) +OUTER_SIZE = (1.539, 0.749, 0.640) BASE_TRIS_MIN = 2470 -BASE_TRIS_MAX = 2680 +BASE_TRIS_MAX = 2900 +ZMIN_EPS = 1e-4 +DOUBLES_EPS = 1e-5 +AREA_EPS = 1e-10 +GAP_MAX = 0.008 +LIFT_Z = 0.05 LOD1_RATIO_MIN = 0.32 LOD1_RATIO_MAX = 0.62 LOD2_RATIO_MIN = 0.10 @@ -71,6 +88,7 @@ BAKE_RES = 256 CAGE_EXTRUSION = 0.08 METAL_FACES_MIN = 24 +WOOD_FACES_MIN = 800 WOOD_IDX = 0 METAL_IDX = 1 @@ -126,7 +144,7 @@ def add_cyl(bm, loc, radius, depth, segments, mat_idx, euler=(0.0, 0.0, 0.0)): geo = bmesh.ops.create_cone( bm, cap_ends=True, - cap_tris=False, + cap_tris=True, segments=segments, radius1=radius, radius2=radius, @@ -143,28 +161,39 @@ def add_cyl(bm, loc, radius, depth, segments, mat_idx, euler=(0.0, 0.0, 0.0)): return verts -def add_rim(bm, loc, major, minor, mat_idx, euler=(0.0, 0.0, 0.0)): - n_major = 16 - n_minor = 8 +def add_ring(bm, loc, r_mid, radial_t, width, segments, mat_idx, euler=(0.0, 0.0, 0.0)): + """Flat-sided ring with a box cross-section (felloe / tyre profile). + + Manifold: outer tread, inner surface, and two side annuli, all quads. + Built in the XY plane, width along Z, then rotated/translated. + """ + r_in = r_mid - radial_t + r_out = r_mid + radial_t + hw = width / 2.0 rings = [] - for i in range(n_major): - u = i * (2.0 * math.pi / n_major) - ring = [] - for j in range(n_minor): - v = j * (2.0 * math.pi / n_minor) - x = (major + minor * math.cos(v)) * math.cos(u) - y = (major + minor * math.cos(v)) * math.sin(u) - z = minor * math.sin(v) - ring.append(bm.verts.new((x, y, z))) - rings.append(ring) - bm.verts.ensure_lookup_table() - for i in range(n_major): - i2 = (i + 1) % n_major - for j in range(n_minor): - j2 = (j + 1) % n_minor - face = bm.faces.new( - (rings[i][j], rings[i2][j], rings[i2][j2], rings[i][j2]) - ) + for i in range(segments): + u = i * (2.0 * math.pi / segments) + cu = math.cos(u) + su = math.sin(u) + rings.append( + [ + bm.verts.new((r_in * cu, r_in * su, -hw)), + bm.verts.new((r_out * cu, r_out * su, -hw)), + bm.verts.new((r_out * cu, r_out * su, hw)), + bm.verts.new((r_in * cu, r_in * su, hw)), + ] + ) + for i in range(segments): + i2 = (i + 1) % segments + a = rings[i] + b = rings[i2] + for quad in ( + (a[1], b[1], b[2], a[2]), + (a[3], b[3], b[0], a[0]), + (a[2], b[2], b[3], a[3]), + (a[0], b[0], b[1], a[1]), + ): + face = bm.faces.new(quad) face.material_index = mat_idx verts = [v for ring in rings for v in ring] rot = Euler(euler).to_matrix() @@ -219,7 +248,17 @@ def pack_uvs(bm, margin=0.08): def add_wheel(bm, loc, wood, metal): wood.extend( - add_rim(bm, loc, RIM_MAJOR, RIM_MINOR, WOOD_IDX, euler=(math.pi / 2.0, 0.0, 0.0)) + add_ring( + bm, loc, RIM_MAJOR, RIM_RADIAL, RIM_W, 16, WOOD_IDX, + euler=(math.pi / 2.0, 0.0, 0.0), + ) + ) + metal.extend( + add_ring( + bm, loc, RIM_MAJOR + RIM_RADIAL + TYRE_T / 2.0, TYRE_T / 2.0, + TYRE_W, 16, METAL_IDX, + euler=(math.pi / 2.0, 0.0, 0.0), + ) ) wood.extend( add_cyl( @@ -232,8 +271,10 @@ def add_wheel(bm, loc, wood, metal): euler=(math.pi / 2.0, 0.0, 0.0), ) ) - inner = HUB_R + 0.008 - outer = RIM_MAJOR - RIM_MINOR * 0.55 + # Spokes root inside the hub and embed into the felloe ring — no + # floating ends hidden by the hub band. + inner = HUB_R * 0.4 + outer = RIM_MAJOR - RIM_RADIAL + 0.008 mid_r = 0.5 * (inner + outer) slen = outer - inner for i in range(N_SPOKES): @@ -283,7 +324,10 @@ def build_cart_mesh(name, bevel_offset, bevel_segments): wood_wheels = [] metal = [] axle_z = RIM_MAJOR - bed_z = axle_z + 0.10 + # The bed rides on the axle through a bolster: axle top -> bolster -> + # bed bottom. Never let the axle interpenetrate the slats. + bed_z = axle_z + AXLE_R + BOLSTER_H + BED_T / 2.0 + bed_bottom = bed_z - BED_T / 2.0 bed_cx = 0.06 add_wheel(bm, (AXLE_X, TRACK / 2.0, axle_z), wood_wheels, metal) @@ -293,7 +337,7 @@ def build_cart_mesh(name, bevel_offset, bevel_segments): add_cyl( bm, (AXLE_X, 0.0, axle_z), - 0.020, + AXLE_R, TRACK + 0.06, 10, METAL_IDX, @@ -313,6 +357,8 @@ def build_cart_mesh(name, bevel_offset, bevel_segments): WOOD_IDX, ) ) + # Side walls and the front board finish flush at WALL_H; the back + # board is a deliberately lower tailgate. for ysign in (-1.0, 1.0): body.extend( add_box( @@ -325,32 +371,37 @@ def build_cart_mesh(name, bevel_offset, bevel_segments): body.extend( add_box( bm, - (bed_cx + BED_L / 2.0 - WALL_T / 2.0, 0.0, bed_z + WALL_H / 2.0 + 0.02), - (WALL_T, BED_W + WALL_T * 2.0, WALL_H + 0.04), + (bed_cx + BED_L / 2.0 - WALL_T / 2.0, 0.0, bed_z + WALL_H / 2.0), + (WALL_T, BED_W + WALL_T * 2.0, WALL_H), WOOD_IDX, ) ) body.extend( add_box( bm, - (bed_cx - BED_L / 2.0 + WALL_T / 2.0, 0.0, bed_z + 0.06), - (WALL_T, BED_W + WALL_T, 0.12), + (bed_cx - BED_L / 2.0 + WALL_T / 2.0, 0.0, bed_z + TAILGATE_H / 2.0), + (WALL_T, BED_W + WALL_T * 2.0, TAILGATE_H), WOOD_IDX, ) ) - for xj in (bed_cx - BED_L * 0.32, bed_cx + BED_L * 0.28): + # Bolsters: one sits on the axle, one forward; both carry the bed. + for xj in (AXLE_X, bed_cx + BED_L * 0.28): body.extend( add_box( bm, - (xj, 0.0, bed_z - BED_T / 2.0 - 0.022), - (0.055, BED_W * 0.92, 0.044), + (xj, 0.0, axle_z + AXLE_R + BOLSTER_H / 2.0), + (0.055, BED_W * 0.92, BOLSTER_H), WOOD_IDX, ) ) + # Shafts hang under the bed front: the back end embeds 6 mm into the + # slat bottom and never pokes through the bed floor. shaft_x = bed_cx + BED_L / 2.0 + SHAFT_L / 2.0 - 0.04 - shaft_z = bed_z - 0.02 - pitch = math.radians(7.0) + shaft_z = ( + bed_bottom + 0.006 - SHAFT_T / 2.0 + - math.sin(SHAFT_PITCH) * (SHAFT_L / 2.0) + ) for ysign in (-1.0, 1.0): body.extend( add_box( @@ -358,28 +409,30 @@ def build_cart_mesh(name, bevel_offset, bevel_segments): (shaft_x, ysign * 0.12, shaft_z), (SHAFT_L, SHAFT_T, SHAFT_T), WOOD_IDX, - euler=(0.0, pitch, 0.0), + euler=(0.0, SHAFT_PITCH, 0.0), ) ) metal.extend( add_box( bm, - (bed_cx + BED_L / 2.0 - 0.02, ysign * 0.12, bed_z - 0.01), + (bed_cx + BED_L / 2.0 - 0.02, ysign * 0.12, bed_bottom - IRON_T / 2.0), (0.05, 0.042, IRON_T), METAL_IDX, ) ) + # Tie-down plates sit on top of the bed floor, fully inboard of the + # walls — visible, not buried inside the slats. for sx, sy in ( - (bed_cx - BED_L / 2.0 + 0.04, -BED_W / 2.0), - (bed_cx - BED_L / 2.0 + 0.04, BED_W / 2.0), - (bed_cx + BED_L / 2.0 - 0.04, -BED_W / 2.0), - (bed_cx + BED_L / 2.0 - 0.04, BED_W / 2.0), + (bed_cx - BED_L / 2.0 + 0.055, -BED_W / 2.0 + 0.055), + (bed_cx - BED_L / 2.0 + 0.055, BED_W / 2.0 - 0.055), + (bed_cx + BED_L / 2.0 - 0.055, -BED_W / 2.0 + 0.055), + (bed_cx + BED_L / 2.0 - 0.055, BED_W / 2.0 - 0.055), ): metal.extend( add_box( bm, - (sx, sy, bed_z + 0.01), + (sx, sy, bed_z + BED_T / 2.0 + IRON_T / 2.0), (0.055, 0.055, IRON_T), METAL_IDX, ) @@ -428,13 +481,33 @@ def build_cart_mesh(name, bevel_offset, bevel_segments): return out -def principled(name, color, metallic, roughness): +def principled(name, color, metallic, roughness, noise_scale=0.0, wear=None): mat = bpy.data.materials.new(name) mat.use_nodes = True - bsdf = mat.node_tree.nodes["Principled BSDF"] + nt = mat.node_tree + bsdf = nt.nodes["Principled BSDF"] bsdf.inputs["Base Color"].default_value = color bsdf.inputs["Metallic"].default_value = metallic bsdf.inputs["Roughness"].default_value = roughness + if noise_scale > 0.0 and wear is not None: + tex = nt.nodes.new("ShaderNodeTexNoise") + tex.inputs["Scale"].default_value = noise_scale + tex.inputs["Detail"].default_value = 8.0 + tex.inputs["Roughness"].default_value = 0.55 + mix = nt.nodes.new("ShaderNodeMix") + mix.data_type = "RGBA" + mix.inputs["A"].default_value = color + mix.inputs["B"].default_value = wear + fac = mix.inputs.get("Factor") or mix.inputs.get("Fac") + nt.links.new(tex.outputs["Fac"], fac) + nt.links.new(mix.outputs["Result"], bsdf.inputs["Base Color"]) + rmix = nt.nodes.new("ShaderNodeMix") + rmix.data_type = "FLOAT" + rmix.inputs["A"].default_value = roughness + rmix.inputs["B"].default_value = min(1.0, roughness + 0.18) + rfac = rmix.inputs.get("Factor") or rmix.inputs.get("Fac") + nt.links.new(tex.outputs["Fac"], rfac) + nt.links.new(rmix.outputs["Result"], bsdf.inputs["Roughness"]) return mat @@ -481,6 +554,84 @@ def uv_stats(mesh): return min(us), min(vs), max(us), max(vs), overlap, len(aabbs) +def face_area(me, poly): + vs = [me.vertices[i].co for i in poly.vertices] + if len(vs) < 3: + return 0.0 + v0 = vs[0] + area = 0.0 + for i in range(1, len(vs) - 1): + area += (vs[i] - v0).cross(vs[i + 1] - v0).length * 0.5 + return area + + +def hygiene_audit(me): + # Combinatorics match examples/mesh-hygiene-audit.audit (copied, not imported). + nv, ne, nf = len(me.vertices), len(me.edges), len(me.polygons) + ngons = sum(1 for p in me.polygons if len(p.vertices) > 4) + areas = [face_area(me, p) for p in me.polygons] + zero_area = sum(1 for a in areas if a <= AREA_EPS) + bm = bmesh.new() + try: + bm.from_mesh(me) + bm.verts.ensure_lookup_table() + bm.edges.ensure_lookup_table() + loose_v = sum(1 for v in bm.verts if len(v.link_edges) == 0) + loose_e = sum(1 for e in bm.edges if len(e.link_faces) == 0) + nonman = sum(1 for e in bm.edges if not e.is_manifold) + ret = bmesh.ops.find_doubles(bm, verts=list(bm.verts), dist=DOUBLES_EPS) + doubles = len(ret.get("targetmap") or {}) + finally: + bm.free() + return { + "nv": nv, + "ne": ne, + "nf": nf, + "ngons": ngons, + "loose_v": loose_v, + "loose_e": loose_e, + "nonman": nonman, + "zero_area": zero_area, + "doubles": doubles, + "euler": nv - ne + nf, + } + + +def min_mat_distance(me, ia, ib): + """Closest surface distance between two material islands via BVH. + + Vert-vert distance is the wrong metric for thin parts: a face interior + can touch while its corner verts sit a radius apart. + """ + bm_a = bmesh.new() + bm_b = bmesh.new() + try: + bm_a.from_mesh(me) + bm_b.from_mesh(me) + bm_a.faces.ensure_lookup_table() + bm_b.faces.ensure_lookup_table() + drop_a = [f for f in bm_a.faces if f.material_index != ia] + drop_b = [f for f in bm_b.faces if f.material_index != ib] + if drop_a: + bmesh.ops.delete(bm_a, geom=drop_a, context="FACES") + if drop_b: + bmesh.ops.delete(bm_b, geom=drop_b, context="FACES") + if not bm_a.faces or not bm_b.faces: + return 1e9 + tree = BVHTree.FromBMesh(bm_b) + best = 1e9 + for src in list(bm_a.verts) + list(bm_a.faces): + co = src.co if hasattr(src, "co") else src.calc_center_median() + hit = tree.find_nearest(co) + if hit[0] is None: + continue + best = min(best, hit[3]) + return best + finally: + bm_a.free() + bm_b.free() + + def make_lod(obj, name, ratio, skip_decimate): mesh = obj.data.copy() lod = bpy.data.objects.new(name, mesh) @@ -567,14 +718,24 @@ def export_unity(path, objects): ) -def check(skip_decimate): +def check(skip_decimate, lift_z=False): bpy.ops.wm.read_factory_settings(use_empty=True) low = build_cart_mesh("CartLow", bevel_offset=0.005, bevel_segments=2) high = build_cart_mesh("CartHigh", bevel_offset=0.005, bevel_segments=4) - wood = principled("CartWood", (0.42, 0.22, 0.08, 1.0), 0.0, 0.58) - metal = principled("CartIron", (0.13, 0.135, 0.15, 1.0), 1.0, 0.32) + wood = principled( + "CartWood", (0.42, 0.22, 0.08, 1.0), 0.0, 0.58, + noise_scale=7.0, wear=(0.26, 0.12, 0.04, 1.0), + ) + metal = principled( + "CartIron", (0.13, 0.135, 0.15, 1.0), 1.0, 0.32, + noise_scale=5.0, wear=(0.05, 0.05, 0.06, 1.0), + ) assign_slots(low, wood, metal) assign_slots(high, wood, metal) + if lift_z: + for v in low.data.vertices: + v.co.z += LIFT_Z + low.data.update() if low.data is None or len(low.data.polygons) < 6: return fail("cart mesh did not build", 3), None, None, None, None, None @@ -637,6 +798,14 @@ def check(skip_decimate): f"measured collider_tris={col_tris} bake={bake_result} " f"bake_has_data={img.has_data} export_bytes={export_size}" ) + hyg = hygiene_audit(low.data) + gap_mw = min_mat_distance(low.data, METAL_IDX, WOOD_IDX) + print( + f"measured hygiene loose_v={hyg['loose_v']} loose_e={hyg['loose_e']} " + f"nonman={hyg['nonman']} zero_area={hyg['zero_area']} " + f"doubles={hyg['doubles']} ngons={hyg['ngons']} euler={hyg['euler']}" + ) + print(f"measured gap_metal_wood={gap_mw:.5f}") if not (BASE_TRIS_MIN <= base_tris <= BASE_TRIS_MAX): return fail( @@ -653,6 +822,11 @@ def check(skip_decimate): f"metal faces {idx_counts.get(METAL_IDX, 0)} < {METAL_FACES_MIN}", 5, ), None, None, None, None, None + if idx_counts.get(WOOD_IDX, 0) < WOOD_FACES_MIN: + return fail( + f"wood faces {idx_counts.get(WOOD_IDX, 0)} < {WOOD_FACES_MIN}", + 5, + ), None, None, None, None, None if u0 < -UV_EPS or v0 < -UV_EPS or u1 > 1.0 + UV_EPS or v1 > 1.0 + UV_EPS: return fail( f"UVs outside 0..1: ({u0:.4f},{v0:.4f})-({u1:.4f},{v1:.4f})", @@ -696,6 +870,32 @@ def check(skip_decimate): ), None, None, None, None, None if export_size <= 0: return fail("export file missing or empty", 13), None, None, None, None, None + if ( + hyg["loose_v"] + or hyg["loose_e"] + or hyg["nonman"] + or hyg["zero_area"] + or hyg["doubles"] + or hyg["ngons"] + ): + return fail( + f"hygiene loose_v={hyg['loose_v']} loose_e={hyg['loose_e']} " + f"nonman={hyg['nonman']} zero_area={hyg['zero_area']} " + f"doubles={hyg['doubles']} ngons={hyg['ngons']}", + 15, + ), None, None, None, None, None + if abs(bb[2]) > ZMIN_EPS: + return fail( + f"zmin {bb[2]:.6f} not within {ZMIN_EPS} of 0 " + "(--lift-z is the designed fail)", + 16, + ), None, None, None, None, None + if gap_mw > GAP_MAX: + return fail( + f"metal-wood gap {gap_mw:.5f} > {GAP_MAX} " + "(tyres, hubs, straps, and plates must touch the wood they mount to)", + 17, + ), None, None, None, None, None return 0, low, high, wood, tex, collider @@ -814,9 +1014,16 @@ def main(): action="store_true", help="falsification: skip the LOD DECIMATE stage", ) + p.add_argument( + "--lift-z", + action="store_true", + help="falsification: lift the mesh so zmin fails the grounded budget", + ) args = p.parse_args(argv) - code, low, _high, wood, tex, _col = check(args.skip_decimate) + code, low, _high, wood, tex, _col = check( + args.skip_decimate, lift_z=args.lift_z + ) if code: return code if args.output: diff --git a/showcase/cart/preview.webp b/showcase/cart/preview.webp index c7127ceffdc2c417a18c907604cb4fdff22bbb57..33e7fcfe604a40c6c36556cb7934e59adda4dc6f 100644 GIT binary patch literal 25924 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 literal 19774 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 dUpfx0S&7vfs*J(;%$+mB_b}fa8Zr_F003` Date: Tue, 15 Sep 2026 21:21:33 -0400 Subject: [PATCH 3/3] docs: add material face-floor convention and refresh showcase gallery Adds the material face-floor convention to the showcase README: every declared material asserts a named minimum polygon count recomputed from polygon.material_index, which catches the slot-assignment wipe class (materials.clear() resets material_index to 0 on some versions while the slot count still passes). Slot assignment must be index-preserving. Refreshes the stone-well and cart witness strings in showcase/gallery.json for the quality-pass numbers and regenerates docs/gallery. The regeneration also picks up iron-cauldron detail-page drift whose README landed without a gallery rebuild. Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Cursor --- docs/gallery/index.html | 4 ++-- docs/gallery/iron-cauldron/index.html | 2 +- showcase/README.md | 7 +++++++ showcase/gallery.json | 4 ++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/gallery/index.html b/docs/gallery/index.html index 8915f9c..8e07123 100644 --- a/docs/gallery/index.html +++ b/docs/gallery/index.html @@ -903,7 +903,7 @@

shipping-crate

stone-well

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

-

witnesses Recomputed: 8388 tris, three materials, UVs in 0..1 with zero AABB overlap, outer AABB 1.640×1.640×1.688 m, LOD ratios in band, convex collider 230 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.

+

witnesses Recomputed: 9380 tris, three materials with face floors, UVs in 0..1 with zero AABB overlap, outer AABB 1.640×1.640×1.761 m, LOD ratios in band, convex collider 306 tris, hygiene zero (loose, non-manifold, doubles, n-gons), grounded zmin, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget; --lift-z exits 16 on the grounded budget.

View example
@@ -1002,7 +1002,7 @@

watchtower

cart

A procedural two-wheel wooden cart through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.

-

witnesses Recomputed: 2572 tris, two materials with 100 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.547×0.749×0.656 m, LOD ratios in band, convex collider 306 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.

+

witnesses Recomputed: 2600 tris, two materials with metal and wood face floors, UVs in 0..1 with zero AABB overlap, outer AABB 1.539×0.749×0.640 m, LOD ratios in band, convex collider 122 tris, hygiene zero (loose, non-manifold, doubles, n-gons), grounded zmin, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget; --lift-z exits 16 on the grounded budget.

View example
diff --git a/docs/gallery/iron-cauldron/index.html b/docs/gallery/iron-cauldron/index.html index 239ed7f..ea55dc7 100644 --- a/docs/gallery/iron-cauldron/index.html +++ b/docs/gallery/iron-cauldron/index.html @@ -265,7 +265,7 @@

iron-cauldron

Budgets

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

| Axis | Declared | Measured (4.5.11 / 5.1.2 / 5.2.1) | | --- | --- | --- | | Base triangles | 3280–3520 | 3388 / 3388 / 3388 | | LOD1 ratio | 0.32–0.62 of base | 0.5000 / 0.5000 / 0.5000 | | LOD2 ratio | 0.10–0.35 of base | 0.2196 / 0.2196 / 0.2172 | | Materials | exactly 2 distinct, ≥12 wood, ≥24 metal | 2 slots, 450 wood, 1198 metal | | UVs | in 0..1, AABB overlap ≤ 1e-5 | in range, overlap 0 | | Outer AABB | (1.013, 0.986, 0.827) m ± 0.01 | (1.0128, 0.9865, 0.8271), zmin 0.002 | | Pot–leg clearance | ≥ 0.04 m (recomputed vs pole axes) | 0.0513 / 0.0513 / 0.0513 | | Collider tris | ≤ 200 | 98 | | Export | written, size > 0 | 245060 / 245060 / 245044 bytes |

-

DECIMATE COLLAPSE triangle counts are not identical across series — 5.2.1 is 4 tris leaner on 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.

+

DECIMATE COLLAPSE triangle counts are not identical across series — 5.2.1 is 8 tris leaner on 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 16 B on 5.2.1 (glTF serializer), not a gated axis. The pot–leg clearance is recomputed from shell verts vs the three pole axes; clipping exits 3.

--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.

Run

blender --background --python iron_cauldron.py --
diff --git a/showcase/README.md b/showcase/README.md
index 5896fe7..c46a12f 100644
--- a/showcase/README.md
+++ b/showcase/README.md
@@ -43,6 +43,13 @@ entry in `showcase/gallery.json`, and a rendered still.
   characteristic 2 — that is a single-shell contract. Pairs of parts
   meant to touch assert a BVH surface gap below a named epsilon
   (vert-vert is the wrong metric for thin straps and collars).
+- **Material face floors.** Every declared material asserts a named
+  minimum face count on the finished mesh, recomputed from
+  `polygon.material_index`. This catches the slot-assignment wipe class:
+  `obj.data.materials.clear()` resets every polygon's `material_index`
+  to 0 on some versions, which renders the piece single-material while
+  the slot count still passes. Assign slots by index-preserving
+  append/replace, never clear-and-rebuild.
 - **Exit codes** are file-local: `0` success, argparse `2`, `3` and above
   in check order. `9` is legal. FATAL `sys.exit(1)` is a crash, never a
   named check.
diff --git a/showcase/gallery.json b/showcase/gallery.json
index 09b5d48..ef09b9c 100644
--- a/showcase/gallery.json
+++ b/showcase/gallery.json
@@ -21,7 +21,7 @@
       "name": "stone-well",
       "dir": "showcase/stone-well",
       "teaches": "A procedural stone well through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.",
-      "witnessesFix": "Recomputed: 8388 tris, three materials, UVs in 0..1 with zero AABB overlap, outer AABB 1.640×1.640×1.688 m, LOD ratios in band, convex collider 230 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.",
+      "witnessesFix": "Recomputed: 9380 tris, three materials with face floors, UVs in 0..1 with zero AABB overlap, outer AABB 1.640×1.640×1.761 m, LOD ratios in band, convex collider 306 tris, hygiene zero (loose, non-manifold, doubles, n-gons), grounded zmin, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget; --lift-z exits 16 on the grounded budget.",
       "hero": "docs/gallery/assets/stone-well-hero.webp",
       "preview": "showcase/stone-well/preview.webp",
       "tags": [
@@ -129,7 +129,7 @@
       "name": "cart",
       "dir": "showcase/cart",
       "teaches": "A procedural two-wheel wooden cart through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.",
-      "witnessesFix": "Recomputed: 2572 tris, two materials with 100 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.547×0.749×0.656 m, LOD ratios in band, convex collider 306 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.",
+      "witnessesFix": "Recomputed: 2600 tris, two materials with metal and wood face floors, UVs in 0..1 with zero AABB overlap, outer AABB 1.539×0.749×0.640 m, LOD ratios in band, convex collider 122 tris, hygiene zero (loose, non-manifold, doubles, n-gons), grounded zmin, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget; --lift-z exits 16 on the grounded budget.",
       "hero": "docs/gallery/assets/cart-hero.webp",
       "preview": "showcase/cart/preview.webp",
       "tags": [