diff --git a/backend/app/domains/pipeline/tasks/export_glb.py b/backend/app/domains/pipeline/tasks/export_glb.py index dfa1956..9e7c34b 100644 --- a/backend/app/domains/pipeline/tasks/export_glb.py +++ b/backend/app/domains/pipeline/tasks/export_glb.py @@ -768,7 +768,11 @@ def generate_usd_master_task(self, cad_file_id: str) -> dict: if manifest_parts: try: resolved = { - p["part_key"]: {"source_name": p["source_name"], "prim_path": p["prim_path"]} + p["part_key"]: { + "source_name": p["source_name"], + "prim_path": p["prim_path"], + "canonical_material": p.get("canonical_material"), + } for p in manifest_parts } eng3 = _ce(sync_url) diff --git a/render-worker/scripts/export_step_to_usd.py b/render-worker/scripts/export_step_to_usd.py index afbd92f..5a768ad 100644 --- a/render-worker/scripts/export_step_to_usd.py +++ b/render-worker/scripts/export_step_to_usd.py @@ -634,7 +634,7 @@ def main() -> None: # ── Create USD stage ────────────────────────────────────────────────────── stage = Usd.Stage.CreateNew(str(output_path)) - UsdGeom.SetStageUpAxis(stage, UsdGeom.Tokens.y) + UsdGeom.SetStageUpAxis(stage, UsdGeom.Tokens.z) UsdGeom.SetStageMetersPerUnit(stage, 0.001) # mm; Blender handles m conversion on import root_prim = UsdGeom.Xform.Define(stage, "/Root") @@ -705,7 +705,10 @@ def main() -> None: mesh = UsdGeom.Mesh.Define(stage, mesh_path) mesh.CreateSubdivisionSchemeAttr(UsdGeom.Tokens.none) - # OCC (X, Y, Z) mm Z-up → USD (X, -Z, Y) mm Y-up + # OCC is Z-up (mm) but Y-forward. Blender is Z-up, Y-backward. + # GLB export uses: Blender(X, -Z_occ, Y_occ) × 0.001 + # USD stage is Z-up with metersPerUnit=0.001, so Blender applies + # only the scale. Write (X, -Z, Y) to match GLB orientation. mesh.CreatePointsAttr(Vt.Vec3fArray([ Gf.Vec3f(x, -z, y) for (x, y, z) in vertices ]))