Skip to content

Fix 3D meshes never loading for uploaded scans - #129

Merged
aperson30 merged 1 commit into
mainfrom
fix/session-3d-meshes
Aug 6, 2026
Merged

Fix 3D meshes never loading for uploaded scans#129
aperson30 merged 1 commit into
mainfrom
fix/session-3d-meshes

Conversation

@aperson30

Copy link
Copy Markdown
Collaborator

Problem

When you upload a scan and open it in the viewer, the 2D panes render fine but the
3D pane hangs forever on "Loading 3D segmentation..." (see the stuck viewport
in a /session/<uuid> view).

Cause

MeshViewer fetches /api/cases/<id>/mesh-manifest, which only serves pre-baked
dataset meshes
(get_panTS_id + MESH_PATH, generated offline by
preprocess_meshes.py). For a session the id is a UUID, so that route 404s,
manifest stays null, and the pane never renders. Inference never generated any
session meshes, so there was nothing to serve.

Fix — generate session meshes on demand, reusing the existing machinery

Backend

  • GET /api/sessions/<id>/mesh-manifest — builds the manifest from the session's
    combined_labels (generate_mesh_manifest(..., route_base="sessions")).
  • GET /api/sessions/<id>/render_only/<file> — marching-cubes the requested organ
    out of combined_labels (generate_organ_glb_bytes), cached next to the mask
    so organ toggles / revisits don't recompute.
  • generate_mesh_manifest gains a route_base arg so organ URLs point at the
    session route; default "cases" keeps dataset behaviour byte-for-byte.
  • Register liver_lesion/kidney_lesion/colon_lesion (33/34/35) in mesh LABELS
    so the four LesionSegmenter lesions also get 3D meshes (absent labels are skipped).

Frontend

  • fetchMeshManifest/SegmentationMeshViewer take an isSession flag;
    VisualizationPage passes it for session routes. Organ GLB URLs come from the
    manifest, so no other frontend change is needed.

Verification

  • npm run build (tsc + vite) passes on the server toolchain.
  • Runtime-tested against a real session combined_labels.nii.gz:
    generate_mesh_manifest(route_base="sessions") returns organs with correct
    /api/sessions/<id>/render_only/*.glb URLs, and generate_organ_glb_bytes
    produced a valid ~1 MB GLB.

The 3D pane hung on "Loading 3D segmentation..." for every uploaded scan.
MeshViewer fetches /api/cases/<id>/mesh-manifest, which only serves pre-baked
dataset meshes via get_panTS_id + MESH_PATH; for a session id (a UUID) it 404s,
so the manifest stayed null and the pane never rendered. Inference never
generated session meshes.

Add on-demand session meshes, reusing the existing mesh machinery:
- GET /api/sessions/<id>/mesh-manifest: builds the manifest from the session's
  combined_labels (generate_mesh_manifest with route_base="sessions")
- GET /api/sessions/<id>/render_only/<file>: marching-cubes the requested organ
  from combined_labels (generate_organ_glb_bytes), cached next to the mask
- generate_mesh_manifest gains a route_base arg so organ URLs point at the
  session route (default "cases" keeps dataset behaviour unchanged)
- MeshViewer/fetchMeshManifest take isSession; VisualizationPage passes it for
  session routes
- register liver/kidney/colon_lesion (33/34/35) in mesh LABELS so the four
  LesionSegmenter lesions also get 3D meshes (absent labels are skipped)
try:
glb_bytes = generate_organ_glb_bytes(organ_key, seg_path)
except ValueError as e:
return jsonify({"error": str(e)}), 404
@aperson30
aperson30 merged commit 9573b94 into main Aug 6, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants