Difference between revisions of "Documentation/Nightly/Developers/DisplayableManagers"

From Slicer Wiki
Jump to: navigation, search
Line 3: Line 3:
  
 
Displayable managers are registered into a view factory (e.g. 3D view displayable manager factory) and when a view is created, the factory instantiate each displayable manager and associate them to the view.
 
Displayable managers are registered into a view factory (e.g. 3D view displayable manager factory) and when a view is created, the factory instantiate each displayable manager and associate them to the view.
There is 1 instance of each displayable manager per view/renderer. For example, in the conventional layout, the 2D model displayable manager (<code>vtkMRMLModelSliceDisplayableManager</code>) is instantiated 3 times, once for the red slice view, once for the yellow slice view and once for the green slice view.  
+
There is 1 instance of each displayable manager per view/renderer. For example, in the conventional layout, the 2D model displayable manager (<code>vtkMRMLModelSliceDisplayableManager</code>) is instantiated 3 times: once for the red slice view, once for the yellow slice view and once for the green slice view.  
  
 
Theoretically the slice logics should be displayable managers ( however, it might be a huge effort for just the sake of being consistent ).
 
Theoretically the slice logics should be displayable managers ( however, it might be a huge effort for just the sake of being consistent ).

Revision as of 23:57, 17 January 2013

Home < Documentation < Nightly < Developers < DisplayableManagers

Displayable Managers

Displayable managers automatically observe the scene and when a matching display node is added into the scene, they create corresponding VTK actors to add them in their VTK renderer. For example, the model displayable manager creates a vtkPolyDataActor and vtkPolyDataMapper when a vtkMRMLModelDisplayNode is added into the scene.

Displayable managers are registered into a view factory (e.g. 3D view displayable manager factory) and when a view is created, the factory instantiate each displayable manager and associate them to the view. There is 1 instance of each displayable manager per view/renderer. For example, in the conventional layout, the 2D model displayable manager (vtkMRMLModelSliceDisplayableManager) is instantiated 3 times: once for the red slice view, once for the yellow slice view and once for the green slice view.

Theoretically the slice logics should be displayable managers ( however, it might be a huge effort for just the sake of being consistent ).

Displayable managers contain some limitations

  1. there is no control (yet?) over their creation, and once instantiated, it's not easy to control their behavior (properties can't be set externally on displayable managers).
  2. they are not (yet?) well designed to communicate with each others.

Build

Displayable managers are instantiated from their class name by the displayable manager groups. An instantiator must be included in the library containing the displayable manager. To do so, add in your CMakeLists.txt:

set(displayable_manager_SRCS
 vtkMRMXYZDisplayableManager.cxx
 )
set(VTK_USE_INSTANTIATOR_NEW 1)
VTK_MAKE_INSTANTIATOR3("${MODULE_NAME}Instantiator"
  displayable_manager_instantiator_SRCS
  "${displayable_manager_SRCS}"
  "${${KIT}_EXPORT_DIRECTIVE}"
  ${CMAKE_CURRENT_BINARY_DIR}
  "${KIT}Export.h"
  )
set(${KIT}_SRCS
  ${displayable_manager_instantiator_SRCS}
  ${displayable_manager_SRCS}
  ...
  )

Register

Displayable managers must be registered as early as possible (before the first view is created. Therefore, displayable managers should be registered when modules are setup.

void qSlicerXYZModule::setup()
{
  ...
  // If the displayable manager is for 3D views:
  vtkMRMLThreeDViewDisplayableManagerFactory::GetInstance()->RegisterDisplayableManager(
     "vtkMRMLXYZDisplayableManager");
  // If the displayable manager is for 2D views:
  vtkMRMLSliceViewDisplayableManagerFactory::GetInstance()->RegisterDisplayableManager(
     "vtkMRMLXYZDisplayableManager");
  ...
 }

How a view is refreshed

It's the 3D view (ctkVTKAbstractView) that controls WHEN the vtkRenderWindow::Render is called. There are 2 ways to tell the view to re-render:

  1. vtkRenderWindowInteractor::Render() is called (by vtkInteractorStyle when the mouse is moved or by some vtkWidgets that call it internally). The request is blocked and ctkAbstractView::scheduleRender() is called on the view.
  2. or it is done by the vtkMRMLDisplayableManagers (e.g. vtkMRMLVolumeRenderingDisplayableManager) by the RequestRender() calls. They call vtkMRMLDisplayableManagerGroup::RequestRender() which fires a vtkCommand::UpdateEvent. The Qt view (e.g. qMRMLThreeDView) observes the UpdateEvent and calls ctkVTKAbstractView::scheduleRender().

The CTK view compacts the render requests and ensure the FPS (vtkRenderWindow::GetDesiredUpdateRate()) is respected.

 vtkInteractorStyle ---------------------------\
 vtkWidget -------------------------------------> vtkRenderWindowInteractor::Render() ------------------------------\
 vtkMRML???DisplayableManager::RequestRender() -> vtkMRML???DisplayableManagerGroup::RequestRender() -> UpdateEvent -> ctkVTKAbstractView::scheduleRender()