vertex baker: export contract + vertex normals; validator accepts COLOR_0 asset class
Some checks failed
CodeQL Advanced / Analyze (${{ matrix.language }}) (none, c-cpp) (push) Has been cancelled
CodeQL Advanced / Analyze (${{ matrix.language }}) (none, python) (push) Has been cancelled

- _export_pbr vertex branch returns (trimesh, pre_simplified) per contract
- materialize vertex_normals pre-export (glTF NORMAL, same trick as _raw_trimesh)
- gltf_validation: COLOR_0-without-UVs primitives are a legitimate color-bearing
  static asset (glTF default material x COLOR_0); texture checks skip for them

Full gate now EXIT=0: 71.96s e2e, 26.5GB peak (from A0 216.6s / 75.4GB).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
m3ultra 2026-07-20 03:53:35 +10:00
parent 7860148eb2
commit 0db816b55d
2 changed files with 11 additions and 4 deletions

View File

@ -242,9 +242,9 @@ def _export_pbr(mesh, path: Path, *, baker: str, target: Optional[int], texture_
rgba = np.concatenate([rgb, np.ones((len(v_gltf), 1))], 1)
out.visual = trimesh.visual.ColorVisuals(
out, vertex_colors=(rgba * 255).astype(np.uint8)) # LINEAR
_ = out.vertex_normals # materialize so glTF gets NORMAL (see _raw_trimesh)
out.export(str(path))
return {"baker": "vertex", "pre_simplified": pre_simplified,
"triangles": int(len(f_np)), "vertices": int(len(v_np))}
return out, pre_simplified
if baker == "metal":
available, reason = _metal_baker_available()

View File

@ -83,8 +83,13 @@ def inspect_glb(path: Path, *, require_pbr: bool) -> dict[str, Any]:
if int(primitive.get("mode", 4)) != 4:
raise ValueError("only TRIANGLES primitives are supported")
attributes = primitive.get("attributes", {})
required = ["POSITION", "NORMAL"] + (["TEXCOORD_0"] if require_pbr else [])
required = ["POSITION", "NORMAL"]
missing = [name for name in required if name not in attributes]
# a color-bearing static asset may carry UVs (texture bake) OR
# per-vertex colors (vertex bake) — either satisfies require_pbr
if require_pbr and "TEXCOORD_0" not in attributes \
and "COLOR_0" not in attributes:
missing.append("TEXCOORD_0|COLOR_0")
if missing:
raise ValueError(f"primitive is missing attributes: {', '.join(missing)}")
position = document["accessors"][int(attributes["POSITION"])]
@ -103,7 +108,9 @@ def inspect_glb(path: Path, *, require_pbr: bool) -> dict[str, Any]:
raise ValueError("invalid triangle index count")
triangles += index_count // 3
if require_pbr:
_vertex_colored = ("COLOR_0" in attributes
and "TEXCOORD_0" not in attributes)
if require_pbr and not _vertex_colored:
if "material" not in primitive:
raise ValueError("PBR primitive has no material")
material = document["materials"][int(primitive["material"])]