409fb92899
M1 — USD exporter:
- render-worker/scripts/export_step_to_usd.py (631 lines)
Full XCAF traversal, one UsdGeom.Mesh per leaf part,
schaeffler:partKey on every prim, index-space sharpEdgeVertexPairs
- render-worker/Dockerfile: usd-core>=24.11 installed (USD 0.26.3)
M2 — usd_master MediaAsset + pipeline auto-chain:
- migrations 060 (usd_master enum), 061 (3 JSONB columns),
062 (rename tessellation settings keys)
- generate_usd_master_task: runs export_step_to_usd.py, upserts
usd_master MediaAsset, writes resolved_material_assignments to CadFile
- Auto-chained from generate_gltf_geometry_task after every GLB export
- step_tasks.py shim re-exports generate_usd_master_task
M3 — scene-manifest API:
- part_key_service.py: build_scene_manifest(), generate_part_key(),
four-layer material priority resolution with provenance
- SceneManifest / PartEntry Pydantic models in products/schemas.py
- GET /api/cad/{id}/scene-manifest endpoint (graceful fallback to
parsed_objects when USD not yet generated)
- POST /api/cad/{id}/generate-usd-master endpoint
- frontend/src/api/sceneManifest.ts: fetchSceneManifest(),
triggerUsdMasterGeneration()
M4 — manual-material-overrides API:
- GET/PUT /api/cad/{id}/manual-material-overrides endpoints
- CadFile.manual_material_overrides JSONB column (migration 061)
- getManualOverrides() / saveManualOverrides() in cad.ts
M5 — ThreeDViewer partKey integration:
- export_step_to_gltf.py injects partKeyMap into GLB extras
- ThreeDViewer: partKeyMap extraction, resolvePartKey(), effectiveMaterials
merges legacy partMaterials + new manualOverrides (server-side persistence)
- MaterialPanel: dual-path save (partKey vs legacy), provenance badge,
reconciliation panel for unmatched/unassigned parts
Also:
- Admin.tsx: generate-missing-usd-masters + canonical scenes bulk actions
- ProductDetail.tsx: usd_master row in asset table
- vite-env.d.ts: fix ImportMeta.env TypeScript error
- GPUProbeResult: add timestamp/devices/render_time_s fields
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
6.4 KiB
6.4 KiB
Plan: P2 USD Foundation — Commit & Verify
Context
All five P2 milestones are already implemented in the working tree as uncommitted changes. The task now is to apply the DB migrations, commit the work, and verify the stack runs.
Milestone status (assessed 2026-03-12)
| Milestone | Status | Key files |
|---|---|---|
M1: export_step_to_usd.py with schaeffler:partKey |
✅ DONE | render-worker/scripts/export_step_to_usd.py (631 lines) |
M2: usd_master MediaAsset + migrations 060–062 + Celery task |
✅ DONE | migrations 060/061/062, generate_usd_master_task in export_glb.py |
M3: GET /api/cad/{id}/scene-manifest |
✅ DONE | part_key_service.py, SceneManifest schema, endpoint in cad.py |
M4: PUT /api/cad/{id}/manual-material-overrides |
✅ DONE | New endpoint pair in cad.py, saveManualOverrides in cad.ts |
| M5: ThreeDViewer uses partKey, survives reload | ✅ DONE | partKeyMap in GLB extras, effectiveMaterials merge, server-side persistence |
Affected Files (all uncommitted — working tree only)
Backend
backend/alembic/versions/060_usd_master_asset_type.py— new migrationbackend/alembic/versions/061_material_assignment_layers.py— new migrationbackend/alembic/versions/062_rename_tessellation_settings.py— new migrationbackend/app/domains/media/models.py—MediaAssetType.usd_masteraddedbackend/app/domains/products/models.py— 3 new JSONB columns onCadFilebackend/app/domains/products/schemas.py—SceneManifest,PartEntryPydantic modelsbackend/app/domains/pipeline/tasks/export_glb.py—generate_usd_master_task+ auto-chainbackend/app/domains/pipeline/tasks/extract_metadata.py— minor updatebackend/app/domains/pipeline/tasks/render_thumbnail.py— minor updatebackend/app/domains/pipeline/tasks/render_order_line.py— minor updatebackend/app/api/routers/cad.py— scene-manifest + manual-material-overrides endpointsbackend/app/api/routers/admin.py— generate-missing-usd-masters + generate-missing-canonical-scenes buttonsbackend/app/services/part_key_service.py— new file:build_scene_manifest(),generate_part_key()backend/app/core/config_service.py— minor updatebackend/app/core/tenant_context.py— new filebackend/app/tasks/step_tasks.py— re-exportsgenerate_usd_master_task
Render worker
render-worker/scripts/export_step_to_usd.py— new file: full USD exporterrender-worker/scripts/export_step_to_gltf.py— injectspartKeyMapinto GLB extrasrender-worker/scripts/still_render.py— USD path supportrender-worker/scripts/turntable_render.py— USD path supportrender-worker/Dockerfile—usd-core>=24.11added
Frontend
frontend/src/api/cad.ts—getManualOverrides(),saveManualOverrides()frontend/src/api/media.ts—usd_mastertype addedfrontend/src/api/sceneManifest.ts— new file:SceneManifest,fetchSceneManifest()frontend/src/components/cad/ThreeDViewer.tsx—partKeyMap,effectiveMaterials, reconciliation panelfrontend/src/components/cad/MaterialPanel.tsx— dual-path save, provenance badgefrontend/src/pages/Admin.tsx— USD master bulk action buttonsfrontend/src/pages/ProductDetail.tsx—usd_masterrow in asset tablefrontend/src/pages/Orders.tsx— minor update
Tasks (in order)
[ ] Task 1: Apply migrations 060–062
- What: Run
docker compose exec backend alembic upgrade headto apply the three pending migrations - Acceptance gate:
docker compose exec backend alembic currentshows062(or higher) as current - Dependencies: none
- Risk: Low — each migration is additive (ADD VALUE, ADD COLUMN, UPDATE). Check for phantom drops before running.
[ ] Task 2: TypeScript check
- What: Run
docker compose exec frontend npx tsc --noEmitto verify no type errors in the frontend changes - Acceptance gate: Zero TypeScript errors
- Dependencies: none (frontend hot-reload, no rebuild needed)
- Risk: Low
[ ] Task 3: Rebuild and restart backend + render-worker
- What:
docker compose up -d --build backend worker render-worker beat— picks up new Dockerfile (usd-core), new tasks, and new migrations - Acceptance gate:
docker compose logs backend | grep "Application startup complete"anddocker compose exec render-worker python3 -c "from pxr import Usd; print(Usd.GetVersion())"both succeed - Dependencies: Task 1
- Risk: Medium —
usd-corepip install adds build time; if it fails the render-worker won't start
[ ] Task 4: Commit all P2 work
- What: Stage and commit all uncommitted P2 files in a single
feat(P2)commit - Acceptance gate:
git statusshows clean working tree (except LEARNINGS.md and review-report.md which can be included) - Dependencies: Tasks 1–3 (verify before committing)
- Risk: Low
[ ] Task 5: Smoke-test end-to-end via Admin panel
- What: Via Admin → "Generate Missing Canonical Scenes" to regenerate GLBs with
partKeyMap+ auto-chain USD masters for existing CAD files - Acceptance gate:
GET /api/cad/{id}/scene-manifestreturns{"parts": [...], ...}for a processed CadFile- ThreeDViewer loads, click a part → MaterialPanel shows assignment provenance
- Assign a material → reload page → assignment still present
- Dependencies: Task 3
- Risk: Medium — existing CAD files need backfill; may take minutes for bulk jobs to complete
Migration Check
Three migrations are pending in the working tree:
060_usd_master_asset_type.py— additive enum value061_material_assignment_layers.py— additive JSONB columns062_rename_tessellation_settings.py— UPDATE onsystem_settingsrows (already checked: migration 062 was applied per review-report)
Before running: read each migration file to confirm no unexpected DROP statements.
Order Recommendation
Migrations → TypeScript check → Rebuild → Commit → Smoke test
Risks / Open Questions
usd-corebuild in Docker may be slow (first build) — expected, not a problem- Migration 062 may already be applied (review noted "verified by 0-row SELECT") —
alembic upgrade headis idempotent if so - Existing CAD files need backfill for
partKeyMapin GLB extras — handled by "Generate Missing Canonical Scenes" bulk action resolvePartKey()falls back to identity (raw mesh name) for GLBs generated before this change — graceful degradation, not a blocking issue