Skip to content

Commit d6efb25

Browse files
authored
Merge pull request #52 from AdaWorldAPI/claude/fma-torso-splat
cockpit/torso: real BodyParts3D anatomy as a gaussian splat (splat3d CPU + three.js orbit)
2 parents 81a0d3d + f197cab commit d6efb25

27 files changed

Lines changed: 646 additions & 0 deletions
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# FMA torso gaussian splat — real BodyParts3D geometry, two cockpit pages
2+
3+
> 2026-06-24 · status: in progress
4+
> The `/fma` heart slice (PR #51) renders the FMA partonomy with *synthesized*
5+
> 8:8-HHTL layout because FMA itself has **zero geometry**. This adds a **torso**
6+
> rendered from **real anatomical meshes** — BodyParts3D, which keys 3D meshes
7+
> directly on FMA concept IDs — across two new cockpit pages.
8+
9+
## The convergence
10+
11+
- **FMA partonomy** (`part_of`) = mereotopological containment in BodyParts3D
12+
(NAR 2009, Table 1: `A part_of B``A° ⊂ B°`, coveredBy). So the HHTL
13+
`[container:identity]` cascade *is* the spatial nesting.
14+
- **BodyParts3D** (DBCLS, CC-BY 4.0) realizes FMA concepts as OBJ meshes in one
15+
shared whole-body frame. `concept id` column **is** the FMA id.
16+
- Z-Anatomy / the Unity app are curated atlases on the same data; we use the raw
17+
FMA-keyed OBJ (no Blender needed).
18+
19+
## Data (measured)
20+
21+
- Root `FMA7181 trunk`**178 concepts, 577 OBJ meshes, ~694K verts**, all present.
22+
Regions: thoracic segment (548 meshes), body wall (81), abdominal (24), perineum (4).
23+
The heart (PR #51) nests inside (`trunk → … → content of middle mediastinum → heart`).
24+
- Source (external, NOT committed): `dbarchive.biosciencedbc.jp/.../partof_BP3D_4.0_obj_99.zip`
25+
+ `partof_inclusion_relation_list.txt` / `partof_element_parts.txt` / `partof_parts_list_e.txt`.
26+
- License: **CC-BY 4.0** — attribution: "BodyParts3D, © The Database Center for
27+
Life Science licensed under CC Attribution 4.0 International".
28+
29+
## Pipeline
30+
31+
```
32+
BodyParts3D (FMA partof tree + FJ OBJ meshes)
33+
→ tools/bake_torso_splat.py (BFS FMA7181 → concepts → FJ meshes → vertices,
34+
recenter/normalize, region-colour, downsample)
35+
→ cockpit/public/torso.splat (SPL1 binary: real positions + rgb + opacity)
36+
→ /torso-live three.js orbit (reads SPL1; the "live orbit")
37+
→ torso.ply (Inria) → ndarray splat3d_flex → frames → /torso (the "splat", CPU)
38+
```
39+
40+
`splat3d` (ndarray, CPU-SIMD, no GPU) renders bake-side via its own 1.95 toolchain
41+
(q2 stays clean of the ndarray dep). Both pages read ONE asset → identical geometry.
42+
43+
## Checklist
44+
45+
- [x] `tools/bake_torso_splat.py` — BodyParts3D → SPL1 gaussian asset + manifest
46+
(231K gaussians, 577 meshes, 102 structures; muted pastel per-structure hues)
47+
- [x] `cockpit/public/torso.splat` (3.7 MB) + `torso.manifest.json` (attribution/legend)
48+
- [x] SPL1 TS decoder + `/torso-live` three.js orbit page + route
49+
- [x] `/torso` splat3d CPU render: scratchpad `torso-render` driver reads SPL1 →
50+
`Gaussian3D` → ndarray::hpc::splat3d turntable (no Inria .ply needed) →
51+
20 JPEG frames in `cockpit/public/torso-frames/``/torso` viewer page + route
52+
- [x] attribution surfaced in-UI; tsc clean
53+
- [ ] PR
54+
55+
Notes:
56+
- The CPU render runs under ndarray's own 1.95 toolchain (scratchpad project,
57+
path-dep on ../ndarray) — q2's workspace stays free of the ndarray dep.
58+
~6.6 s/frame on the scalar path (no AVX target-cpu in the scratchpad project);
59+
correctness verified by viewing the rendered frames.
60+
- Colours: golden-angle hue per structure at S=0.34 V=0.78 (muted, per request).
23 KB
Loading
23.2 KB
Loading
24.1 KB
Loading
25.4 KB
Loading
26.8 KB
Loading
27.8 KB
Loading
27.9 KB
Loading
27.5 KB
Loading
26.6 KB
Loading

0 commit comments

Comments
 (0)