Changelog
Source:NEWS.md
threeBrain 1.4.0
Rendering Engine:
- The viewer now renders with
WebGPU, the successor toWebGL. Browsers or pages withoutWebGPUkeep working: the viewer falls back toWebGL2by itself, and both draw the same picture. Ashinyapp served over plainhttpfrom anything but the local machine is such a page, since browsers only exposeWebGPUin secure contexts - All custom shaders (surfaces,
MRIslices, volumes, electrodes, streamlines and fat lines) were rewritten asthree.jsnode materials, becauseWebGPUcannot compile the previousGLSLcode - A viewer whose
GPUdevice is lost (a driver reset, or a laptop waking up) now shows a message with a reload button instead of freezing - In
shiny, a viewer that gets re-inserted (for example byrenderUI()) reuses its cached viewer. Every re-insert used to build a second viewer while the first one kept its graphics contexts, so a few re-inserts exhausted the browser’s supply of them - Screenshots and video recordings no longer drop the side-panel titles
- Debug mode reports frame timings with the
three.jsInspectorpanel, replacingstats-gl, which always reported zeroGPUtime
Standalone Viewers (save_brain):
- A saved viewer now carries its web worker inside the page, so opening the file from disk no longer logs worker errors in
Chrome,SafariandFirefox. Volume gradient maps, which were silently skipped in saved viewers, are computed again, and surfaces and streamlines do their heavy set-up off the main thread as they do on a server - Wherever a worker genuinely cannot start, the viewer now says so once and does the work on the main thread instead. It used to try again for every surface and every volume, and one code path waited forever for a worker that never existed
Volume Rendering Improvements:
- Added precomputed gradient textures for faster normal calculation during volume rendering
- Implemented 3D
Sobelfilter for computing gradients on both continuous (MRI) and discrete (atlas parcellation) volume data - Added
MatCap(Material Capture) texture-based lighting for improved visual quality of volumetric surfaces - Introduced gradient-based opacity modulation for continuous data visualization
- Added adaptive fast-pass empty space skipping with ray-angle-aware step sizing for improved rendering performance
- Added slice material instead of
RawMaterialto wrap up changes to theuniforms - Rewrote slice sampling method (super-sampling rather than completely linear interpolation) to improve the user experience when inspecting MRI slices
- Added outline mode for discrete overlays
- Added slice threshold, a user controller to strip the skulls
- Volume slice masks work even when orientation and dimensions are different
- Improved lazy rendering so the canvas does not forces the
GPUto render unless there is a need to
Worker Thread Infrastructure:
- Added
invokeWorker()method toViewerAppfor unified worker thread dispatch with fallback support - Added
ArrayBuffertransferable support for zero-copy data transfer between main thread and workers - Registered
computeVolumeGradientsas a worker-callable function for offloading heavy gradient computation - Better fallback method for workers who don’t get new job spawned
- Worker spawn is throttled
- Worker results that transfer their buffers back are no longer posted a second time. The repeat post tried to clone the already-detached buffers and logged an unhandled
DataCloneError(TypeError: Type errorin Safari) for every surface - Errors thrown inside a worker are now reported back to the viewer, so the request falls back to the main thread instead of waiting forever
Shader Optimizations:
- Converted
colorChannelsandditheringuniforms to compile-time shader defines for better GPU performance - Added
USE_GRADIENT_MAPandSINGLE_CHANNELshader variants for optimized code paths - Implemented two-sided lighting with proper view-space normal correction
- Added a per-camera lighting node (
ViewLighting) so the four views (main plus three side canvases), which intentionally light with different lights, no longer evict and rebuild each other’s compiled shader and pipeline on every switch, several times a frame
Engine Updates:
- Upgraded
three.jsengine tor185 - Replaced the deprecated
three.jsClockwith a single sharedTimer, advanced once per frame, so all animation deltas within a frame come from one time base - Rebased the vendored fat-line material onto
r185and gave it a private shader key so it no longer competes with the upstream one - Removed
jsmfolder; optimized electrode shader to calculate inversemodelViewProjectionin JavaScript rather than vertex-shader - Updated
jsPDFversion
Main Camera Controls:
- Rewrote the main-camera trackball on top of the
three.jsControlsbase class and Pointer Events, replacing the separate mouse and touch handler pairs it had carried sincer80. Drags now use pointer capture, so releasing the button outside the viewer (or outside the browser window) no longer leaves the camera spinning, and pen input works like a mouse - Wheel zoom now normalizes
event.deltaMode. Firefox reports wheel deltas in lines rather than pixels, which made one wheel notch zoom roughly 30x less there than in Chrome; both now zoom at the same rate - Wheel zoom, drag zoom, and pinch zoom are anchored on the cursor, so the point under the pointer stays put as you zoom. Set
canvas.trackball.cursorZoom = falsefor the previous zoom-to-center behavior - Pointer coordinates are taken from
getBoundingClientRect()instead of the deprecatedwindow.pageXOffset, so rotation and panning stay aligned after the surrounding page scrolls - Measuring the viewer while it has no layout (a hidden
shinytab,display: none) no longer produces aNaNcamera and a permanently blank canvas - Removed the trackball’s undocumented
A/S/Dkey bindings, which used the deprecatedkeyCodeAPI and collided with the viewer’s owna,s, anddshortcuts - Resetting the main camera now discards any zoom or pan still being damped out, so the reset lands exactly on the initial camera instead of being nudged off it by the tail of the last interaction
- The
wheellistener is registered as non-passive, removing the Chrome console warning the viewer used to emit on every load - Rotating, panning or zooming the main view no longer redraws the side panels, whose picture does not depend on the main camera. They are still redrawn whenever anything else changes, and always while animating, while the slice cameras follow the main camera, and while recording
Control Panel:
- The control panel’s widgets now run on
Tweakpaneinstead oflil-gui. TheaddController()/onChange()/folder API is unchanged, so existingcontrollers = list(...)calls keep working for every controller not renamed below - Added a range controller: one control with two handles for settings that are really a min/max pair.
Frustum Near/Frustum Farbecame a singleFrustumcontroller, andLine MinLen/Line MaxLenbecame a singleLine Lengthcontroller -
Breaking:
Frustum Near/Frustum FarandLine MinLen/Line MaxLenare replaced by theFrustumandLine Lengthrange controllers above. Update anycontrollers = list("Frustum Near" = ..., "Frustum Far" = ...)tocontrollers = list("Frustum" = list(min = ..., max = ...)), andcontrollers = list("Line MinLen" = ..., "Line MaxLen" = ...)tocontrollers = list("Line Length" = list(min = ..., max = ...)) - The electrode animation panel gained a
Display Data (Graph)line plot: it traces the focused electrode’s value over the recording’s time axis with a play-head cursor, and stays hidden unless a continuous variable with more than one time point is shown on the focused electrode -
Voxel LabelandLine Simplify Factornow recompute only once a drag or edit finishes, rather than on every intermediate value while dragging - Changing
Background Coloralso refreshes the activity graph above once the color stops changing, keeping its colors in sync with the panel theme -
Copy Controller StateandPaste to Set Statestill save and restore panel values under the new panel engine - Buttons in the control panel span the full row instead of being capped to the width of a value field
View Layouts:
- Added a
View Layoutcontroller (underVolume Settings, afterShow Panels) for slice-centered layouts similar toITK-SNAP:3dview(the default, unchanged),sliceview-flat(the three slices in a row),sliceview-axial,sliceview-coronal,sliceview-sagittal(one slice featured large) andsliceview-twobytwo(a 2x2 grid). Set it from R withcontrollers = list("View Layout" = "sliceview-twobytwo") - The featured layouts arrange themselves by the viewer’s shape: at 5:2 or wider the featured slice sits next to the other two, down to 4:3 it sits below them, and in a viewer narrower than 4:3, which leaves no room for the 3D view, the 2x2 grid is used instead
- In
sliceview-*layouts the slice panels are locked in place, the 3D view is framed in the foreground color, and the canvas text (legend, timestamp, title) scales with the 3D view so it does not crowd a small panel - Keyboard:
lcycles the view layouts;Voxel Displaymoved toShift+L
Streamline Visualization:
- Streamlines are simplified before they are drawn, with the new
Line Simplify Factorcontroller: a bundle’s points are dropped while the drawn line stays within that many millimeters of the original, and 0 draws every point. Tract files are often resampled far finer than the screen can show (theCIT168alicbundles carry a point every 0.08 mm), and every segment is transformed again in each of the four views. At the default 0.05 mm, those bundles draw 14 times fewer segments, use a third of the graphics memory, and take between a fifth and a tenth of the frame time they used to. Streamline lengths and theLine Selectordistances are still measured on all of the points - Fixed a length filter that kept every streamline of a bundle asking for one segment more than the bundle has, which
WebGPUrejects, dropping the whole frame. It was reachable withLine MinLenon any bundle of fewer than 200 streamlines - Added support for
ttstreamline format - Fixed
trkformat; supportedtckformat (drag and drop) - Use
KDTreeto query the streamlines that intersect the target volume - Streamlines have better memory management with random shuffle
- In highlight mode faded streamline widths can be adjusted
-
add_streamlineresolves sub-folders of a circuit, so part of a circuit can be loaded on its own (alic/stn/*instead ofalic/*); the circuit is still the top-level folder, and a bundle in a sub-folder keeps that sub-path in its name -
Breaking: streamline visibility controllers are named by the full
circuit/bundlekey, the same keyadd_streamlinetakes, so two circuits holding a bundle of the same name are no longer ambiguous. Update anycontrollers = list("Show: <bundle>" = ...)tocontrollers = list("Show: <circuit>/<bundle>" = ...), including for thedefaultcircuit
Surface Thresholding:
- Added
Surface Threshold Data,Surface Threshold Range, andSurface Threshold Methodcontrollers, so a surface can be colored by one vertex data while being thresholded on another, the way electrodes already could. Vertices failing the threshold fall back to the underlay (curv/sulc) color - The threshold data offers the same choices as
Surface Color Data, including drag-and-dropped[custom measurement]and[custom annotation]. Continuous measurements use the same seven operators as the electrode threshold; annotations threshold on a|-separated list of label names - The mask gates whichever overlay is active, so it applies to
sync from voxelsandsync from electrodesas well asvertices - FreeSurfer
annotfiles now keep their per-vertex color table keys and label names, which is what makes annotation thresholding possible - Masked-out fragments now skip the volume and electrode sampling in the surface shader instead of computing a color that is thrown away. With
sync from electrodesand 200 active contacts, thresholding away 87% of the surface renders about 3x faster; the un-thresholded path is unchanged
Surface Colors:
- Added
Surface Color Map,Surface Color Min, andSurface Color Maxcontrollers, so continuous surface data added withadd_annotation(for examplesurf/sulcorsurf/curv) can be re-colored from the viewer, not only drag-and-dropped measurements. They show whenSurface Colorisverticesand theSurface Color Datais continuous, and can be set from R, e.g.controllers = list("Surface Color Map" = "viridis") - The color range defaults to
±max|v|of the selected data and resets wheneverSurface Color Datachanges. Both hemispheres now share this range (they used to be scaled separately), and values outside it are clamped to the end colors; use theSurface Thresholdcontrollers to hide values instead - Drag-and-dropped surface measurements are colored by the same controllers: their
Color Map (Continuous)selector setsSurface Color Map, and the surfaceClipping Min,Clipping Max, andDynamic Colorcontrollers are removed - Switching from one continuous surface data to another no longer carries the previous data’s clipping range over, which could hide most of the new data
Shiny Proxy:
-
brain_proxy()has a new fieldcontroller_specsand methodget_controller_specs(): the type, choices, range, folder, and visibility of every controller, so an application can check values before callingset_controllers(). The viewer re-sends them when its control panel changes - The viewer now reports controller values to
shinyhalf a second after any change, including changes whose handlers did not report (for exampleBackground ColororVoxel Display) and crosshair moves made by clicking a slice, so$controllersand$plane_positionno longer go stale - Fields
background,surface_type,display_variable, andside_displaynow follow the controllers; they used to return their defaults because the viewer never sent them - Field
plane_positionis reactive, as documented - Fixed
set_display_data(), which failed in the viewer, andset_focused_electrode(), which the viewer ignored - A page can ask the viewer for pictures of its views by dispatching one
viewerApp.captureOnceevent on the viewer’s wrapper (.threejs-brain-canvas) with an object asdetail: the viewer draws a frame and, right after drawing it, adds{ canvas, dataURI }(aPNGdata URL) todetail.viewsfor the main view and each shown side view, and setsdetail.dataURIto the main view. The viewer draws only when something changes, and a copy of aWebGPUcanvas taken outside the frame that drew it can be blank (Chromium) or out of date.shidashisends the event before it captures the viewer for an agent
Minor Changes:
- Automatically download template subject when
merge_brainis called but the subject is missing - Electrode transparency is improved when visualized as geometry
- Electrode
Additional Datatext containing an<a href=...>link now renders as a clickable link in a message bar at the bottom of the canvas instead of raw markup; links open in a new tab - Using physical/standard materials for electrode prototype geometries
- Allowed electrode prototype transforms to be rigid when mapping to template
- Removed
raveiofrom comments and using scanner RAS for slices - Added
fsaverage_inCIT168template - Added
radiographicview - Added global ruler next to compass
- Added
read_colormapto support reading fromRAVE(JSON) orITK-SNAPformat - Mask is now applied to slice overlays
- Use
MeshBasicMaterialwhen rendering sphere electrodes for better performance - Updated
BlueRedcolor palette to match with theravebuiltinscolor - Removed obsolete
freesurfer_brainand embrace the new universal interfacethreeBrain - Added
rendermethod for template brain for remembering the states in shiny applications -
merge_brainalso gains new argumentelectrode_priorityto control the priority when setting electrode shape - Added pseudo random generator
- Native annotation from template supports
FreeSurfercurvfile too - Surface mapping is more robust even if the hemisphere is unset: using
MNI152R-axis to infer the hemisphere instead - Added
YBAatlas color-map - Improved readability for screenshots and recordings
- Screenshot and recording filenames now use full-year with local timestamp
- Preserved canvas context to allow obtaining
dataURL - The on-canvas readout for surfaces and volumes shows the value before the data name (
0.52 (sulc)rather thansulc = 0.52), so a long data name, such as a dropped file’s, can run off the panel without hiding the value
Electrode Localization:
- Added “interpolate without refine” option for electrode localization, if the users prefer
- Added support for multiple electrodes
- Added per-contact active/inactive tracking for
InstancedMeshcontacts: inactive contacts suppress outlines;hide inactivesvisibility mode discards inactive contact fragments viaHIDE_INACTIVE_CONTACTSshader define - Added
guessHemisphere()to infer electrode hemisphere fromFreeSurferanatomical label - Localization accuracy: every position calculation was checked against coordinates computed independently from the image headers, and these were fixed (voxel centers are at integer indices, as in
NIfTIandFreeSurfer):- Atlas labels (
FSLabel_*) were read from a voxel half a voxel below the contact, so a contact near a region boundary could get the neighboring region’s label. Labels saved by earlier versions may be wrong; for example, 6 of the 48 savedaparc+aseglabels of theRAVEdemo subjectyael_demo_001change - Interpolating or extrapolating contacts along a shaft (with auto-refine off) returned voxel corners, about 0.9 mm from the voxel centers, and could read past the edge of the volume
- Clicking a
CTwith non-cubic voxels placed contacts slightly off the depth of the clicked voxel (up to 0.03 mm on a 0.39 x 0.39 x 1 mmCT) - Clicking a side panel placed the cross-hair 1 pixel left of and 2 pixels above the pointer (1 to 2 mm at the default zoom)
- A
CTpassed tobrain$localize()orlocalization_module()as a loaded image (rather than a file path) failed to show up, and once shown sat half aCTvoxel off in every direction (0.87 mm with 1 mm voxels), as did every contact placed or refined on it.RAVE’s electrode localization module passes a file path and was not affected by this one
- Atlas labels (
New Experimental Electrode Prototypes:
- Added
PMT-2102-16-099specifications - Added
BF09R-SP51X-0BBspecifications - Added
BF07R-SP21X-0B0,BF08R-SP21X-0C2,BF09R-SP21X-0BB, andBF12R-SP21X-0C3(AdTech) specifications - Added
RD16R-SP03/05X(AdTech) specifications - Added
AdTech RDseries specifications (RD06R,RD08R,RD10R,RD12R,RD14Rvariants in multiple spacing sizes) - Added
DIXI-D08-15PIXandDIXI-D08-18PIXELspecifications - Added
DIXI-MM08electrode specifications - Added
Behnke-Friedelectrode specifications - Added
NeuroOne/Zimmerelectrode specifications - Added
Medtronic 3387andMedtronic 3389DBSlead specifications - Added
NeuroPixel NP1001,NP2004, andNP2014shank specifications - Added
Spencer-MXene-7x18ECoGarray specifications
Drag and Drop Improvements:
- Drag and drop is handled by file-system API or
WebKitbefore fallback to naive approaches to support dropping in folders - Drag drop supports folders now
- The default colors for dropped objects are determined by their file names to avoid random colors
- Drag-and-dropped files now generate consistent default colors and ignores the left-right keywords
- Fixed drag and drop multiple files issue
- Fixed drag and drop color key length issue
- Added try-catch to handle file processing errors to avoid stopping processing files
Bug Fixes:
- Suppressed rendering flags when the trackball is inactive, fixing the rendering policy
- Fixed the
datacube2(atlas) ISO surface: an unnormalized color-key byte made every non-zero label take the>= 1branch, so the whole surface rendered as a single flat color (the last entry in the color map). Colors now decode from display space correctly, with a matched emissive term so the surface’s brightness lines up with the ray-marched volume it stands in for, andGLTFexport bakes in the same corrected colors - Fixed continuous color maps (surface data and the volume ray-marching ramp) coming out too dark from converting
sRGBto linear color twice -
MRIslices and slice overlays are drawn with each voxel exactly where its coordinates say it is. They used to be shifted by up to half a voxel, which showed at high zoom as the cross-hair not landing on the voxel it reads - Surfaces colored with
sync from voxelsread the voxel whose center is nearest instead of a neighboring one - The side panels no longer show a strip of the viewer’s background color past the edge of the volume
- Electrode colors update as soon as a controller changes them; since the
three.jsr185upgrade they showed one frame late, so a change could appear not to take effect until the next interaction
threeBrain 1.3.0
- Ray-caster with ruler now works on surfaces derived from volumes
- Fixed volume value range issue: instead of using
cal_minandcal_max, always calculate the data minimum and maximum instead. - Updated
jspdfversion - Ruler supports multiple segments and displays segment lengths and angles for adjacent segments
- Minor edits on ruler
- Make sure the ruler does not automatically disappear unless pressing “R” key
- Added ruler helper
- Fixed template brain argument issue when template
atlasandannotationtypes are not specified explicitly - Supported dynamic color-map (value range) for continuous surfaces and volumes; supported showing additional volume components (such as time component in
fMRI) - Added prototype geometries for
AdTech-SD16R-AP0?X - Fixed color palette offset issue; Supported dropping color map for electrode contacts
- Handles infinite electrode numbers
- Fixed bugs drag & drop electrode data type: the electrodes with missing data will be reset, and the color palettes for existing data will be kept
- Fixed
GLBformat issue - Minor change on the error message
- Multi-brain template passes extra arguments to template object constructor
- Function
threeBraindoes not automatically download templates if annotation is not found - Disable downloading files in
WASMby default to avoid triggeringCORScondition that will terminate the program - rewrote drag & drop code so its framework can be easily extended; surface color handlers now handle measurements and annotations different, with separate storage
- Added
FileDataHandlerclasses to handle drag & drop files; supported drop-in electrode coordinate files -
GIfTIreader now respect the transforms if there exists a transform with target space to be thescanner_anat - Allows continuous data cube to change color map
-
add_annotationautomatically compiles annotations from template if missing - Fixing the side panels so the background color is always black
- Canvas and screenshot is transparent when background is
#ffffff - Fixed
shaderignoring always-depth flag when outline is off; updatedjsPDFto the 2.5.2 build - Transition animation allows video recording
- Fixed screenshot button and improved video quality
- Fixed sub-cortical
ROImatrices - Added surface coordinate for cross-hair
- Fixed get controller state function; added stage transition, allowing users to create animations from key states
- Using “color” instead of separated
colorandunderlayColorattributes for surface underlay - Supported visualizing surface annotations; surface colors are synced to the electrode colors if the names are consistent; re-wrote the surface
shaderto support under- and over-lay colors - Updated
SurfaceShaderto use morph normal and transformed positions - Load other common surfaces by default
- Switching subject surface types will trigger morph if the number of vertex nodes are the same
- Allow animation presets to be shown even when data is not available; added keyboard shortcut to sync data threshold with display; added hidden features that are experimental;
crosshairposition is changed to scannerRASandAffine MNI152; addedtooltiptitle support for controllers; added global clock for app; updatedViewerCanvasconstructor arguments; supporteduseMorphTargetfor surface objects - Fixed electrode
useMatrixwhen contacts are represented as spheres - Fixed template mapping, supported non-linear mapping for electrode geometries
threeBrain 1.2.0
CRAN release: 2024-11-07
- Fixed shiny callback when electrode contacts are double-clicked
- Fixed contact-switching and highlight box
- Added
PMTelectrodes - Fixed non-integer search radius issue
- Adjust electrode position can be done under volume-mode to improve user experience
- Electrodes with prototype geometries will use the prototype to infer the locations rather than spacial calculation
- Added keyboard shortcut for registering from cross-hair
- Added
get_atlas_valuesfor continuous atlases such as binary or probabilisticROI - The radius refers to maximum
RASdistance instead ofvoxelindexing distance, hence more accurate when the atlas volume has imbalanced slice count - Renamed
active-voxeltocolumn-row-slicebut still keep the naming for backward compatibility -
Voxelfilter is linear now when displayed at side slices only and when the slice mode is notactive-voxel - Fixed drifting issue when visualizing via active
voxelmode - Added direction arrow helper to
DBS(or electrodes with non-zero model up vectors) - Support
WebAssembly - Avoid using
pandocto save the whole page self-contained - Fixed the depth issue in electrode material shader
- Set maximum render length cut-off for electrode prototypes
- Added model tangent (usually the direction) to electrode shader so outlines are correctly visualized
- Fixed electrode prototype rendering issue (color) on Windows
- Fixed the color map for discrete values
- Setting electrode prototype render order to be
-500so it does not hide behind the transparent surfaces - Plotting electrodes on slices now takes numerical
adjust_brightnessinterpreted as quantile - Changed default color palette for discrete values, removed colors that are too dark or gray
- Change
CTthreshold back to positive (3000) when switching fromDBSleads back tosEEGleads. - Support drag and drop annotation files
- Changed electrode material to display front-side only instead of double side to avoid overlapping contacts visually when spacing is small
- Added
Abbottsegmented electrodes6170-6173, with segmented electrodes clockwise viewing fromproximalend - Fixed a bug that may change electrode coordinate hand
- All the
DBSelectrode prototype maker uses naturalcosforxandsinfory. However, this will cause electrodes to rely on rendering on back side (material) - Added missing prototype
- Fixed
BSCandMedtronicelectrode orientation (now is counter-clockwise when viewing fromproximalend) - Added more spacing for
DBSsegmented contacts - added prototypes for
Medtronicsegmented electrodes - Added
BSC-DBelectrodes for22022201 - Added internal test code for depth mapping
- Surface mapping has been implemented for depth electrodes, with dynamic offset threshold
-
surface_offsethas been added to electrode field -
cvs_avg35_inMNI152has the correcttalXFM(scanner toMNI305) now - Added
load_meshto surface object so users can load surface mesh for computation inR - Added internal
calculate_distancesto compute the distances from a point to its projection to a list of mesh -
DistanceShiftedin electrode table is taken into account and will be passed to electrode instances - Inflated surfaces have offset by default
- Fixed a singular matrix bug when the electrode prototype
upvector is zero or is parallel with the model direction - Allowed the surface mapped electrodes to be snapped to the surface if the surface world matrix is not identity
- Force the inflated brain to have offset positions
- Added
DBSelectrode prototypeBSC-DB-2202 - Prototype
set_transform_from_pointsnow tries to set rotation from transformEulerangle when the prototype guided marker is 1-ranked (electrode strip,DBSelectrodes) - Allowed electrode prototype to display markers; added viewer options for localization
- Changed electrode direction helper to be displayed inside of cross-hair group
- Allowed side panel to be displayed with atlas column-row-slice
- Added controller to display symmetric continuous color map for volumes
- Fixed the
GLTFnot showing inner-most contact issue - Removed
develversion ofravetoolsfrom check - Update
Githubaction check script - Added
rhubcheck - Plotting slices have correct margins with partial plot
- Allow users to drag and drop value tables
- Allow users to hide cross-hairs
- Allow
shinyapp to change current color map via proxy - Allows drag-drop electrode color files
- Added
set_electrode_datato brain proxy class, allowingshinyapplications to change the electrode data, set color palettes, and set value ranges in the same call - Allow masks to be added to
T1 - Added
D99v2for monkey brain - Export
GLTFfordatacube2 - Fixed
fix_electrode_colorbug - Supported
ISOsurface generation from volume - Added white-matter segmentation as default atlas if user has this file
- Exporting
GLTFis wrapped with try-catch -
fix_electrode_coloris exclusive by default - fixed color fixing issue for naive sphere electrodes
- Changed logo message
- Using better
RAVElogo and fixed style issues - Changed shortcut
pto toggling the visibility andshift+pto switching surface types - Added logo to control panel to advertise the project
- Added export
GLTFbinary format - Separate
3Dand2Dcanvas; - Converts
*h.pial.giitoFreeSurferformat when the files are missing - Allow electrode depth test to be disabled (always-depth) on contact and/or outlines
- Fixing the vertex shader output not read by fragment shader issue
- Drop-in feature support color-map for volume and surfaces
- Added contact order to display when electrode is clicked
- Added
DIXI(AM,BM,CM) electrode specifications
threeBrain 1.1.0
Major Changes
-
threejsengine is upgraded tov160; added support forNIfTIandGIfTIimages - Allowed data to be embedded with viewer as
dataURI. This results in a truly standalone viewer: no extra engine required, only web-browser is needed. - Added electrode geometry prototype, allowing users to see the electrode rather than using spheres, useful for electrodes with super micro contacts or electrodes with segmented contact like
DBS - Added support for showing (cortical or sub-cortical)
ROIsurfaces - Implemented drag-and-drop feature to drop arbitrary volume (
nii,mgz) or surface (fs,gii) files to the viewer. The surface coordinate system is inferred from file name followingBIDSconvention. The surface color can be set via a color-map (csv) or in the file name - Implemented slice (in side viewer) overlay
- Users can control side camera
frustums(near and far) separately - Implemented worker system so the viewer can run truly parallel code in the background
- Added
snap-to-electrodeandline-of-sightmode in addition to canonical anatomical slices.- Under
line-of-sightmode, the underlay image will be sliced dynamically with a plane orthogonal to the line of sight; two other (orthogonal) planes parallel to the line of sight - Under
snap-to-electrode, the volume slices will be snapped to electrode direction (only available when electrode prototype is used and electrode direction defined). The other two planes will dynamically slice theMRI
- Under
- Users can localize an electrode probe by clicking on the target location, then entry location
- Added an option to add
QRcode to the viewer, allowing people to link to the publication - Loading progress is more informative now
- Implemented
plot_slicesto allow plottingMRIslices for each contact in canonical order - Users can set default colors to electrodes via
brain$electrodes$fix_electrode_color - Users can override underlay images by placing
rave_slices.nii[.gz]under themri/inFreeSurferfolder - File/Data loaders use
JavaScriptworkers now (can be disabled withenable_cache=TRUE) - Added mesh clipping to see depth electrodes without compromising color
- Implemented volume clipping
- Added new mode for
ACPCalignment - Added
targetflag so objects can be rendered differently on main canvas versus side canvas
Minor changes
- Electrode prototype names follow
type-company-version.jsonformat - Added compass object to side cameras when slice mode is not canonical
- Remove
UVmapping on sphere electrodes - Added model up direction to electrodes to assist calculating Euler axis and angles
- Volume, atlas threshold is asynchronous now
- Changed default values of some controller
- Added
broadcast()to more controllers; - Atlas key number is displayed so users no longer need to search for look-up table
- Added debug flag with keyboard shortcuts
- Viewer finally compiles with
quarto/rmarkdown - Implemented functions to create
sEEGelectrodes - Slices does not write to depth buffer when rendered in side canvas, so electrode contacts are not blocked
- Allowed anchor to be fixed when localizing with electrode prototype
- Using
instancedMeshto render actual electrode spheres when prototype is used and users choose to see the actual contact locations - Implemented
mapToTemplatefor electrode prototypes -
Pialsurface does not write to depth buffer when it’s super transparent - Added drivers to set object transform matrix
- Adjust the implementation of background color and
arcballradius - Removed composer effects, using
shadersto render electrode outline - Trackball uses longer side of the canvas instead of shorter side as radius
- Added electrode visibility mode: use
threshold-onlyto show contacts that pass threshold even no display value is given - Overlay brightness can be adjusted via controller
- Adjusted title position
- Updated
CITATION - New color map is used for electrodes to be consistent with
RAVEcolor - Allow adding additional geometries in
brain$plot - Improved spacing for interpolation and extrapolation (electrode localization); removed old interpolation logic; added
distanceRatioto prevent large shift (auto adjust) - Electrodes are opaque on main but transparent on side canvas
- Using
pialsurface center as trackball center - Dithering the
datacube2to make rendering more natural on main canvas - By default set
MRIslices visible when surfaces are missing - Drag & drop file names is sanitized to avoid displaying issues
- Electrode contacts (
instancedMesh) are now click-able -
disposeis cleaner now, it also fires events - Added
makeClickableandremoveClickableto replace previousadd_clickablefunction - Renamed
register_objecttoregisterToMap - Better ways to sanitize
datacube - Improved
datacubeoverlay texture, including usingclamp-to-borderinsteadclamp-to-edge - Ray-casting electrode prototypes with
instancedMeshnow works undercontact-onlymode - Show electrode prototype with contacts by default
- Added color modes for uploaded images
- removed
normalizemethod (replaced bygetNormalizedImage) fromNiftiImageandMGHImage - Using script to generate change log automatically from Git commits
- Scrolling on side canvas is faster now
- Allowed prototype contact colors to be fixed
- Prototype control points displays channel information (provided control points are channels) Added color (
randomColor,testColorString) and file-name utility functions - Soft removed
addColorCoatand usingElectrodeMaterial, this results in massive code improvement in electrode instance - Allow to set default electrode colors if a contact is not rendered with values nor fixed color
- Scrolling on side canvas is faster now
- Color look-up table can be set with arbitrary single color (in
HexString, indicating that all values should be rendered with such color; Drag & Drop volumes can change to single colors - Remembers the state when switching volumes (
datacube2)
Bug fixes
- Fixed
NamedLutcolor error when a value range is zero - Prototype electrode click information displays the channel number
- Fixed
RShinyDriverissue when object does not have construction parameters (usinggetThreeBrainInstanceinstead) - Avoid rendering volume data to sub-cortical
ROI - Fixed UV issues in electrode geometry prototypes
- Fixed a bug when slice instance is missing but controller tries to set overlay
-
JavaScriptmap is hidden when compiled so browsers will not complain about missing maps - Significantly reduced the chances of viewer crash under R shiny applications
- Fixed a
shadercrash issue onWindows -
WebGL2is the hard requirement now; users will be notified if this requirement is not met - Mouse position in the canvas is calculated every mouse down instead of every resizing to fix the control issues when page is scrolled in shiny app
- Fixed
controller.loadto handle invalid set controller request - Fixed
textspritedepth issues - Fixed light under new engine
- Fixed visualization of volume cubes when using
NIfTIfiles - Fixed volume transforms when
sformandqformare inconsistent inNIfTI - Fixed a bug in interpolation with spacing
- fixed incorrect
ROIlabel -
as_subcortical_labelgenerates correct white-matter labels - Fixed
freesurfer_lut - Fixed
auto-adjustfeature (electrode localization) - Fixed
UVmapping issue in sphere electrode geometry - Fixed
shaderissue when transparency is set to negative (treated as 1) - Using
NIfTIheaders to get calculated color intensities before applying heuristic approach
threeBrain 1.0.2
- Removed a
shaderloop that accidentally used dynamic variable for looping, which may crash onWindowsin certain situations - Updated
README.md - Composer effects are removed
- Added default color to electrodes (JavaScript) to fix the localization electrode color not set correctly issues
- Added
z-indexbase to the side canvas layer (div) - Removed additional unused parameters from material call
- Used new material type to make brain more realistic
- New background color is implemented
-
Trackballuses width instead of height of the viewer as theArcballradius; mouse positions is calculated whenever mouse-down event is triggered (allowing more accurate track-ball calculation inShinyapplications) - Made
col2hexstrinternal function - Added a new electrode visibility mode, allowing to show contacts with no values but passing the threshold
- Added
brain$electrodes$fix_electrode_colorto fix the electrode colors under given data names (to displayDBSelectrodes, for example) - Made
controller.loadmore robust against errors - Fixed the depth issue in
TextSprite - Some default controller values have changed to make more sense
- Outline render effect is removed; electrode outlines are implemented directly in the
shader - Updated
three.jstov160with light model improved - Added
rave_slices.niito allowedMRIprefix inFreeSurferfolder with highest priority, such that this image will be treated as default volume to load in side canvas (default is stillbrain.finalsurfs.mgz) - Allow
MRIto change brightness dynamically in viewer - Ensure that
voxelsindex from zeros - Added
brain$get_atlas_labelsto guess the atlas labels from given masks or atlas files - Allowed to spatially transform electrodes to desired coordinate system
- Updated citation
- The standalone viewer does not require static server anymore: everything is self-contained (require
pandoc, which comes withRStudio) - Changed mechanism on animation color map generator (so the color is more accurate for discrete variables)
- Added
pngto dependence - Added support for
AC-PCalignment, available inRAVE-YAELmodule - Allow
brainto plot with additional customized geometries - Added
plot_slidesto plotMRIcentered at each electrode contact for slide-to-slide visualization - Added Line-of-Sight view mode for side canvas; can be enabled using shortcut
m(previous shortcut to change the material type is changed toshift+M) - Fixed
CTinJavaScriptwhen thesformandqformare different (have different code) - Allowed to specify the spacing for interpolation and extrapolation for unequally spaced electrodes
- Added electrode outlines
-
YAELpaper is finally out - Fixed incorrect sub-cortical labels
- Deprecated old format (no cache is needed anymore)
- Made electrodes opaque on main but transparent in side canvas
- Let controllers check if the variable is valid before set to avoid invalid viewer state during initialization
- Added
get_ijk2rasto getNorigandTorigmatrix
threeBrain 1.0.1
CRAN release: 2023-07-03
- Updated controller library to have reasonable input focus
- Allow
MRIslices to beNIfTIformat - Set slices to be visible by default when the surface is not available
- Fixed transform for
datacube2 - Fixed
qformwhen readingNIfTIfiles - Fixed
auto-refinefunctions in electrode localization - Removed clipboard auto-copy and auto-paste functions since they conflict with other viewers; instead users can use controllers to copy and paste state
threeBrain 1.0.0 - Egypt
CRAN release: 2023-06-03
This version is a major update.
- Created
threeBrain::threeBrainas the formal way to create brain objects - Updated
JavaScriptengine tov150 - Allow getting
HTMLtags from saved widget so the widget can be used fromJupyternotebook - Added
$rendermethod to remember viewer states - Allowing set title via proxy driver
- Added citation information
- Fixed hemisphere issue in localization when electrodes are closer to opposite hemispheres
- Added electrode registration from anatomical slice cross-hair
threeBrain 0.2.9
CRAN release: 2023-03-14
This version plans for a major update. Here are some highlights:
- Electrode localization can be done from original
CTinstead of re-sampled ones - Completely isolate
JavaScriptengine fromRcode. TheJavaScriptcode is available asnpmpackage and is used via sub-module - Implemented file readers directly from
JavaScript, this allows reading files directly in viewer, and no cache is needed - No home-brew version of
threejsis required: standardnpmdistribution is used - New controller
GUIis implemented - The viewer can be driven via
JavaScriptdirectly via event dispatchers - Anatomical segmentation map is visible from the side panels; the
voxelvalues are displayed when settingcrosshair
Detailed Changes
- Added step size in
datacube2material uniforms - Upgraded
threejstor148, and usenpmdistribution “three” - Massive code re-factory (variable names, trackball controls, legacy classes…)
- Removed
data-GUIand uselil-GUI - Fixed compass (finally…)
- Added title to the viewer
- Reworked the whole message signal system, added
ThrottledEventDispatcher.js - Added
MouseKeyboardclass to track mouse and keyboard events, greatly reduced canvas burden - Added
animParameterobject to canvas to keep track of the animation parameters - reworked shiny drivers
- fixed one-voxel shift issues
- Added format support for
nii,mgh/mgz,FreeSurfersurface,FreeSurfernode value binary formats - Added function
threeBrainto allow 3D viewer to run without cache (with fs only) - Fixed memory leak issues in
JavaScriptcode - Geometry groups can now change its storage path
- JS is completely independent now (available on
npmnow) - Peel event dispatcher from the canvas class so the events can be managed separately
- Hide time-stamps when there is no data/animation available
- Added experimental support to show labels on regular electrodes; currently no depth-test is turned on
- Added
GUIsupport to change electrode label visibility and size - Electrode label size adjusts along with electrode radius
-
handle_resizenow put off resizing function when detecting widget size is too small
threeBrain 0.2.7
CRAN release: 2022-10-15
threeBrain 0.2.6
CRAN release: 2022-08-25
Changes
- Allowed users to pan the camera when localizing electrodes
- Added line segment geometry type that can either display static line segments (such as
DTI), or connect two electrodes dynamically - Printing brain now uses more accurate terms
- Allowed
CTto be either path or the actual data when calling localizing function
threeBrain 0.2.5
CRAN release: 2022-05-30
Changes
- Surface
sync from voxelsnow clamp the surface nodes - Added
Voxel Displaycontroller to toggle volume display modes - Changed shortcut
lfromVoxel TypetoVoxel Display - Volume
fragmentShaderuses non-linear function to calculate fragment colors combined with face normal; this will create smoother results -
DataCube2geometry usesConvexHullinstead of box/sphere to improve the performance -
DataCube2are no longer hidden whensync from voxelsis on: users can use shortcutslandkto easily control the visibility. -
download_template_subjectcan download other templates such asfsaverage,cvs_avg35,bert.
threeBrain 0.2.4
CRAN release: 2021-12-03
This version mainly works on the electrode localization. Most changes occur in the JavaScript engine.
Changes
- Allows electrodes to be reset
- Displays electrode labels along with the electrodes
- Allows resizing electrode size on the fly
- Allows resizing the electrode labels
- Localization module has been integrated into
RAVE - Added line mesh to mark the distance of the electrode deviating from its original position. The line color changes with the distance value.
threeBrain 0.2.2
threeBrain 0.2.0
CRAN release: 2021-07-27
Changes
- More efficient volume rendering with transparency
- Added shader functions to surface instances, allowing color rendering from volume, electrodes, or vertices (major change)
- Added color-map generator for surface and volume data
- Added method to generate data cube (volume) from
MNI305coordinates - Optimized loading procedure
- Removed
crayon,base64enc,htmltools,pryrfrom dependence
threeBrain 0.1.9
CRAN release: 2021-01-10
threeBrain 0.1.6
threeBrain 0.1.5
CRAN release: 2020-01-20
Changes
- Import
FreeSurferandSUMAfilessulc - Control element update
- Added
brain_proxyto control in shiny element - Separated display and threshold data
-
FreeMeshmaterial can be switched betweenMeshPhongMaterialandMeshLambertMaterial
Improvements
- UI will blur focus when clicking on canvas
- Allow customizing widgets
background,cex(font magnification),timestamp(display time) - Allow
controllers(list) to override control UI - Added preset
syncviewers(threejs_brain(control_presets = ...)) to synchronize multiple viewers in shiny environment
threeBrain 0.1.4
CRAN release: 2019-10-18
Changes
- Implemented a new mesh type - volume rendering using ray marching
- Added alternative methods to read
.niifiles,nibabelis now optional - Customized color palettes and value range for better visualizations with outliers
- Only requires
T1.mgzorbrainmaskofbrain.finalsurfis not found. This allows users only runFreeSurferto the first stage, which only takes around 8 to 10 minutes instead of 6 hours. - Fully compatible with
htmlwidgetsinshinymode. When callingthreejsBrainOutputundershiny::renderUI, theDOMelement might get reset byshiny, causing a new 3D viewer created. This might consume more resource, causing memory leaks and even conflict context renderings. Also event listeners couldn’t reset correctly. A cache is created and now is reusing the canvas.
threeBrain 0.1.3
CRAN release: 2019-09-10
Changes
- File structure change: now directly read in from
FreeSurferfolder - Added readers for
.mgz,.m3zfiles - Added coordinate system to align volume with surface data
- Implemented side-viewers, added three side cameras at XYZ axis
- Can now read, export electrodes as csv file
- Re-write brain generating function
- Can display/switch multiple value types
- Added transparency to surfaces
- Implemented experimental electrode localization
- Automatically determine color type (continuous or discrete) and value range
Improvements
- Shortcuts available at here
- Optimized electrode value settings
threeBrain 0.1.2
CRAN release: 2019-06-28
Changes
- Re-draw canvas on a 2D context to make customized overlay directly on canvas.
- Implemented continuous and discrete legends to replace D3.
- Added support to set main camera position and initial zoom level.
- Added 3D scatter plot and examples.
- Use hybrid render mode when animation not required to save battery usage.
- Improved color palette calculation.
- Support customized title.