Rotate slice view up interactively

I would like to allow a user to interactively rotate the slice view up direction, similar to how the Ctrl-Alt-Left Drag shortcut allows rotation of lined slice planes, but in this case rotating only the clicked-on slice view, and only within its current plane, about it’s current center. I think the actual reorientation can be handled pretty easily using SetSliceToRASByNTP(), by keeping the same slice normal and position and varying the ‘T’ vector to set the transverse vector orientation, but I am having trouble figuring out how to implement the click-and-drag functionality. I want users to be able to hold down a shortcut (say Ctrl-R for example), and then left click and drag on a slice view. The view should then interactively rotate as the user drags, with the amount of rotation obtained by the angle formed between the line segments connecting the slice center and the the initial click location (the start of the drag) and connecting the slice center and the current mouse location. I gather that I will need to do something like SetEventTranslationClickAndDrag on some widget (a slice view manager of some kind?), but from the examples I can find (like these), I can’t tell what all the inputs are and how to define the callbacks. If anyone can provide a little guidance to get me started, I would appreciate it. Thanks!

Handling interactions at the mouse event level is doable, but can be tricky since you need to worry about interaction with other things like segment edtior effects, widgets, mouse modes, etc. You might be better to add this as a feature to the existing interactive slice planes. Or make changing the orientation of the slice planes a byproduct of manipulating a markups line or something that already manages mouse behaviors.

1 Like

I’d be fine with using a markups point in something like the following way: Pressing Control-R activates this functionality by creating a set of markups points which is to the right of center in each slice view (since I no longer have any guide for which slice view the user wants to rotate), and then grabbing and moving that point results in rotating that view in plane about its current center. Then pressing Control-R again removes the created markups points. I’ll try to get this working. It does sound simpler than working with mouse events at a lower level, and would still provide the functionality in a pretty straightforward way. Thanks for the suggestion @pieper, if I get it working I’ll post back here.

You can also use Reformat module’s Rotation / In-Plane slider. This is what we do in SlicerHeart to align slice view to a valve axis (using two sliders) and nobody is complaining.

If you are not allowed to use a slider then you can add a new widget action to vtkMRMLSliceIntersectionWidget that rotates the current slice (instead of rotating theintersecting slices). You can then map a new widget event (e.g., click-and-drag with some keyboard modifiers) or remap a widget event that you don’t need to do slice rotation. It should be all very straightforward and about 20-30 new lines of code in total.

Another option is to use a markup plane to specify a direction in 3D (you can drag-and-drop and rotate the plane in all the slice and 3D views). When the plane is in good orientation then you can automatically align all the views.

I would also consider doing this fully automatically. Most likely you can use an existing AI model to segment some structures that you can use to determine the anatomical axis directions, or you can train a new model to recognize axis directions.

1 Like

Thanks @lassoan for the ideas. I actually already use an automatic approach to anatomical orientation (Rotate reformat slice view (in plane) - #6 by mikebind) which works very well most of the time. However, sometimes, for very oblique views, it would actually be better to use some sort of custom rotation, and I’d like to give myself and other users the option to rotate as easily as we can reslice. This would also be helpful sometimes when, for example, a patient’s head is turned a bit to one side relative to the image volume axes, and it would be nicer just to rotate the axial view in plane so that anterior for the patient is up on the slice view. This could be accomplished in automated ways or interactive ways of varying complexity, but when it’s just for the aesthetics of screenshots, I’d love to have an easy way to just rotate the view. The Reformat module in my Slicer doesn’t have a Rotation/In-Plane slider; I see that newer versions do. I have been stuck on 5.2.1 for a while because updates to the Elastix module broke some of my code in >5.2.1 and I haven’t dug into why yet (I don’t think it will be a difficult fix, I just haven’t gotten around to it yet, and I haven’t had a strong enough reason that I needed to update Slicer yet either). This might now be enough of a reason.

Is this something I can do in python or would it require building Slicer from source?

You can remap what keyboard/mouse gesture is mapped to what widget action in Python but your can only add new widget action C++. The feature would be added to Slicer core.

1 Like