Slicer4:SliceViews
This is a page describing the functionality, architecture and implementation of the slicer4 slice views.
Contents
Goals
The overall goal is to provide a full-featured set of 2D slice capability with at least the level of functionality, performance, and accuracy provided in slicer3. This implementation needs to be accomplished by the slicer4 team during the summer/fall 2010 timeframe for delivery to the larger developer community for use during the January 2010 NA-MIC All Hands Meeting.
Approach
Background
Because the slice views include significant interactive components they rely on all parts of slicer. In Slicer3, the slice view depended not only on VTK, but also on the KWWidgets GUI infrastructure to implement much of the event management and display. This code was developed using object oriented scripting (incrTcl) on top of tcl-wrapped VTK and KWWidgets (http://viewvc.slicer.org/viewcvs.cgi/branches/Slicer-3-6/Base/GUI/Tcl/). The Editor Module also relies heavily on this infrastructure.
Adapter Layer
In slicer4 uses Qt instead of KWWidgets, and python-wrapped VTK so porting the existing code is non-obvious. To address this, a python-in-tcl compatibility layer was added to slicer to allow tcl scripts to run on top of a python-wrapped vtk (this is essentially the inverse of the slicer3 python functionality that allow python scripts to run on top of a tcl-wrapped vtk).
In addition, a number of KWWidgets and Slicer3 helper classes (such as the vtkKWRenderWidget, vtkSlicerApplicationGUI, etc) are not available in slicer4. To address this, a Slicer3Adapters.tcl file contains a set of facade classes that mimic the needed parts of the behavior of slicer3 classes.
Longer Term
Slicer4 has adopted the concept of MRML Displayable Managers as a way to organize interactive components in 2D and 3D views. As time permits, more and more of the behavior will be ported and implemented in this framework. Once functionality parity is achieved, the adapter layer can be phased out.
Development Issues
This section refers to active development issues during summer/fall 2010:
- slice view corner annotation - in slicer3 this was in vtkKWRenderWidget, in slicer4 functionality not yet exposed
- status label - in slicer3 was in vtkSlicerApplication - slicer4: ?
- sliceplane widget - in slicer3 each slice view was able to add a 3D vtk widget directly to the 3D viewer - for slicer4 we will want to have a 3D Displayable manager to manage this (and a setting on a mrml node, probably the slice node, indicating that the viewer should be visible).
- need to be able to access a 'RequestRender' method from the script. This is needed so that any SWidget that adds or modifies vtkActors in the slice view can ask for a render to be performed during the next idle time in the event loop.
- come up with an application wide control for 'ownership' of the events. In slicer3's vtkSlicerSliceGUI an SWidget could set the GrabID member to a unique string so that other widgets would not try to respond to the event (but would have a chance to examine it if they wished, and sometimes do actions like de-highlight themselves). For example, if you mouse over a fiducial, it sets the grab id to itself and then highlights itself. If a left mouse click comes before the mouse moves off the fiducial, the fiducial responds and not the default left mouse handler (window/level control).
- application resources and themes - a script may need to get the current theme info (colors, fonts, etc). I'm guessing there's a way to do this with PythonQt.
- implement delayed annotation calculation and display. We found that vtkText display is fairly slow and should not be updated at every frame while interacting. For slicer3 there is a delayed annotation feature so the text only shows if your mouse is not moving for 300 milliseconds. We will need something similar for slicer4.
- Compare View: relies on helper methods from the Slices module to coordinate which slice views should be linked. This will need to be reimplemented for slicer4.
- Need a way to create a fiducial in the mrml scene at a given point - in slicer3 the FiducialsSWidget code had access to the FiducialsLogic::AddFiducialPicked method.
- object references are not properly cleaned up yet.
- need a way to emulate the tcl 'after' command with either 'idle' argument or number of milliseconds argument. It seems QTimer is not exposed in PythonQt currently.
Status
- built when Slicer3_USE_PYTHONQT_WITH_TCL is enabled in the Advanced section of CMake.
- What works 2010-08-26:
- slice controls: pan/zoom, mouse wheel, arrow keys, rotate with control-right when in reformat mode
- fiducial display and interaction (need to load a scene that includes fiducials - cannot create in slicer4 yet). (Still need to run a script to trigger them)
- slice intersection display (turn on in the Manipulate Slice Views cursor menu). Need to move mouse into window to trigger redraw.
- window/level control with left mouse button
- Not yet working:
- label grid not tested (can't display label layer in slicer4 yet)
- crosshairs not displaying
- there is room for more performance optimization once the 'after' command is fixed
- slice plane widget
- Nothing in the editor has been touched yet. This will require more work since the gui will need to be converted to pythonqt.
- Compare view not tested
- Lightbox not tested
Update 2010-09-01
- Working
- Fiducials are working normally - load a scene like Slicer3/Libs/MRML/Testing/fiducial_tract.mrml to get a fiducial you can work with.
- Crosshairs are working too - in the python prompt type: "getNodes()['vtkMRMLCrosshairNode1'].SetCrosshairMode(3)" and you can use different numbers 0, 1, 2, to play with different crosshair types (don't go past 6 though or it will crash!). This crosshair node appears not to be hooked up to the Manipulate Slice Views menu yet.
- The label grid also works (I saw it working on Daniel's machine).
- lightbox is working nicely
- window/level control by dragging left mouse
- Not Working
- Corner annotation on the slice views
- slice plane widget not working (probably needs to be re-thought anyway)
- Ron says: yes please!
- Functionality: define an oblique reformat plane.
- Allow to link multiple slice views for oblique but orthogonal reformats.
- Needs a module / slider based interface with numerical inputs as well.
- ruler display not tested (no way to create the node) - will be replaced by annotation node anyway.
- slice intersection is 1/2 working - only Green slice is correctly displayed, Yellow shows only Red slice and Red shows nothing. This is probably due to the order that actors are added to the renderer.
- Not sure yet if all this works on CPacked installers, but hopefully launcher issues are sorted out for python and tcl packages in build trees.
- Biggest issue is performance - still doing profiling and other investigation to get at the root cause.
- A couple of crashs reproducible with easy workflow
- Manipulate 3D view toolbar is still WIP
- Some sizing issues with the 2D views