git clone git@github.com:openbraininstitute/morphoviewer.git
cd morphoviewerThen, you will need two terminals:
cd lib
npm install
npm startcd doc
npm install
npm startThe development of this software was supported by funding to the Blue Brain Project, a research center of the École polytechnique fédérale de Lausanne (EPFL), from the Swiss government's ETH Board of the Swiss Federal Institutes of Technology.
Copyright (c) 2024 Blue Brain Project/EPFL Copyright (c) 2025 Open Brain Institute
- Make the fitted-sphere soma opt-in through
somaAsSphereonMorphoViewerSmallCircuit, defaulting tofalse. v0.32.0 always replaced the file's contour chain with one sphere, which moves the drawn surface out from under synapses positioned against the file's geometry. Branches leaving the soma keep their own radius and colour either way - Keep the camera when only the query part of a cell's
idchanges. A host can use it as a reload key — flipping an axon toggle, say — to rebuild a cell's morphology in place without the view refitting and losing the user's zoom
- Add morphology location picking to
MorphoViewerSmallCircuit: a pointer resolves to a(section, offset)point on a cell, reported throughlocationSelectionas pick, hover and label events- Segment picking runs on its own offscreen buffer at half resolution; the existing cell-level hover and click keep their coarser, cheaper one, which was too lossy to hit a thin dendrite
- The per-segment index rides in the free
vUV channel, so no extra vertex attribute is needed MorphoViewerTreeItemcarriessonataSectionId, letting a host name the branch a click landed on
- Draw the soma as a single fitted sphere rather than the morphology file's contour chain, which rendered as a string of capsules where the instantiated cell shows one compact body
- Give branches leaving the soma their own radius and colour. They inherited both from their parent — a soma contour point — which drew a fat, soma-coloured cone off the cell body for every branch. Visible only once cells are coloured by section type, but wrong before that too
- Per-section-type cell colours via
SectionColorsonMorphoViewerSmallCircuitCell.color, alongside the existing flat colour
- Fix adaptive resolution in
MorphoViewerSomasOnlylowering the render resolution on machines fast enough not to need it- Ending an interaction now always closes the measurement window. It did not when the resolution had never been reduced — i.e. always, on a fast GPU — which left the detector armed for the rest of the session and judging idle repaints, whose spacing reflects how often something asked for a repaint rather than how long a frame takes
- Entering fullscreen or changing the colours no longer degrades the view
- Decide on the median of the last 8 frames instead of a single frame, so a one-off stall (layout, point cloud rebuild, garbage collection) no longer collapses the resolution
- Give the resolution back as soon as frames are fast again; a reduction used to persist for the lifetime of the viewer, so one bad measurement degraded every later interaction
- Limit a single adjustment to at most halving or +40% of the pixel count, and discard frames slower than 1s as stalls rather than steady-state render cost
- Ignore frames measured across a canvas resize or a recolor, which stall the main thread without saying anything about rendering speed
- Restore
context.resolutionfrom afinallyblock in snapshot, so a failed capture can no longer strand the canvas at device-pixel resolution with the gizmo hidden
- Add world-space overlay point clouds to
MorphoViewerSmallCircuitandMorphoViewerSomasOnlyviaoverlays- Per-group color, optional
id/kind/origin/rotationfor placement metadata
- Per-group color, optional
- Add interactive overlay transforms (
overlaysInteractive,onOverlayTransform)- Left-drag translates; right-drag / Alt-drag / Shift-drag rotates
- Emits absolute origin + rotation with
phase: "end"on pointer-up so hosts can sync forms without mid-drag churn
- Add
highlightedOverlayIdfor host-controlled overlay selection highlighting - Add
neuronOpacityto fade neuron geometry while keeping overlay markers fully opaque - Add
overlaysRadius/overlaysMinRadiusInPixelsfor overlay marker sizing
- Fix bounding box computation in
MorphoViewerSmallCircuitby recentering each cell's bbox around its soma center- Prevents camera framing issues when morphologies extend asymmetrically from their soma
- Add
zoomoption tocameraResetsignal for controlling zoom level on reset - Simplify snapshot pipeline by removing the
reencodeSnapshotstep and passing options directly totakeSnapshot - Export additional scalebar types (
ScalebarLabelsConfig,ScalebarOrientation,ScalebarPinsConfig,ScalebarPlacement,ScalebarSide,ScalebarWhen) - Refactor
PainterCellinto separatePainterCellFlatandPainterCellIdsubclasses for cleaner separation of concerns
- Add per-cell soma coloring to
MorphoViewerSomasOnlyvia optionalcoloron each cell info- Distinct colors map to a categorical palette; recolor-only updates preserve the camera
- Extend scalebar with vertical orientation, placement, hover-revealed pins/labels, and hiDPI rendering
- Add
resetCameraSignaltoMorphoViewerSomasOnlyandMorphoViewerSmallCircuitfor host-triggered camera reset - Preserve camera position on recolor-only circuit updates in
MorphoViewerSmallCircuit
- Add version tracking via
data-versionattribute on root elements ofMorphoViewerOctree,MorphoViewerSimul,MorphoViewerSmallCircuit, andMorphoViewerSomasOnly - Add synapses support to
MorphoViewerSmallCircuit- New
synapses,synapsesRadius, andsynapsesMinRadiusInPixelsprops - Dynamically updates synapse rendering without recreating the painter
- New
- Fix minimum size for synapses in
MorphoViewerSimulto prevent them from disappearing at certain zoom levels - Simplify cell highlighting logic in
MorphoViewerSmallCircuitby computing black state inline during cell addition - Fix the issue with
TGDMaterialFlatTexturethat couldn't change the texture once created.
- PointsClouds were using square with back facing.
- Fix depth issue with synapses in
MorphoViewerSimulby disabling depth precision on synapse painter - MorphoViewerSomasOnly now uses an adaptative resolution decreaser to adpat to different GPU.
- Add optional somaRadius prop to
MorphoViewerSomasOnlyfor controlling the rendered soma size at runtime- Defaults to
12when not provided - Dynamically updates without recreating the points cloud by leveraging
radiusMultiplier
- Defaults to
- Optimize bounding box computation in
PainterCellInfosto avoid per-pointaddSpherecalls- Computes center and extents in a single pass for better performance on large datasets
- Reduce resolution during camera movement in
MorphoViewerSomasOnlyfor smoother interaction on large circuits- Resolution scales down based on cell count (threshold at 250k cells)
- Full resolution is restored after 50ms of inactivity
- Simplify ambient occlusion algorithm in
MorphoViewerSomasOnlyfor faster computation- Increase AO sampling radius from
10×to15×cell radius
- Increase AO sampling radius from
- Refactor
addLiaisonsinMorphoViewerSimulto use iterative traversal instead of recursion because this breaks in Chrome - Remove leftover
console.logdebug statement fromMorphoViewerSimul
- Fix missing colors for segments.
- Add optional per-block color support to
MorphoViewerOctreeMorphoViewerOctreeMeshTypenow accepts an optionalcolorstring property- Octree blocks with a custom color override the default material at render time
- New points cloud painter that overcome the MacOS limitation of 64px for points sizes.
- Apply darker colors for more dense zones.
- Enable specular lighting on soma sphere rendering (
specularExponent: 50) - Simplify color palette to 3 gradient stops for cleaner visual appearance
- Add full spinner overlay styling to
MorphoViewerSpinnercomponent - Remove leftover
console.logandcamera.debug()debug statements
- Fix event listener leak in
MorphoViewerSmallCircuitcamera adaptation: the paint event listener was never removed, causing infinite re-registration on each paint cycle
- Add optional
verboseprop toMorphoViewerSmallCircuitfor enabling/disabling debug console output - Refactor
MorphoViewerSmallCircuitrendering pipeline: removeTgdFilterBlur,TgdPainterFilter,TgdPainterFramebufferWithAntiAliasing, andTgdPainterMixfor a leaner rendering approach - Refactor
CameraManagerto useTgdControllerCameraOrbitwith smooth camera interpolation viatgdActionCreateCameraInterpolation - Use
TgdValueWaitablefor lazy context initialization inPainterManager - Add
isDeletedguard inOffscreenPainterto prevent operations after deletion
- Increase default minRadius from
0.25to2.5inMorphologyCanvasand from2to2.5inSwcPainterfor better rendering of thin neurites - Remove leftover
console.logdebug statements fromAbstractCanvas,SwcPainter, and NRRD parser
- Enable antialiasing on
MorphoViewerSmallCircuitWebGL context for smoother rendering - Remove leftover
console.debugstatement fromMorphoViewerSimul
- Add section-based coloring to
MorphoViewerSmallCircuit- Cell
colorprop now accepts aSectionColorsobject with per-section colors (soma, axon, myelin, apicalDendrite, basalDendrite, unknown) - Uses a texture palette for rendering distinct colors per morphology section type
- Cell
- Add
Myelinentry toCellNodeTypeenum - Add new
morphoViewerConvertSwcIntoTreeutility function for converting SWC file content into aMorphoViewerTreestructure - Export
morphoViewerConvertSwcIntoTreefrom the library entry point
- Improve Octree misalignment tester (
tst/) with margin-based bounding box comparison to handle float precision errors- Add
SuccessGridcomponent displaying per-LOD-level success/failure counts - Add restart button and hide file selector after loading
- Use
rehype-rawfor richer Markdown rendering in reports
- Add
- Add loading progress indicator to
MorphoViewerOctreedoc page (bytes loaded, blocks in progress) - Remove leftover
console.logdebug statement fromOctreeManager - Split
typedocscript intodoc(single run) anddoc:watch(watch mode)
- Add new
MorphoViewerScalebarcomponent (lib/src/components/morpho-viewer-scalebar/) for displaying a dynamic scale bar- Renders graduated tick marks with auto-scaled units (m, mm, μm, nm, pm, fm)
- Accepts a
spacePerPixelevent to reactively update when the camera zooms - Supports custom positioning via an optional
classNameprop
- Add optional
scalebarprop toMorphoViewerSmallCircuitandMorphoViewerOctree- Accepts
booleanor a CSS class name string for custom styling
- Accepts
- Switch camera from perspective to orthographic projection for
MorphoViewerSmallCircuitandMorphoViewerOctree- Enables accurate scale bar measurements
- Add
space-per-pixelbehavior (lib/src/behaviors/) to broadcast camera zoom level changes - Rename
controls-layer/directory tocontrols-layout/for consistency - Fix CSS specificity issues by scoping canvas styles to a
.webglclass
- Add new
ControlsLayoutcomponent (lib/src/components/controls-layer/) for configurable viewer header controls- Supports built-in actions:
fullscreen,reset-camera,minimize,close - Accepts arbitrary
React.ReactNodeelements alongside named actions - Groups can be nested in arrays for flex-based layout with
space-betweenjustification
- Supports built-in actions:
- Add
controlsprop toMorphoViewerSmallCircuitto allow custom header control layouts- Falls back to a default layout (
reset-camera,fullscreen,close,minimize) when not provided
- Falls back to a default layout (
- Add
onMinimizecallback prop toMorphoViewerSmallCircuit - Replace hardcoded
<header>markup inMorphoViewerSmallCircuitwith the newControlsLayoutcomponent - Update
MorphoViewerSmallCircuitdoc page to demonstrate the configurable controls
- Add optional
gizmoprop toMorphoViewerSmallCircuitfor displaying an axes orientation controller- Accepts
booleanor aPartial<TgdPainterGizmoOptions>object (alignX,alignY,size,margin) - Dynamically updates gizmo position, size, and visibility at runtime
- Accepts
- Reuse
GizmoSettingscomponent in theMorphoViewerSmallCircuitdoc page for interactive gizmo configuration - Move
GizmoSettingscomponent to shareddoc/src/components/gizmo-settings/directory - Remove leftover
console.logdebug statements fromOctreeManager - Fix import ordering in
tst/rspack.config.mjs
- Add optional
gizmoprop toMorphoViewerOctreefor displaying an axes orientation controller- Accepts
booleanor aPartial<TgdPainterGizmoOptions>object (alignX,alignY,size,margin) - Dynamically updates gizmo position, size, and visibility at runtime
- Accepts
- Add
GizmoSettingspanel in the doc app for interactive gizmo configuration - Add nested route
/morpho-viewer-octree/gizmo-settingsin the doc app - Upgrade
@tolokoban/tgddependency from^2.0.126to^2.0.130to fix a bug in Gizmo resizing
- Add Tauri-based testing tool (
tst/) for checking LOD blocks bounding boxes potential misalignements