Discuss open questions
|Open||None||T23721 Project "Astonishing Angelfish"|
|Open||None||T23758 Introduction of custom multi widget editor|
|Open||None||T24216 Synchronization of individual render windows: camera position|
|Resolved||kalali||T24232 Discuss camera position synchonization|
The MouseModeSwitcher is initialized in the StdMultiWidget / CustomMultiWidget. It creates the DisplayInteractor, loads a state machine (*.xml) and connects the actions and functions for interaction.
The DisplayInteractor has access to the RenderingManager singleton instance and is therefore able to update all currently know render windows. This is done in DisplayInteractor::SetCrosshair, which is triggered on a LeftMouseButton-click. A new crosshair position is set for all render windows (except the sending render windows, since setting a new position on a 2D slice does not change the camera-view).
Zooming or panning does not affect other render windows than the sending render window. If we want the syhcnronization behavior for other camera modifications, like zoom, we have to establish a similar mechanism here (e.g. DisplayInteractor::Zoom).
However, here also the sender has to be updated, since zooming, scrolling or moving (pan) also changes the camera-view of the sender.
Scrolling is different since the slice number varies for different images in the render windows.
Currently, for testing purposes, the zoom- or pan-function is called for each known render window (before it was only called for the sending render window).
This synchronizes the mouse interaction throughout all render windows.
The drawback is, that this changes the behavior for the DisplayInteractor, which is also used in the StdMultiWidget.
If we now want to be able to switch from synchronization to de-synchronization, we need to implement a mechanism that can dynamically handle those events.
We would then be able to allow the synchronization only on demand, e.g. when using the custom multi widget.
The DisplayInteractor-class seems to be a good place to include the synchronization, since it knows the original sender and event and also all render windows (using the RenderingManager).
QmitkRenderWindow is a mitk::RenderWindowBase and its initialization function
- adds the vtkRenderWindow to the RenderingManager (the vtkRenderWindow is created in and retrieved from the QVTKWidget),
- creates a new mitk::VtkPropRenderer and
- adds the pair (vtkRenderWindow, mitk::VtkPropRenderer (as mitk::BaseRenderer) to the globally accessible BaseRenderer-map.
In order to change e.g. the camera position via mouse interaction, the vtkRenderWindow's and the vtkPropRenderer are accessed. Here, the rendering manager is asked for all render windows and the vtkPropRenderer is accessed inside the aforementioned BaseRenderer-map.
The mitk::VtkPropRenderer is currently the only implementation of our mitk::BaseRenderer.
So basically, with the RenderingManager and the BaseRenderer-map, which are both accessible via singleton / static function, we can modify the camera controller / slice navigation controller from everywhere and update the render window afterwards.
Accessing the global RenderingManager singleton requires it to keep / register the vtk render windows.
It is also possible to have different RenderingManager for each vtk render windows, but this introduces another issue, which we won't discuss here.
So as written before, the mitk::DisplayInteractor-class has access to the mentioned mitk::RenderingManager and the BaseRenderer-map.
Additionally it knows the sender (the sending mitk::VtkPropRenderer / the interaction event).
We could subclass and extend the DisplayInteractor to a SynchronizedDisplayInteractor, which extends the functionality and thus sets e.g. the zoom and the pan for other render windows. This has already been proven to work, but extending the DisplayInteractor would allow the StdMultiWidget to keep the simpler interactor, while the CustomMultiWidget could use the SynchronizedDisplayInteractor.
However, the MouseModeSwitcher needs to be adjusted to create the correct interactor.
Another possibility would be to define an own DisplayConfig.xml file and extend the DisplayInteraction.xml-file. However, we still would need to either add new functions to the DisplayInteractor or to subclass it. And the MouseModeSwitcher needs to be adjusted as well to create the correct interactor / load the correct config-files.
This solution does also not handle the context-issue.
So either subclassing or extending the DisplayInteractor would need a mechanism to notify a SynchronizationHandler, which knows the sender, all other render windows, the current QmitkAbstractRenderEditor (or berry::Workbenchpart or mitk::IRenderWindowPart) and the InteractionEvent on which to react.