Class AbstractBigViewer

java.lang.Object
sc.fiji.snt.viewer.AbstractBigViewer
Direct Known Subclasses:
Bdv, Bvv

public abstract class AbstractBigViewer extends Object
Abstract base for SNT's BigDataViewer-family viewers (Bvv, Bdv, etc.).

Provides shared infrastructure for tree/path management, calibration, and bookmark support, leaving viewer-specific rendering, source loading, and camera control to concrete subclasses.

The AbstractBigViewer.AnnotationOverlay interface defined here is the common contract that all viewer overlays must satisfy so that BookmarkManager can drive them without knowing the concrete viewer type.

Author:
Tiago Ferreira
See Also:
  • Field Details

  • Constructor Details

    • AbstractBigViewer

      protected AbstractBigViewer()
    • AbstractBigViewer

      protected AbstractBigViewer(SNT snt)
  • Method Details

    • getSNT

      public SNT getSNT()
      Returns:
      SNT instance this viewer is tethered to, or null if no SNT instance is available.
    • syncPathManagerList

      public boolean syncPathManagerList()
      Replaces the rendered trees with the current contents of the Path Manager. Only available in SNT-tethered instances.
      Returns:
      true if paths were synced; false if the path manager is empty
      Throws:
      IllegalArgumentException - if this is a standalone viewer
    • getViewerFrame

      public abstract JFrame getViewerFrame()
      Returns the top-level Swing window for this viewer, or null if not yet open.
    • getViewerSplitPanel

      protected abstract JSplitPane getViewerSplitPanel()
      Returns the JSplitPane that separates the viewer canvas from the card panel. Both BDV and BVV frames expose this via their own getSplitPanel() methods, but those classes share no common supertype above JFrame, so this method lets subclasses expose the split pane without the abstract method returning a viewer-specific frame type.
    • getViewerWidth

      public abstract int getViewerWidth()
      Returns the width of the viewer canvas in logical pixels, or 0 if the viewer is not yet initialized.
    • getViewerHeight

      public abstract int getViewerHeight()
      Returns the height of the viewer canvas in logical pixels, or 0 if the viewer is not yet initialized.
    • getViewerTransform

      public abstract net.imglib2.realtransform.AffineTransform3D getViewerTransform()
      Returns a snapshot of the current viewer-to-screen (world-to-screen) transform. The returned object is a copy; callers may modify it freely.
    • setViewerTransform

      public abstract void setViewerTransform(net.imglib2.realtransform.AffineTransform3D target, long durationMs)
      Animates the viewer transform to target over durationMs milliseconds. Use durationMs = 0 for an immediate jump.
      Parameters:
      target - the desired world-to-screen transform
      durationMs - animation duration in milliseconds (0 = immediate)
    • showViewerMessage

      public abstract void showViewerMessage(String msg)
      Displays a short status message in the viewer's overlay area.

      This is bdv-core/bvv-core's fading toast: it auto-dismisses after a few seconds. For an ongoing, non-auto-dismissing indication of a long-running operation, use updateStatus(java.lang.String, int, int) instead.

      Parameters:
      msg - the message to show
    • updateStatus

      public abstract void updateStatus(String message, int step, int nSteps)
      Updates the persistent progress bar docked at the bottom of this viewer's card panel. Unlike showViewerMessage(java.lang.String), it stays visible until reset.
      • nSteps = 0: hides the bar
      • nSteps < 0: indeterminate mode (animated, no percentage)
      • nSteps > 0: determinate mode showing step/nSteps
      Safe to call from any thread.
      Parameters:
      message - short status message displayed inside the bar
      step - current step (0-based; ignored in indeterminate mode)
      nSteps - total steps (0 = hide, negative = indeterminate)
    • resyncCalibrationFromActiveSource

      public abstract void resyncCalibrationFromActiveSource()
      Forces snt's image metadata (dimensions, calibration, pixel data, channel/frame) to be re-read from this viewer's currently active Source, the same resync AbstractBigViewer.AbstractTracer performs on its own before starting a new path (see AbstractTracer#syncChannelFromActiveSource()).

      That resync is otherwise only triggered by the first click of a new path, so snt's calibration can be stale (or still at whatever BigDataLoaderCmd's best-effort fallback produced at load time) for anything that reads it beforehand - such as SNT#buildMaterializedCrop(BoundingBox). Callers that need calibration to reflect exactly what this viewer is currently rendering, before the user has traced anything, should call this first.

      A no-op if no tracer has been created yet, or if the active source can't be resolved.

    • applyAutoBrightness

      protected abstract void applyAutoBrightness(AbstractBigViewer.BrightnessScope scope)
      Recomputes the display range (brightness/contrast) for the source(s) selected by scope, from data percentiles, on a bounded background thread - see initBrightnessSafely(bdv.viewer.ViewerState, bdv.viewer.ConverterSetups, java.lang.String). Called automatically with AbstractBigViewer.BrightnessScope.ALL right after a source is first added, and re-invocable on demand (any scope) via the "Auto Brightness/Contrast" scene-control button (see autoBrightnessButton(sc.fiji.snt.viewer.AbstractBigViewer.Actions)). Does nothing if this viewer isn't yet backed by an underlying BDV/BVV scene (e.g. show(...) hasn't been called).
      Parameters:
      scope - which source(s) to recompute
    • addToCardPanelBottom

      protected static void addToCardPanelBottom(bdv.ui.CardPanel cardPanel, JComponent comp)
      Docks a component at the bottom of a CardPanel, below all cards, without a card header. Uses MigLayout's "dock south" constraint. If the CardPanel's container layout ever changes away from MigLayout this degrades gracefully: the component simply won't appear (no crash, no viewport flicker). Shared by Bvv and Bdv's own progress bars.
    • initBrightnessSafely

      protected static void initBrightnessSafely(bdv.viewer.ViewerState state, bdv.viewer.ConverterSetups setups, String label)
      Computes and applies a display range from data percentiles (InitializeViewerState.initBrightness(double, double, bdv.viewer.ViewerFrame)) on a bounded background thread so that a remote N5/Zarr/SPIM data hit by a bad chunk or network stall cannot block the caller indefinitely (see SNTUtils.runWithTimeout(java.util.concurrent.Callable<T>, long, java.lang.String)). Callers should invoke this off the EDT; a caller that doesn't is still bounded by the timeout, just at the cost of freezing the UI for up to BRIGHTNESS_INIT_TIMEOUT_SECONDS seconds instead o`f indefinitely.

      On timeout or any other failure, the failure is logged and swallowed` rather than thrown: a slow/failed brightness estimate should never prevent a viewer from opening, or block whatever triggered this call (initial load, or a manual "Auto Brightness/Contrast" button click).

      Parameters:
      state - the viewer state to sample and update
      setups - the converter setups whose display ranges are updated
      label - short, human-readable description of the viewer/dataset (used only in the failure log)
    • initBrightnessSafely

      protected static void initBrightnessSafely(bdv.viewer.SourceAndConverter<?> source, bdv.tools.brightness.ConverterSetup setup, int timepoint, String label)
      Single-source counterpart of initBrightnessSafely(bdv.viewer.ViewerState, bdv.viewer.ConverterSetups, String), for AbstractBigViewer.BrightnessScope.CURRENT/AbstractBigViewer.BrightnessScope.ACTIVE. InitializeViewerState. This samples the source's own data directly via ImgUtils.computePercentile(net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>>, double) (max 100k pixels, regardless of image size) at its coarsest available resolution level
    • applyBrightnessScope

      protected static void applyBrightnessScope(AbstractBigViewer.BrightnessScope scope, bdv.viewer.ViewerState state, bdv.viewer.ConverterSetups setups, bdv.viewer.SourceAndConverter<?> currentSource, String label)
      Parameters:
      scope - which source(s) to recompute
      state - the viewer state (sources, active flags)
      setups - the converter setups (source -> display-range control lookup)
      currentSource - the viewer's current/selected source, or null if none
      label - short, human-readable description of the viewer (for logging)
    • showLoadedData

      public abstract void showLoadedData()
      Displays the main tracing data (the currently active channel/frame of the image being traced) from the associated SNT instance. Only available in SNT-tethered instances.
      Throws:
      IllegalArgumentException - if this is a standalone viewer, or no valid image data is available
    • showSecondaryData

      public abstract void showSecondaryData()
      Displays the secondary tracing data (the filtered/processed layer used for cost-function-based tracing) from the associated SNT instance. Only available in SNT-tethered instances.
      Throws:
      IllegalArgumentException - if this is a standalone viewer, or no secondary data is available
    • hideSecondaryData

      public abstract void hideSecondaryData()
      Removes the secondary tracing data layer previously added by showSecondaryData() from this viewer, if one is currently displayed. No-op otherwise (e.g., standalone viewers, untethered instances, or when no secondary layer has been shown yet).
      See Also:
    • updateSecondaryLayerIndicator

      public abstract void updateSecondaryLayerIndicator()
      Refreshes the persistent "secondary layer active" indicator shown in this viewer's SNT Controls card, reflecting SNT.isTracingOnSecondaryImageActive(). No-op if this is not a tethered, tracer-enabled instance (i.e., the indicator was never built). Safe to call from any thread.
    • resetView

      public abstract void resetView()
      Resets the view to frame all loaded data.
    • isOpen

      public abstract boolean isOpen()
      Returns true if the viewer window is currently visible and usable.
    • repaint

      public abstract void repaint()
      Requests a repaint of the viewer canvas.
    • syncOverlays

      public abstract void syncOverlays()
      Synchronizes all active rendering overlays (paths, markers) with the current state of renderedTrees and any pending annotation changes.
    • setDisplayRadii

      public abstract void setDisplayRadii(boolean display)
      Sets whether paths are rendered as frusta (tubes) or simple centerlines, and triggers an overlay cache invalidation.
      Parameters:
      display - true to render frusta using per-node radii; false for fast centerline rendering
    • annotations

      public abstract AbstractBigViewer.AnnotationOverlay annotations()
      Returns the annotation overlay for this viewer. The overlay renders point markers in the viewer's world coordinate space. May return null if the viewer has not been opened yet.
    • getDefaultMarkerSize

      public abstract float getDefaultMarkerSize()
      Returns the default sphere radius (in physical units) for newly placed markers. Implementations typically derive this from their rendering-options or a sensible default.
    • getDefaultMarkerColor

      public abstract Color getDefaultMarkerColor()
      Returns the default color for newly placed markers, or null to use the viewer's own fallback color.
    • getCurrentTimepoint

      public abstract int getCurrentTimepoint()
      Returns this viewer's current timepoint (1-based, matching Path.getFrame()'s convention), or 1 if no data is loaded / timepoint tracking is unavailable.
    • setCurrentTimepoint

      public abstract void setCurrentTimepoint(int timepoint)
      Navigates this viewer to the specified timepoint (1-based, matching Path.getFrame()'s convention). Does nothing if no data is loaded.
      Parameters:
      timepoint - the 1-based timepoint to navigate to; values < 1 are coerced to 1
    • flyTo

      public boolean flyTo(BoundingBox box)
      Animates the camera to frame the given world-coordinate bounding box: an isotropic scale is computed so the box's width/height fit the viewport, and the transform is translated to center the box's centroid on screen. Any existing rotation is dropped.

      A degenerate box (zero width/height - e.g. a single-node selection, whose origin and originOpposite are the same point) cannot be "fit" (there is nothing to scale to), so this recenters on the centroid at the viewer's current zoom level instead.

      Parameters:
      box - the world-coordinate bounding box to frame; a no-op if null, its corners are not real (e.g. an empty/uncomputed box), or the viewport has not yet been realized
      Returns:
      true if the transform was computed and applied; false otherwise
    • createMarkerManager

      protected abstract BookmarkManager createMarkerManager()
      Creates and returns a new BookmarkManager for this viewer. Called exactly once (lazily) by getMarkerManager().
    • getGlobalMouseCoordinates

      public abstract void getGlobalMouseCoordinates(net.imglib2.RealPoint pos)
      Writes the current global (world-space) mouse position into pos. Callers must supply a pre-allocated RealPoint with at least 3 dimensions.
      Parameters:
      pos - 3D point to receive the world-space cursor position
    • getCurrentSource

      protected abstract bdv.viewer.SourceAndConverter<?> getCurrentSource()
      Returns the currently active source, or null if none.
    • addMouseListenerToDisplay

      public abstract void addMouseListenerToDisplay(MouseListener ml)
      Adds a mouse listener to the viewer's canvas component so that click events on the display surface can be handled (e.g. for hit testing annotation markers).
      Parameters:
      ml - the listener to add
    • getViewerAction

      protected abstract Action getViewerAction(String name)
      Looks up a named action from the viewer's keybindings action map. Returns null if the action is not registered or the viewer is not ready.
      Parameters:
      name - the action key (e.g., "align XY plane")
    • registerNativeCommands

      protected void registerNativeCommands(SNTCommandFinder commandFinder, ActionMap actionMap, InputMap inputMap, List<String> path, Icon icon, Set<String> excludedNames, KeyStroke... excludedTriggers)
      Registers this viewer's native (library-level) single-shot commands -- i.e., entries of the BDV/BVV keybindings ActionMap, as opposed to SNT's own overlaid commands (see AbstractBigViewer.Actions) -- in commandFinder, so they become searchable/runnable from the command palette. Meant to be called once per viewer instance, only while Stream mode is active

      Continuous, held-key or mouse-drag behaviors (pan, rotate, zoom, scroll) are not picked up by this scrape: they live elsewhere so they are excluded by construction. excludedTriggers additionally drops named actions bound to specific keys that clutter the palette.

      Parameters:
      commandFinder - the palette to register into; a no-op if null
      actionMap - the viewer's concatenated keybindings ActionMap
      inputMap - the viewer's concatenated keybindings InputMap, used only to resolve excludedTriggers to the action keys they are bound to
      path - palette category shown for every registered entry, e.g. List.of("Bvv Viewer")
      icon - icon applied to every registered entry via Action.SMALL_ICON; may be null
      excludedNames - action-map keys to skip outright, matched case-insensitively against the raw (un-prettified) key -- for contextual/"abort this in-progress gesture" natives that have no single dedicated trigger key, or SNT press/release-pair overlays (e.g., "hide annotations (hold)") that only make sense as a held key, never as a one-shot palette command
      excludedTriggers - keystrokes whose bound action should be skipped (the keystroke itself does not need to be a valid trigger for this viewer; unresolved ones are ignored)
    • registerCommandFinderAccelerator

      protected static void registerCommandFinderAccelerator(InputMap sntIMap, ActionMap sntAMap, SNTCommandFinder commandFinder)
      Wires commandFinder's own show/toggle shortcut (SNTCommandFinder.getAccelerator()) into this viewer's keybindings, so it fires while the Bvv/Bdv window itself has focus. Standard Swing accelerators (as installed by SNTCommandFinder.attach(JDialog)) don't reach here: BDV/BVV's behavior-based trigger layer intercepts keystrokes before a component's ordinary InputMap/ActionMap ever sees them (see the identical constraint noted where sntIMap/ sntAMap are built in Bvv/Bdv), so the shortcut has to be added to that same sntIMap/sntAMap pair instead, alongside SNT's other viewer-overlay bindings.
      Parameters:
      sntIMap - the viewer's own SNT-overlay InputMap, not yet installed via addInputMap
      sntAMap - the matching ActionMap, not yet installed via addActionMap
      commandFinder - the palette whose accelerator should open/focus it; a no-op if null
    • addTree

      public void addTree(Tree tree)
      Adds a Tree to the viewer overlay, assigning it a unique display label.
      Parameters:
      tree - the Tree to render; must not be null or empty
    • addTree

      protected void addTree(Tree tree, boolean syncNow)
      Internal add with optional immediate overlay sync. Subclasses may override if they need to track per-tree state beyond the shared map.
    • add

      public void add(Object o)
      Script-friendly dispatcher: accepts a Tree, DirectedWeightedGraph, File[], or any Collection of supported objects.
      Parameters:
      o - the object to add
      Throws:
      IllegalArgumentException - if the type is not supported
    • add

      protected void add(Object o, boolean syncNow)
      Internal dispatcher with deferred sync support for batch operations.
    • addCollection

      protected void addCollection(Collection<?> collection, boolean syncNow)
      Adds all elements of a collection, optionally syncing once at the end.
    • add

      public void add(File[] reconstructionFiles)
      Loads reconstruction files (SWC, JSON, TRACES) and adds them to the viewer. Trees are colored with distinct colors and the overlay is synced once at the end. Subclasses may override for async loading with progress feedback (see Bvv).
      Parameters:
      reconstructionFiles - the files to load; null or empty is silently ignored
    • removeTree

      public boolean removeTree(String treeLabel)
      Removes the tree with the given label from the overlay.
      Parameters:
      treeLabel - the display label of the tree to remove
      Returns:
      true if a tree with that label existed and was removed
    • clearAllTrees

      public void clearAllTrees()
      Removes all rendered trees from the overlay.
    • getRenderedTrees

      public Collection<Tree> getRenderedTrees()
      Returns a snapshot of the currently rendered trees (insertion order). Deliberately an independent copy, not a live view over renderedTrees - see renderedTreesLock's javadoc: a live view (the previous behavior) is vulnerable to a ConcurrentModificationException if another thread mutates renderedTrees while this collection is being iterated, which for a caller like Bvv.OverlayRenderer#updatePaths(Collection) (iterating well after this method returns) is a real, previously-observed race during active interactive tracing.
      Returns:
      collection of rendered trees (insertion order)
    • getMarkerManager

      public BookmarkManager getMarkerManager()
      Returns the marker manager panel, creating it lazily on first call via createMarkerManager().
      Returns:
      the marker manager for this viewer
    • hasMarkerManager

      public boolean hasMarkerManager()
      Checks whether a BookmarkManager has already been created for this viewer, without triggering its (lazy, non-trivial) creation as getMarkerManager() would. Useful for display/logging code that wants to report marker counts only if the panel is already in use.
    • setCalibration

      public void setCalibration(double[] spacing, String unit)
      Sets the voxel calibration for the viewer.
      Parameters:
      spacing - voxel sizes [x, y, z]
      unit - physical unit string (e.g., "um")
    • getCalibration

      public double[] getCalibration()
      Returns the current voxel sizes, or null if not set.
    • getBoundingBox

      public BoundingBox getBoundingBox()
      Returns the world-space bounding box of the primary loaded volume, assuming an origin at (0,0,0), i.e., no world-origin offset or per-source transform is factored in.
      Returns:
      the volume's bounding box, or null if dimensions/calibration are not yet known
    • getPrimarySourcePath

      public String getPrimarySourcePath()
      Returns the file path/URL of the primary loaded volume, for display/logging purposes (e.g., a Notes entry documenting the dataset being traced).

      Only sources registered through spimDataFilePaths (i.e., datasets opened via AbstractSpimData-based show(...) overloads, such as N5/Zarr/BDV/IMS data) are tracked. There is no guaranteed order if more than one source is loaded; this simply returns the first entry found.

      Returns:
      the source path/URL, or null if unknown/not applicable
    • getPhysicalUnit

      public String getPhysicalUnit()
      Derives the best available physical unit string. Subclasses may override to add viewer-specific fallbacks (e.g., reading units from source VoxelDimensions).
    • getUniqueLabel

      protected String getUniqueLabel(Tree tree)
      Returns a display label for the tree that is unique within renderedTrees. Derived from the tree's own label, appending "(2)", "(3)" etc. as needed.
    • isPathRenderingEnabled

      protected abstract boolean isPathRenderingEnabled()
      Returns true if path/tree overlay rendering is currently enabled.
    • setPathRenderingEnabled

      protected abstract void setPathRenderingEnabled(boolean enabled)
      Enables or disables path/tree overlay rendering.
    • setPathOverlayOffset

      public abstract void setPathOverlayOffset(double offsetX, double offsetY, double offsetZ)
      Applies a world-space offset to all rendered path annotations.
      Parameters:
      offsetX - x offset in calibrated units
      offsetY - y offset in calibrated units
      offsetZ - z offset in calibrated units
    • getRenderingOptions

      public AbstractBigViewer.PathRenderingOptions getRenderingOptions()
      Returns the rendering options shared across this viewer's overlays.
    • blockMarkerPlacement

      protected boolean blockMarkerPlacement()
      Whether M-key marker placement should be blocked in the current mode, showing a viewer message if so. True whenever SNTUI is present in "classic-mode-tracing", since the image canvas already has a fully working Bookmarks tab (Shift+B, right-click, etc.). Shared by Bvv/Bdv's own M-key bindings.
      Returns:
      true if placement was blocked (and a message shown); callers should return immediately without placing a marker
    • optionsButton

      protected JButton optionsButton(AbstractBigViewer.Actions actions)
      Builds the "Options" button (Import Reconstructions.../Remove All Annotations...) shared by Bvv/Bdv's own SNT Annotations toolbar.
    • autoBrightnessButton

      protected JButton autoBrightnessButton(AbstractBigViewer.Actions actions)
      Builds the "Auto Brightness/Contrast" options button (Current Source.../Active Source(s).../All Sources...) for the scene-control toolbar. See applyAutoBrightness(BrightnessScope).
    • tracingStatusRow

      protected JComponent tracingStatusRow(AbstractBigViewer.Actions actions, AbstractBigViewer.AbstractTracer tracer)
      Builds the second row shown below the SNT Annotations toolbar whenever this viewer has an active AbstractBigViewer.AbstractTracer (undo/cancel controls, secondary-layer toggle, progress bar). Shared by Bvv/Bdv, which both keep the returned components (see tracingStatusBar, tracingCancelButton, tracingUndoButton, secondaryLayerIndicator) in sync from their own AbstractBigViewer.AbstractTracer subclass.
    • showCalibrationDialog

      public void showCalibrationDialog(Component parent)
      Prompts the user for voxel spacing and its physical unit, and updates calibration.

      Confirming here also propagates to snt via SNT.setImageMetadata(int, int, int, double, double, double, java.lang.String).Dimensions are left untouched (passed as 0, which setImageMetadata treats as "no change").

      Parameters:
      parent - component used to anchor the dialog
    • buildBaseSceneControlToolbar

      protected JToolBar buildBaseSceneControlToolbar()
      Builds the shared scene-control toolbar: fit-source button, align-plane buttons (XY, XZ, YZ), minimap toggle, text-overlay toggle, scale-bar toggle. Subclasses call this and may prepend or append viewer-specific buttons.
      Returns:
      a partially populated JToolBar ready for additional buttons