refactor: rebrand project to HartOMat

This commit is contained in:
2026-04-06 12:45:47 +02:00
parent fa7093307a
commit b795f0e6d6
95 changed files with 608 additions and 497 deletions
+17 -17
View File
@@ -12,7 +12,7 @@
- [ ] `blender_render.py` decomposition is still pending; current file remains monolithic
- [ ] Legacy STL-era cleanup is still pending (`stl_quality`, STL endpoints, orphaned directories)
- [x] Decision: USD authoring library → **`usd-core` (pip)** — provides `pxr` module, no GPU tools needed, pip-installable in render-worker
- [x] Decision: seam/sharp payload encoding → **index-space primvars** (`primvars:schaeffler:seamEdgeVertexPairs`, `primvars:schaeffler:sharpEdgeVertexPairs`) — survives transforms, no KD-tree needed
- [x] Decision: seam/sharp payload encoding → **index-space primvars** (`primvars:hartomat:seamEdgeVertexPairs`, `primvars:hartomat:sharpEdgeVertexPairs`) — survives transforms, no KD-tree needed
- [x] Decision: preview GLB derivation → **co-author from same tessellation pass** during migration (avoid round-trip loss from USD→GLB export)
- [x] Decision: single-file vs override layers → **Option B: canonical geometry layer + material override layer, flattened via `UsdUtils.FlattenLayerStack()` for delivery** — preserves hierarchy AND allows instancing later (`FlattenLayerStack` keeps `instanceable` prims; `UsdStage.Flatten` would expand them). Note: Phase 1 uses no instancing (matching current GLB pipeline), but the delivery path is already instancing-safe.
@@ -63,14 +63,14 @@ Add after the `gmsh` line. `usd-core` is the Pixar-maintained pip distribution o
| Attribute | Value source |
|---|---|
| `schaeffler:partKey` | `generate_part_key(xcaf_label_path)` |
| `schaeffler:sourceName` | XCAF `TDataStd_Name` attribute |
| `schaeffler:sourceColor` | XCAF embedded color (hex string) |
| `schaeffler:rawMaterialName` | from `CadFile.part_materials` if available |
| `schaeffler:tessellation:linearDeflectionMm` | CLI arg value |
| `schaeffler:tessellation:angularDeflectionRad` | CLI arg value |
| `primvars:schaeffler:seamEdgeVertexPairs` | OCC B-rep seam edges (index pairs in mesh-local space) |
| `primvars:schaeffler:sharpEdgeVertexPairs` | sharp edges from `_extract_sharp_edge_pairs()` |
| `hartomat:partKey` | `generate_part_key(xcaf_label_path)` |
| `hartomat:sourceName` | XCAF `TDataStd_Name` attribute |
| `hartomat:sourceColor` | XCAF embedded color (hex string) |
| `hartomat:rawMaterialName` | from `CadFile.part_materials` if available |
| `hartomat:tessellation:linearDeflectionMm` | CLI arg value |
| `hartomat:tessellation:angularDeflectionRad` | CLI arg value |
| `primvars:hartomat:seamEdgeVertexPairs` | OCC B-rep seam edges (index pairs in mesh-local space) |
| `primvars:hartomat:sharpEdgeVertexPairs` | sharp edges from `_extract_sharp_edge_pairs()` |
**CLI interface:**
@@ -86,7 +86,7 @@ python3 export_step_to_usd.py \
**Acceptance gate:** `python3 export_step_to_usd.py --step_path 81113-l_cut.stp --output_path /tmp/test.usd`
- File exists, parseable
- 25 part prims with `schaeffler:partKey` attribute
- 25 part prims with `hartomat:partKey` attribute
- Part count matches `export_step_to_gltf.py` output for same file
### Task 1.2 — `usd_master` MediaAsset type
@@ -150,7 +150,7 @@ def build_scene_manifest(cad_file: CadFile, usd_asset: MediaAsset) -> dict:
"part_key": "ring_outer",
"source_name": "RingOuter_AF0",
"prim_path": "/Root/Assembly/Bearing/RingOuter",
"effective_material": "SCHAEFFLER_010102_...",
"effective_material": "HARTOMAT_010102_...",
"assignment_provenance": "manual|auto|default",
"is_unassigned": false
}
@@ -198,7 +198,7 @@ New endpoint returning `SceneManifest`. Calls `build_scene_manifest()` — reads
**File:** `backend/app/api/routers/cad.py`
Accept `{ "part_key": "ring_outer", "material": "SCHAEFFLER_010102_..." }` body (or bulk map). Write to `manual_material_overrides` column (not the old `part_materials` column).
Accept `{ "part_key": "ring_outer", "material": "HARTOMAT_010102_..." }` body (or bulk map). Write to `manual_material_overrides` column (not the old `part_materials` column).
**Acceptance gate:** PUT with `partKey` → subsequent GET `/scene-manifest` shows that part's `assignment_provenance: "manual"`.
@@ -218,10 +218,10 @@ After tessellation (OCC or GMSH), for each mesh face:
Write to USD mesh prim:
```python
mesh_prim.GetPrimvar("schaeffler:seamEdgeVertexPairs").Set(
mesh_prim.GetPrimvar("hartomat:seamEdgeVertexPairs").Set(
Vt.Vec2iArray(seam_pairs), # [(vi0, vi1), ...]
)
mesh_prim.GetPrimvar("schaeffler:sharpEdgeVertexPairs").Set(
mesh_prim.GetPrimvar("hartomat:sharpEdgeVertexPairs").Set(
Vt.Vec2iArray(sharp_pairs),
)
```
@@ -243,8 +243,8 @@ def import_usd_and_restore_topology(usd_path: str) -> list:
if obj.type != 'MESH':
continue
# Read custom attributes set by USD importer
seam_pairs = obj.get("schaeffler_seamEdgeVertexPairs") or []
sharp_pairs = obj.get("schaeffler_sharpEdgeVertexPairs") or []
seam_pairs = obj.get("hartomat_seamEdgeVertexPairs") or []
sharp_pairs = obj.get("hartomat_sharpEdgeVertexPairs") or []
_mark_seams_from_index_pairs(obj, seam_pairs)
_mark_sharp_from_index_pairs(obj, sharp_pairs)
...
@@ -262,7 +262,7 @@ def import_usd_and_restore_topology(usd_path: str) -> list:
Add `--usd_path` argument. When provided:
1. Call `import_usd.py` instead of `export_gltf.py` GLB import
2. Read `schaeffler:partKey` and `schaeffler:canonicalMaterialName` per mesh object after import
2. Read `hartomat:partKey` and `hartomat:canonicalMaterialName` per mesh object after import
3. Apply materials by `partKey → material library name` lookup instead of object-name heuristics
**Migration:** Keep `--glb_path` working in parallel; switch production task to prefer `--usd_path` when `usd_master` asset exists.