Difference between revisions of "Documentation/Labs/ViewInfrastructureImprovements"
From Slicer Wiki
(Created page with ' = Goal = * Update Slicer code base to listen to interactor instead of interator style = Motivation = * It is convenient to be able to easily change the interactor style witho…') |
|||
(4 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | = Goals = | ||
+ | * Update Slicer code base to listen to interactor instead of interactor style | ||
+ | * Add support for interactor style switch per view | ||
+ | * Allow access to vtkRenderWindow from vtkMRMLViewNode | ||
− | = | + | = Motivation = |
+ | |||
+ | * We would like to conveniently be able to change the interactor style without having to reset all observer for the displayable managers. | ||
+ | * Accessing the vtkRenderWindow would allow us to do (for example) screenshots given a specific viewNode. | ||
+ | |||
+ | = InteractorStyle management = | ||
+ | == Workaround == | ||
+ | === Access 3D View === | ||
+ | * Created a new Action menu in qSlicerMouseModeToolBar following [https://github.com/Slicer/Slicer/blob/a331fb0/Base/QTGUI/qSlicerMouseModeToolBar.cxx#L59-L103 this method.] | ||
+ | * Accessed all qMRMLThreeDView through the layoutManager : | ||
+ | <pre> | ||
+ | void qSlicerMouseModeToolBar::switchToTrackBallInteractorStyle() | ||
+ | { | ||
+ | qMRMLLayoutManager *layoutManager = qSlicerApplication::application()->layoutManager(); | ||
+ | |||
+ | // loop through all existing threeDViews | ||
+ | vtkNew<vtkThreeDViewInteractorStyle> interactorStyle; | ||
+ | for (int i=0; i < layoutManager->threeDViewCount(); ++i) | ||
+ | { | ||
+ | qMRMLThreeDView* view = layoutManager->threeDWidget(i)->threeDView(); | ||
+ | // Update Interactor style | ||
+ | this->SetInteractorStyle(view, interactorStyle.GetPointer()); | ||
+ | // Reset focal point | ||
+ | view->resetFocalPoint(); | ||
+ | } | ||
+ | |||
+ | // Update icon | ||
+ | Q_D(qSlicerMouseModeToolBar); | ||
+ | d->InteractorStyleToolButton->setIcon(QIcon(":/Icons/TrackBall.png")); | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | * Issue : not setting the interactor per view but for all views | ||
+ | * Possible solution : adding the switch in each 3D View Qt controller | ||
+ | |||
+ | === Update InteractorStyle === | ||
+ | * Set the interactorStyle to the qMRMLThreeDView interactor : | ||
+ | <pre> | ||
+ | void qSlicerMouseModeToolBar::SetInteractorStyle(qMRMLThreeDView* view, | ||
+ | vtkInteractorStyle* interactorStyle) | ||
+ | { | ||
+ | // Set InteractorStyle on renderview | ||
+ | view->interactor()->SetInteractorStyle(interactorStyle); | ||
− | + | // Get DMs | |
+ | vtkNew<vtkCollection> collection; | ||
+ | view->getDisplayableManagers(collection.GetPointer()); | ||
+ | int numManagers = collection->GetNumberOfItems(); | ||
− | = | + | // Set and Observe InteractorStyle for cameraDM |
+ | for (int i = 0; i < numManagers; ++i) | ||
+ | { | ||
+ | vtkMRMLCameraDisplayableManager *cameraDM = | ||
+ | vtkMRMLCameraDisplayableManager::SafeDownCast(collection->GetItemAsObject(i)); | ||
+ | if (cameraDM) | ||
+ | { | ||
+ | cameraDM->SetCameraToInteractor(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | collection->RemoveAllItems(); | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | * Issues : | ||
+ | ** Should need to update the observations for all the DM using [https://github.com/Slicer/Slicer/blob/8617758/Libs/MRML/DisplayableManager/vtkMRMLAbstractDisplayableManager.cxx#L309-L338 SetAndObserveInteractorStyle()], but this crashes Slicer. | ||
+ | ** The camera was not set anymore after a change of interactor styles in the vtkMRMLCameraDisplayableManager, so we had to use [https://github.com/Slicer/Slicer/blob/5ca7d0f/Libs/MRML/DisplayableManager/vtkMRMLCameraDisplayableManager.cxx#L518 SetCameraToInteractor()] and define it as a public method. | ||
+ | |||
+ | * Possible solution : updating Slicer core so that it listen only to the interactor instead of the interactorStyle. | ||
+ | |||
+ | == Design & implementation == | ||
+ | TODO | ||
+ | |||
+ | = vtkRenderWindow mapping = | ||
+ | == Workaround == | ||
+ | * Created a method that accessed the renderWindow through the layout manager MRMLViewFactory : | ||
+ | <pre> | ||
+ | vtkRenderWindow* getMRMLViewRenderWindow(vtkMRMLViewNode* viewNode) | ||
+ | { | ||
+ | qSlicerLayoutManager *layoutManager = qSlicerApplication::application()->layoutManager(); | ||
+ | qMRMLThreeDWidget* threeDWidget = qobject_cast<qMRMLThreeDWidget*>(layoutManager->mrmlViewFactory("vtkMRMLViewNode")->viewWidget(viewNode)); | ||
+ | vtkRenderWindow *renderWindow = threeDWidget->threeDView()->renderWindow(); | ||
+ | |||
+ | return renderWindow; | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | * Issue : calls to qMRML while we would prefer to stay with vtkMRML only | ||
+ | * Possible solution : map the vtkRenderWindow to the vtkMRMLViewNode in the view factory when creating the widget | ||
− | + | == Design & implementation == | |
+ | TODO |
Latest revision as of 20:44, 1 December 2015
Home < Documentation < Labs < ViewInfrastructureImprovementsContents
Goals
- Update Slicer code base to listen to interactor instead of interactor style
- Add support for interactor style switch per view
- Allow access to vtkRenderWindow from vtkMRMLViewNode
Motivation
- We would like to conveniently be able to change the interactor style without having to reset all observer for the displayable managers.
- Accessing the vtkRenderWindow would allow us to do (for example) screenshots given a specific viewNode.
InteractorStyle management
Workaround
Access 3D View
- Created a new Action menu in qSlicerMouseModeToolBar following this method.
- Accessed all qMRMLThreeDView through the layoutManager :
void qSlicerMouseModeToolBar::switchToTrackBallInteractorStyle() { qMRMLLayoutManager *layoutManager = qSlicerApplication::application()->layoutManager(); // loop through all existing threeDViews vtkNew<vtkThreeDViewInteractorStyle> interactorStyle; for (int i=0; i < layoutManager->threeDViewCount(); ++i) { qMRMLThreeDView* view = layoutManager->threeDWidget(i)->threeDView(); // Update Interactor style this->SetInteractorStyle(view, interactorStyle.GetPointer()); // Reset focal point view->resetFocalPoint(); } // Update icon Q_D(qSlicerMouseModeToolBar); d->InteractorStyleToolButton->setIcon(QIcon(":/Icons/TrackBall.png")); }
- Issue : not setting the interactor per view but for all views
- Possible solution : adding the switch in each 3D View Qt controller
Update InteractorStyle
- Set the interactorStyle to the qMRMLThreeDView interactor :
void qSlicerMouseModeToolBar::SetInteractorStyle(qMRMLThreeDView* view, vtkInteractorStyle* interactorStyle) { // Set InteractorStyle on renderview view->interactor()->SetInteractorStyle(interactorStyle); // Get DMs vtkNew<vtkCollection> collection; view->getDisplayableManagers(collection.GetPointer()); int numManagers = collection->GetNumberOfItems(); // Set and Observe InteractorStyle for cameraDM for (int i = 0; i < numManagers; ++i) { vtkMRMLCameraDisplayableManager *cameraDM = vtkMRMLCameraDisplayableManager::SafeDownCast(collection->GetItemAsObject(i)); if (cameraDM) { cameraDM->SetCameraToInteractor(); } } collection->RemoveAllItems(); }
- Issues :
- Should need to update the observations for all the DM using SetAndObserveInteractorStyle(), but this crashes Slicer.
- The camera was not set anymore after a change of interactor styles in the vtkMRMLCameraDisplayableManager, so we had to use SetCameraToInteractor() and define it as a public method.
- Possible solution : updating Slicer core so that it listen only to the interactor instead of the interactorStyle.
Design & implementation
TODO
vtkRenderWindow mapping
Workaround
- Created a method that accessed the renderWindow through the layout manager MRMLViewFactory :
vtkRenderWindow* getMRMLViewRenderWindow(vtkMRMLViewNode* viewNode) { qSlicerLayoutManager *layoutManager = qSlicerApplication::application()->layoutManager(); qMRMLThreeDWidget* threeDWidget = qobject_cast<qMRMLThreeDWidget*>(layoutManager->mrmlViewFactory("vtkMRMLViewNode")->viewWidget(viewNode)); vtkRenderWindow *renderWindow = threeDWidget->threeDView()->renderWindow(); return renderWindow; }
- Issue : calls to qMRML while we would prefer to stay with vtkMRML only
- Possible solution : map the vtkRenderWindow to the vtkMRMLViewNode in the view factory when creating the widget
Design & implementation
TODO