From Slicer Wiki
Jump to: navigation, search
Home < Documentation < Labs < VTKWidgets


This page has the following purposes:

  • It documents the user and developer features we wish to support in Slicer
  • It documents the changes could be considered in the official VTK Widgets.
  • It presents Slicer specific implementation acting as an alternative to VTK widgets.
  • It evaluates the VTK widgets in terms of the appropriateness of their current design and implementation for efficiently addressing the needed use cases in Slicer.

Features Missing in 4.4

For Users

  • Control L to make a new fiducial list
  • Control I for persistent place toggle
  • Control M to make a ruler between last two placed fiducials
  • back tick and control/shift back tick to jump slices to fiducials
  • delete or backspace (or 'd') to delete fiducial under mouse
  • 'p' to place fiducial without having to click in window to grab focus
  • Right click context menu (allow all operations currently supported in the table widget in the Markups GUI)
  • modifier key to move fiducials between slices in 2D
  • scaling issues (2D widget is scaled down by 300x compared to 3D)
  • restrict to surface (found issues with the point placer wrt how it would be used in Slicer)
  • rubber band placement for rulers

For Developers

  • A start/end and moving event with seed number
  • A start/end and hover event
  • near widget vs near handle events
  • A 2D version of the oriented handle widget
  • consistent widget interfaces for click to place as well as programatic placement (vs them being added with zero size and having to be manipulated)
  • consistent distribution of settings from the widget to all handles (process events on/off, visibility, display properties).
  • expanded WidgetState settings that can be queried and maybe set

Design and Implementation


For the fiducials, we are currently using a vtkSeedWidget in both 2D and 3D. With the oriented polygonal handle representation being the only option to show a glyph and text together, and it being a 3D widget, it introduces some quirks in the 2D viewers. The Markups displayable managers have already been split into 2D and 3D versions to deal with this.

Some approaches:

  • subclass the seed widget and representation and handles and create Slicer specific implementations
    • Cons:
      • not easy to feed back into VTK
    • Pros:
      • full control
      • did something similar already with the ROI widget
  • modify the Slicer specific VTK github fork to implement the features we need in C++, then migrate them back via gerrit
    • Cons:
      • Still constrained by the VTK implementation as a starting point
    • Pros:
      • more freedom to experiment/customise
      • easy to feed back into VTK
  • Port the Slicer3 Tcl implmentation of the 2D fiducials to Python for Slicer4
    • Cons:
      • issues with the reloadability of the scripted displayable managers
      • not easy to feed back into VTK
      • not quite as modular as we might end up with the widget type code embedded in the displayable manager
    • Pros:
      • full control
      • nominally easier as that version supported many of our missing use cases
  • Port the Slicer3 Tcl implementation of the 2D fiducials into C++ for Slicer4
    • Cons:
      • Slightly more complex port
    • Pros:
      • full control
      • supports modularity (make a widget class first, then the displayable manager can be scripted)
      • can have a custom VTK class in our fork, easy to port back to VTK


vtkAnnotationROIWidget/vtkAnnotationROIRepresentation are clones of vtkBoxWidget2/vtkBoxRepresentation that have been modified and extended. Ideally the necessary changes will be integrated back into the VTK classes. The changes are:

  • Commented out face picking, and therefore rotation by dragging on faces. The VTK classes now offer this control.
  • Added control over the color of individual handles. The only concern would be maintaining a backwards compatible API.
  • Added members and getters related to handling when the MRML node has a parent transform. For example, WorldToLocalMatrix, GetExtents(), GetCenter(), and GetActors().

The transform-related additions seem intended to either simplify or optimize how vtkMRMLAnnotationROIDisplayableManager synchronizes the MRML node and the widget. For example, instead of calling SetTransform() on the widget, which would rebuild the representation, the displayable manager sets the UserMatrix on all the vtkActors. Another example is how GetExtents() and GetCenter() return computations based directly on the point data, which are now always in local coordinates, whereas calling GetBounds() would return world coordinates.

Reworking the displayable manager to not use these extra functions seems possible. One concern would be that doing so would affect performance, because likely the extra functions allow optimization by avoiding excessive transforming of the points and rebuilding of the widget representation. Another concern would be verifying that the proper coordinate frames are used in the reworked the display manager, since the code is currently not well-documented and some method calls to convert coordinate frames are simply commented out.