Hello everyone,
So I’m developping a module in python and at some point i need to move the camera around. For that I need to disable all the interaction that moves the camera around in the 3D view.
My solution for now is to reach the interactor and to delete it until the module does not need it anymore. I use those few lines to achieve it :
#Copy original interactor
self.interactorStyle = slicer.app.layoutManager().threeDWidget(0).threeDView().interactorStyle()
self.interactor = self.interactorStyle.GetInteractor() #Delete the interactor
self.interactorStyle.SetInteractor(None) #Reset the interactor
self.interactorStyle.SetInteractor(self.interactor)
It works for now but i’m afraid that it could interfere with other modules or cause problem with slicer directly.
I tried to find some other functions on vtkInteractorStyle but none seemed to work as i wanted.
Is there a way to achieve what i did directly in slicer or with a function i would have missed ?
Sorry to re-open this topic, but I don’t undestand the proposed solution since vtkMRMLThreeDViewInteractorStyle has no SetActionEnabled function.
Also, vtkMRMLThreeDViewInteractorStyle::EnabledOff() and vtkMRMLThreeDViewInteractorStyle::Off() do not deactivate interaction with the 3D scene.
So, how does one disable interaction in a 3D view ?
SetActionEnabled was added at the time when keyboard&mouse gestures were hardcoded and we needed a way to disable some. Now you can add/remove/edit all keyboard&mouse gestures - see for example here. SetActionEnabled method is only kept for backward compatibility, but I would not recommend using them anymore.
I see, but if I were to follow this example, disabling all interaction would require to set all events of the camerawidget to vtk.vtkWidgetEvent.NoEvent, right ? Given the number of interactions possible in vtkCommand, this will be quite long (unless I could loop on it). Isn’t there a simpler way ?
In general, it is not expected that a module disables all other modules. You are always expected to know what features you disable and why. You might be able to implement some simpler hacks, such as adding an observer to the interactor for all interaction events with very high priority that consumes all the events (as it is done in Segment Editor, which was implemented before the widget infrastructure was in place).
I’m displaying a frustum in 3D from a very specific point of view, so I don’t want the user to be able to move the camera and change that point of view.
Also, I’m using parallel projection for the camera and mouse-wheel zooming turns it off for some reason (if it’s a bug I’ll open a new separate ticket).
I’m displaying a frustum in 3D from a very specific point of view, so I don’t want the user to be able to move the camera and change that point of view.
Then disabling camera translation & rotation may make sense. You may still want to allow right-click menu, etc. so it makes sense not to disable all interactions.
Mouse wheel should not change camera projection, so it that happens then it is a bug. I tried this and for me the view is zoomed in/out with mouse wheel correctly (without changing projection mode).
I see, this is not a bug, but it is due to that camera projection mode is defined in vtkMRMLViewNode. If you change it in the camera VTK object then the view node will restore it to the stored value at the next update. I agree that this can be unexpected and it is probably like this due to historical reasons. You could file an enhancement request to change this (i.e., only store projection mode in the camera node, not in the view node).