import {flushSync} from 'react-dom'; import {registerAtlasTools} from './agent-tools'; import {useEffect,useMemo,useRef,useState} from 'react'; import {Activity,ArrowUpRight,ChevronRight,Focus,Info,Layers3,Pause,RotateCcw,RotateCw,Search,X} from 'lucide-react'; import {Button} from '@/components/ui/button'; import {Badge} from '@/components/ui/badge'; import {Slider} from '@/components/ui/slider'; import {Switch} from '@/components/ui/switch'; import {Sheet,SheetContent,SheetTitle,SheetDescription} from '@/components/ui/sheet'; import {Combobox,ComboboxInput,ComboboxContent,ComboboxList,ComboboxItem,ComboboxEmpty} from '@/components/ui/combobox'; import AnatomyScene from './scene'; import {DEFAULT_VISIBLE,SYSTEMS,EXPLANATIONS,explanation,type Atlas,type Concept,type SceneState,type SystemId,type View} from './anatomy'; const initial:SceneState={explode:0,visible:DEFAULT_VISIBLE,selected:[],isolate:false,view:'three-quarter',rotate:false,reset:0}; export default function Home(){ const detailTitle=useRef(null); const [atlas,setAtlas]=useState(null),[state,setState]=useState(initial),[progress,setProgress]=useState(0),[error,setError]=useState(''),[panel,setPanel]=useState<'layers'|'search'|null>(null),[details,setDetails]=useState(false),[about,setAbout]=useState(false),[query,setQuery]=useState(''),[chosen,setChosen]=useState(null); useEffect(()=>{const abort=new AbortController();setProgress(0);setError('');setAtlas(null);setChosen(null);setDetails(false);setState({...initial,visible:DEFAULT_VISIBLE});fetch('/models/atlas.json',{signal:abort.signal}).then(r=>{if(!r.ok)throw new Error('The anatomy catalogue could not be loaded.');return r.json();}).then(data=>setAtlas(data as Atlas)).catch(e=>{if(e.name!=='AbortError')setError(e.message);});return()=>abort.abort();},[]); useEffect(()=>{const key=(e:KeyboardEvent)=>{if(e.key==='/'&&!(e.target instanceof HTMLInputElement)&&!(e.target instanceof HTMLTextAreaElement)){e.preventDefault();setPanel('search');setDetails(false);}};window.addEventListener('keydown',key);return()=>window.removeEventListener('keydown',key);},[]); const parts=useMemo(()=>new Map(atlas?.parts.map(p=>[p.id,p])),[atlas]); const counts=useMemo(()=>Object.fromEntries(SYSTEMS.map(s=>[s.id,atlas?.parts.filter(p=>p.system===s.id).length??0])),[atlas]); const activeSystems=SYSTEMS.filter(s=>counts[s.id]>0); const selectedParts=state.selected.map(id=>parts.get(id)).filter(p=>!!p),selected=selectedParts[0],system=SYSTEMS.find(s=>s.id===selected?.system); const visibleCount=atlas?.parts.filter(p=>state.isolate?state.selected.includes(p.id):state.visible.includes(p.system)||state.selected.includes(p.id)).length??0; const results=useMemo(()=>{if(!atlas)return[];const term=query.toLowerCase().trim();if(!term)return ['heart','brain','liver','stomach','spleen','pancreas','urinary bladder','trachea'].map(name=>atlas.concepts.find(c=>c.name.toLowerCase()===name)).filter((x):x is Concept=>!!x);return atlas.concepts.filter(c=>c.name.toLowerCase().includes(term)||c.id.toLowerCase().includes(term)).sort((a,b)=>a.name.length-b.name.length).slice(0,80);},[atlas,query]); const choose=(c:Concept)=>{setChosen(c);setState(s=>({...s,selected:c.elements,isolate:false,rotate:false}));setDetails(true);setPanel(null);}; useEffect(()=>{if(!atlas)return;return registerAtlasTools(atlas,c=>flushSync(()=>choose(c)));},[atlas]); const choosePart=(id:string)=>{const p=parts.get(id);if(!p)return;setChosen({id:p.conceptId,name:p.name,elements:[id]});setState(s=>({...s,selected:[id],isolate:false,rotate:false}));setDetails(true);setPanel(null);}; const toggle=(id:SystemId)=>{setDetails(false);setState(s=>({...s,selected:[],isolate:false,visible:s.visible.includes(id)?s.visible.filter(x=>x!==id):[...s.visible,id]}));}; const reset=()=>{setState(s=>({...initial,visible:DEFAULT_VISIBLE,reset:s.reset+1}));setChosen(null);setDetails(false);setPanel(null);}; const openPanel=(next:'layers'|'search')=>{setDetails(false);setPanel(p=>p===next?null:next);}; return
{atlas&&0}} onSelect={choosePart} onProgress={n=>{setProgress(n);if(n===100)setError('');}} onError={setError}/>}
INTERACTIVE ANATOMY

Human Atlas3D

{atlas?atlas.parts.length.toLocaleString():'2,234'} modeled pieces · BodyParts3D
Systems{activeSystems.length}
{activeSystems.map(s=>
toggle(s.id)} aria-label={`Show ${s.name.toLowerCase()}`} />
)}
{visibleCount.toLocaleString()} pieces visible
{panel==='search'&&
Find a structure
items={results} value={null} onValueChange={value=>{if(value)choose(value);}} inputValue={query} onInputValueChange={setQuery} itemToStringLabel={c=>c.name} filter={null} open onOpenChange={open=>{if(!open)setPanel(null);}}>No structures match your search.{(c:Concept)=>{c.name}{c.elements.length} {c.elements.length===1?'piece':'pieces'}}

{query?'Showing up to 80 matches. Refine your search to find smaller structures.':'Start with a major organ, or search every named structure.'}

}
{state.isolate?(chosen?.name??'SELECTED STRUCTURE'):state.explode>.95?'ANATOMICAL INVENTORY':state.explode>.05?'SEPARATED STRUCTURES':'ADULT HUMAN · MALE'}
{Math.round(state.explode*100)}%
setState(s=>({...s,explode:(Array.isArray(v)?v[0]:v)/100,view:(Array.isArray(v)?v[0]:v)>80?'front':s.view,rotate:false}))}/>
AssembledEvery piece
{state.explode>.8?'Drag to pan':'Drag to orbit'} · Pinch to zoom · Tap to inspect
{progress<100&&!error&&
Preparing the anatomy{progress}% · Loading {atlas?.parts.length.toLocaleString()??'2,234'} pieces
} {error&&

{error}

} 0} modal={false} disablePointerDismissal onOpenChange={setDetails}>
{system?.name??'ANATOMY'}
{chosen?.name}
{chosen&&selected?explanation(chosen.name,selected.system):''}{chosen&&!EXPLANATIONS[chosen.name.toLowerCase()]&&System overview · structure identified from source anatomy}
Atlas reference{chosen?.id}Selected pieces{state.selected.length.toLocaleString()}
{selectedParts.length>1&&

Included structures

{selectedParts.slice(0,50).map(p=>)}{selectedParts.length>50&&

And {selectedParts.length-50} more modeled pieces.

}
}View anatomical source
SOURCE & SCOPE
A body, revealed.Explore the adult male reference anatomy from BodyParts3D.

Male · BodyParts3D
2,234 individual meshes and 3,432 named concepts from an adult male reference anatomy.

This reference does not contain every human structure or variation. Named concepts can contain multiple pieces; each source mesh is rendered once.

Colors and system groupings are designed for exploration. The geometry is simplified for the web, and short explanations provide general educational context. This is an anatomical reference, not a diagnostic or surgical tool.

Source

BodyParts3D, © The Database Center for Life Science licensed under CC Attribution 4.0 International.

Dataset license Original geometry & metadata Read the source publication
; }