fix(materials): stop orphaning references; add a scene audit gate

The blockout cleaning pass found the map was rendering with 604 of 620 mesh actors
unmaterialed - every kit piece and all theatre trim.

Cause: ensure_material() deleted and recreated each /Game/Hollywood/Site/M_* asset on
every run, so actors staged by other tools kept references to deleted assets and fell
back to the default material. Nothing errored; the map looked merely slightly flat.

- Materials are now updated IN PLACE (load, delete_all_material_expressions, rebuild
  the graph, recompile, save). Material.expressions is protected from Python, so the
  editing library's deleter is used.
- 53 duplicated kit actor labels fixed (both shop piers of a bay shared one name).
- New Tools/ue_audit_scene.py gates the scene: every mesh actor has a material, every
  verified frontage span is within +/-1 m (via ue_placement), no duplicate labels.
- render_screenshots.sh now runs the chain in the required order (demo map -> kit ->
  theatre -> audit -> cameras -> capture) and exits non-zero on an audit failure,
  because the demo builder rebuilds materials and later staging must follow it.

Scene audit: 0 failures. Packaged QA PASS. Spawn-view reference score 0.72.
This commit is contained in:
zwitschi committed 2026-11-08 22:48:00 +01:00
1 parent 442d0f3d73
commit 600633cd5b
35 files changed
+226 -55

No files matched your search

+5 -3
View File
@@ -156,11 +156,13 @@ def apply_to_actor(actor, kit, materials=None, prefix=None):
for bay in range(bays):
cx = mn.x + bay_w * (bay + 0.5)
# ground floor: shopfront
for piece, dx in (("Kit_ShopPier_L", -bay_w / 2 + 30.0),
("Kit_ShopPier_R", bay_w / 2 - 30.0)):
for piece, dx, side in (("Kit_ShopPier_L", -bay_w / 2 + 30.0, "L"),
("Kit_ShopPier_R", bay_w / 2 - 30.0, "R")):
if piece in kit:
# The side belongs in the label: both piers of a bay shared one
# label, which left 53 ambiguous pairs in the outliner.
if _spawn(kit[piece], unreal.Vector(cx + dx, face_y, base_z),
f"{prefix}shop_pier_{bay}", kit_material(piece)):
f"{prefix}shop_pier_{side}_{bay}", kit_material(piece)):
placed += 1
if "Kit_ShopGlass" in kit:
if _spawn(kit["Kit_ShopGlass"], unreal.Vector(cx, face_y, base_z),