medOS ultra

Body Model Anatomy Variants

Gender-affirming and post-surgical anatomy variants for the 3D body model.

4 min read diagramsUpdated 2026-05-30docs/architecture/body-model-anatomy-variants.md

Status: design (not yet implemented). Companion to the 3D body-model + SNOMED region system (web/packages/medical-kit/src/body-model-3d/). This doc is for the session/owner handling the base anatomy gap; it layers cleanly on top of that work.

Problem

The model today has two base meshes (male, female) and sex-specific organ sets (male: prostate/testes; female: uterus/ovaries/breasts). Real patients aren’t always one of those two fixed sets:

  • Gender-affirming anatomy — trans women (MTF), trans men (FTM), non-binary, and intersex patients have anatomy that mixes/alters the base sets (e.g., a trans man post-mastectomy + hysterectomy with a neophallus).
  • Post-surgical states (any patient) — post-mastectomy, post-hysterectomy, nephrectomy, amputation, colostomy/ileostomy, orchiectomy, etc. A region may be absent, altered, or reconstructed, and there may be new structures (neo-organs, stomas) that don’t exist on either base mesh.

Hard-coding more “models” doesn’t scale. Instead, model anatomy as a profile that layers region-level overrides + additions on top of a base mesh.

Core rule (non-negotiable)

Anatomy ≠ gender identity. This profile describes what tissue/organs are physically present for clinical care (dosing, screening, exam, imaging). It is decoupled from gender identity, pronouns, legal sex, and the “MTF/FTM” labels — those live in the demographic/identity record, never inferred from anatomy and never the other way around. The presets below are starting points a clinician edits, not assumptions applied from an identity field. (See also the platform’s inclusivity / patient-dignity stance.)

Data model

type RegionStatus = 'present' | 'absent' | 'altered' | 'reconstructed';

interface AnatomyRegionState {
  regionId: string;                 // key in COORDINATE_SETS
  status: RegionStatus;
  /** SNOMED procedure/finding that explains the state (e.g. mastectomy 172043006). */
  procedureSnomedCode?: string;
  note?: string;                    // free text, e.g. "TRAM flap 2023"
}

interface AnatomyAddition {
  /** New structure not on the base mesh — neo-organ, stoma, flap, expander. */
  id: string;
  label: string; labelTh?: string;
  snomedCode?: string;              // body-structure SCTID where one exists
  /** Anchor: reuse an existing region position, or an explicit 3D point. */
  anchorRegionId?: string;
  position?: [number, number, number];
  kind: 'neo-organ' | 'stoma' | 'reconstruction' | 'device';
}

interface AnatomyProfile {
  baseModel: BodyModelId;           // 'male' | 'female' (which mesh to render)
  overrides: AnatomyRegionState[];  // change status of base regions
  additions: AnatomyAddition[];     // add structures the base mesh lacks
}

The profile is per-patient (Supabase anatomy_profiles row keyed by patient, or an encounter-scoped snapshot). It is read-only to the viewer.

Rendering contract (additive to BodyModelViewer)

BodyModelViewer gains an optional anatomyProfile?: AnatomyProfile prop. Resolution:

  1. Render the baseModel mesh.
  2. Start from COORDINATE_SETS[baseModel]; apply overrides:
    • absenthide the region’s marker/overlay; if a diagnosis/device targets it, surface a “region absent” affordance rather than a silent drop.
    • altered / reconstructed → render the marker with a small status badge (e.g. ⚑) and expose the procedureSnomedCode + note in the popup.
    • present → unchanged.
  3. Append additions as extra regions (reuse the icon-overlay path; neo-organs/stomas get their own SCTID + label, grounded exactly like the existing region set).

No change to the grounding guarantee — every state references a real region id or a real SCTID; nothing is invented at render time.

Presets (clinician-editable starting points)

Preset Base Overrides Additions
Trans woman (MTF), post-op male testes absent (orchiectomy), prostate present* breast-L/R (augmentation), neovagina (vaginoplasty)
Trans man (FTM), post-op female breast-L/R absent/reconstructed (chest reconstruction), uterus absent (hyst), ovaries absent (oophorectomy) neophallus (phalloplasty/metoidioplasty)
Non-binary / partial either any subset of the above any subset
Intersex either per individual per individual
Post-mastectomy any breast absent (or reconstructed + implant/flap addition) optional reconstruction
Amputation any limb region(s) absent optional stump/prosthesis marker
Ostomy any stoma addition (colostomy/ileostomy/urostomy)

* prostate is typically retained in MTF surgery — flagged because it remains a screening target; this is exactly why anatomy must be tracked independently of identity.

SNOMED anchors (look up exact active SCTIDs from the RF2 release at build time)

  • Neo-organs/structures: neovagina, reconstructed breast, constructed phallus, colostomy stoma, ileostomy stoma, urostomy stoma all have SNOMED body-structure or morphologic concepts — resolve via the same import-snomed-terminology.mjs flow used for the region pack (add codes to CODES, regenerate anatomy.seed.ts).
  • Procedure context: mastectomy, hysterectomy, oophorectomy, orchiectomy, vaginoplasty, phalloplasty, amputation — SNOMED procedure concepts stored on procedureSnomedCode.

(Do not hand-write SCTIDs — pull them from the release like every other region, so they’re guaranteed active.)

Why this fits the existing system

  • The base-mesh choice reuses the existing bodyModel registry.
  • Overrides/additions reuse COORDINATE_SETS + the icon-overlay renderer + the grounding guard — no new rendering pipeline.
  • It is purely additive: a patient with no profile renders exactly as today.

Open questions for the implementing session

  1. Storage: dedicated anatomy_profiles table vs an extension on the patient/encounter read model? (Leaning: its own table, encounter can snapshot.)
  2. Authoring UI: a small editor (toggle region status, add structures from a SNOMED picker) — likely a new admin/clinical surface.
  3. How absent regions interact with diagnosis/device tagging (block? warn? allow with a flag) — needs a clinical decision.
  4. Pediatric/teen meshes (scaffolded) get the same profile treatment once calibrated.
Ask Anything