Skip to content

Transform interaction

Sam Horvath requested to merge github/fork/vovythevov/TransformInteraction into master

Created by: vovythevov

This PR add a widget that allow user to interact with transform directly in the 3D view.

To support this feature, the following infrastructure was added/modified in Slicer:

  • Improved GetRASBounds(): The vtkMRMLDisplayableTransform method GetRASBounds() was improved to allow the user choose whether they want the bounds of the node transformed (when the node is observing a transform) or not. This is useful when you want to be able to have a cube that emcopasses the bounds of the node. Also, a boolean return value was added to be able to check easily if the bounding box returned is valid. Note: Because it wasn't very straight forward to do for the Segmentation node, it is NOT supported for this node. A warning is emitted if you try to use that option on such node. Testing was added with SlicerRASBoundsTest.py

  • Added Transform logic methods:

  1. GetNodesRASBounds(): This method is fairly straight forward and returns the RAS bounds of a list of nodes. It is tested in vtkSlicerTransformLogicTest3.cxx.

  2. GetTransformedNodes() This method returns the nodes that are observing a particular transform. It also offers the option to do so recursively so any nodes under a child transform may be returned as well. It is tested in vtkSlicerTransformLogicTest2.

  • Add TransformReferenceAddedEvent and TransformReferenceRemovedEvent The transform node lacked a good way to be notified when a node would start observing it. These new event remediate to this by being sent on the transform node whenever another node set it as its transform. This is tested in vtkMRMLTransformNodeOnNodeReferenceAddTest.

  • Minor fix of sample data This is simply to be able to use the CTA abdomen (Panoramix) dataset in testing because it is not centered and thus offers better testing for transforms.

The transform interaction itself has the following features:

  • The widget is shown/hidden based on the vtkMRMLTransformDisplayNode::VisualizationMode and the Visible option. The visualization mode option was chosen instead of a separate "Interactive" option because the interactive mode is so far incompatible with the other modes of visualization for the transform. In my opinion, it integrates better in the interface as well.

transformmodule

  • If no transform is present, the widget will have a default size so the user can still interact with it.

defaultsize

  • Whenever a node that has valid bounds is placed under the transform, the widget will automatically resize itself to the bounds of the node. onecube If multiple nodes (with valid bounds) are set under the transform, the widget will resize itself to encompass all the nodes. twonodes

  • GUI/Widget synchronization Of course, whenever the user interacts with the widget, the transform node will be updated. Likewise, the whenever the transform node is modified the widget will be updated.

  • Support for parent transforms Parent transforms are supported and allow one to be able to move node individually or by group like so: withparents

  • User interaction: The interaction is the standard provided by the widget. Options are exposed to the user through the transform module interface (enable/disable Scaling/Translation/Rotation).

Interaction infrastructure:

  • The underlying widget used is vtkBoxWidget2. This widget provides a very nice interface as you can directly set to it the desired transform.

  • No non-linear transforms: As of now, due to the limitations of the widget, the interaction does not support non-linear transforms.

  • Do not allow interactive and transform visualization at the same time The interaction takes precedence over the transform visualization.

  • Default scale size of widget: The default size is hard-coded for now in the displayable manager. It could made into a parameter later easily however.

  • Testing: The widget is tested through the SlicerTransformInteractionTest1. To do so, an internal method to access the widget was added to the vtkMRMLTransformsDisplayableManager3D.

Limitations and future work:

  • 2D interaction Unfortunately, VTK does not have an appropriate 2D widget that would work. The only remotely close widget vtkBorderWidget does not handle rotations correctly. To have the 2D interaction working, one would first have to write a VTK 2D widget for it.

Merge request reports