Difference between revisions of "Documentation/Labs/ViewInfrastructureImprovements"

From Slicer Wiki
Jump to: navigation, search
m (moved Documentation/Labs/InteractorStyle to Documentation/Labs/ViewInfrastructureImprovements: including improvements for interactorstyle & mapping between vtkRenderWindow & vtkMRMLViewNode)
 
(3 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
  
= Goal =
+
= 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);
  
* Update Slicer code base to listen to interactor instead of interator style
+
  // Get DMs
 +
  vtkNew<vtkCollection> collection;
 +
  view->getDisplayableManagers(collection.GetPointer());
 +
  int numManagers = collection->GetNumberOfItems();
  
= Motivation =
+
  // 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
  
* It is convenient to be able to easily change the interactor style without having to reset all observer.
+
== Design & implementation ==
 +
TODO

Latest revision as of 20:44, 1 December 2015

Home < Documentation < Labs < ViewInfrastructureImprovements

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