Setting mouse place mode for specific view

It is currently possible to globally change the interaction mode (PersistentPlaceMode, SinglePlaceMode, ViewTransformMode) by updating the interaction node singleton. This is exposed to the user using the place mode toolbar:

image

In custom application, it is sometimes needed to disable placing of “annotations” only in specific view.

To support this, I proposed to:

  • update vtkAbstractViewNode adding a SupportedInteractionMode bit field

    • by default it would be initialized to 0 for all type of view.
    • and initialized to Place | ViewTransform only for for vtkMRMLViewNode and vtkMRMLSliceViewNode.
  • the Place and ViewTransform corresponds to values of mouse mode enum in vtkMRMLInteractionNode

This would allow to easily disable support for Place mode in specific view.

In addition to the SupportedInteractionMode bit field, we also need to keep track of the current interaction mode for each view.

There are two possible approaches:

  1. add a CurrentInteractionMode property to the view
  2. update vtkMRMLInteractionNode to keep track of interaction mode for all views.

(I see Andras is replying too - let’s see if he says the same thing…)

Why not use the list of view names like in the display nodes?

Currently, difference in behavior is usually managed by using display nodes. For example, we can already show/hide annotations in selected views. We could add a bitfield to display nodes that describe what interactions are allowed in that view.

Alternatively, we could use the technique that we use for connecting layout managers to views using ParentLayoutNode reference (if no parent node is defined then the default layout manager should be used). Implementation would be adding reference to InteractionNode (and maybe also to SelectionNode). If this node reference is undefined then the default interaction node would be used. This method would have the advantage that we could set what annotation to place in which view.

The issue is that corresponding display node do not exist yet.

I like the idea but currently both interaction and selection node are singleton, these would be quite a disruptive change I think.

I think we need more than a list. Indeed, the idea is to keep track of:

  • which interaction modes are supported by which view.
  • current mode of a given view

If needed, you can pre-create annotation/markup node and corresponding display node. You can definitely do it for markup fiducials but may be some annotation nodes cannot be pre-created with 0 points. Anyway, this is not a good solution anyway, as it would not allow customization of markup/annotation node selection per view.

It is similar change as we implemented for managing virtual reality views by non-default layout manager. It does not seem disruptive to me.

I would not even consider any solution that only allows customization of interaction flags and not what markup node to place.

For example, in landmark registration module, we show fixed image in top row, moving image in middle row (and registration result in bottom row). It would be a bad solution to just enable landmark placement in either fixed or moving image views. We must keep placement enabled in all views but we need to place different landmarks in different view groups.

In the virtual reality extension, we implemented a custom layout node. This means that we didn’t have to change the “singleton-ness” of the layout node.

To support different interaction node for different view, we would have to instantiate multiple interaction node.

Are you suggesting we change selection and interaction node to not be singleton anymore ?

If interaction (and/or selection) node ID is not defined in a view node then the default singleton interaction node is used. If a custom node interaction node ID is defined then that is used. This logic can be implemented at one place (probably in the view node) and can be used everywhere where interaction node for a view is needed.

This would be such a great feature! No more switching between placed fiducial groups (markup nodes).

How do you propose to do this without removing the singletonness of the interaction node? If you awnt to have a second interaction node in the scene then it cannot be singleton I think. Or do you propose keeping it out of the scene? It doesn’t seem like a good way to do it.

Additional selection and interaction nodes would not need to be singletons.

1 Like

That would work, doing the following allow to create additional interaction node:

n = slicer.mrmlScene.CreateNodeByClass("vtkMRMLInteractionNode")
n.SetSingletonOff()
slicer.mrmlScene.AddNode(n)

I also suggest to add a reference between interaction and selection node, they both work in pair.

After adding a selection node reference to the view, it was pretty straightforward to update the code base.

That said, the following three widgets are directly interfaced with the default interaction node:

  • qSlicerMarkupsPlaceWidget
  • qMRMLSegmentEditorWidget
  • qSlicerMouseModeToolBar:

By default, I suggest the widgets continue to look up the default interaction node but a new SetInteractionNode(vtkMRMLInteractionNode* ...) function will be added.

1 Like

Here it is: