vertex baker: export contract + vertex normals; validator accepts COLOR_0 asset class
- _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:
parent
7860148eb2
commit
0db816b55d
@ -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)
|
rgba = np.concatenate([rgb, np.ones((len(v_gltf), 1))], 1)
|
||||||
out.visual = trimesh.visual.ColorVisuals(
|
out.visual = trimesh.visual.ColorVisuals(
|
||||||
out, vertex_colors=(rgba * 255).astype(np.uint8)) # LINEAR
|
out, vertex_colors=(rgba * 255).astype(np.uint8)) # LINEAR
|
||||||
|
_ = out.vertex_normals # materialize so glTF gets NORMAL (see _raw_trimesh)
|
||||||
out.export(str(path))
|
out.export(str(path))
|
||||||
return {"baker": "vertex", "pre_simplified": pre_simplified,
|
return out, pre_simplified
|
||||||
"triangles": int(len(f_np)), "vertices": int(len(v_np))}
|
|
||||||
|
|
||||||
if baker == "metal":
|
if baker == "metal":
|
||||||
available, reason = _metal_baker_available()
|
available, reason = _metal_baker_available()
|
||||||
|
|||||||
@ -83,8 +83,13 @@ def inspect_glb(path: Path, *, require_pbr: bool) -> dict[str, Any]:
|
|||||||
if int(primitive.get("mode", 4)) != 4:
|
if int(primitive.get("mode", 4)) != 4:
|
||||||
raise ValueError("only TRIANGLES primitives are supported")
|
raise ValueError("only TRIANGLES primitives are supported")
|
||||||
attributes = primitive.get("attributes", {})
|
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]
|
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:
|
if missing:
|
||||||
raise ValueError(f"primitive is missing attributes: {', '.join(missing)}")
|
raise ValueError(f"primitive is missing attributes: {', '.join(missing)}")
|
||||||
position = document["accessors"][int(attributes["POSITION"])]
|
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")
|
raise ValueError("invalid triangle index count")
|
||||||
triangles += index_count // 3
|
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:
|
if "material" not in primitive:
|
||||||
raise ValueError("PBR primitive has no material")
|
raise ValueError("PBR primitive has no material")
|
||||||
material = document["materials"][int(primitive["material"])]
|
material = document["materials"][int(primitive["material"])]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user