Update slice view positions and orientations using MarkupsFiducialNode interactions

Hi every one,
I add an interactive vtkMRMLMarkupsFiducialNode with a single point which allows me to update my 2D views orientations and positions.
But here’s the thing, if I call SetNthControlPointPosition, then when I try to move it on the 3D view, then it only moves along Axial axis. I can’t translate it on other direction.
Does anyone has any clue about this ?
Thanks a lot.

Depending on “Placement mode” setting (in Markups module / Display / Advanced / 3D Dsiplay) in 3D views markups either move in the camera plane or it snaps to the surface visible at the mouse pointer position. Do you experience a different behavior?

Hi Andras,
I tried to move from ‘snap to visible surface’ and ‘unconstrained’ but I have the same.
I forgot to mention that I did that in a custom python module.
Here is the main goal. I want to update the red slice according to the markups position, but I also want to update the markups position if I move the 2D slices. So I first create the markups

orientationMarkupsNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsFiducialNode")

def _onPlaneMarkupChanged(self):
  # Update the red slice position

I also observe the 2D slices modified event

slicer.util.getNode("vtkMRMLSliceNodeRed").AddObserver(vtk.vtkCommand.ModifiedEvent, self._updateMarkupPosition)

def _updateMarkupPosition(self):
  # Update the markups position by setting it the correct position
  orientationMarkupsNode.SetNthControlPointPosition(0, correct_position)

If I call the SetNthControlPointPosition then my markup is blocked along the Z axis. But if I don’t call it, it works well except I cannot update it when I move 2D slices.

To be honest, I’m surprised that it doesn’t make a loop because as I understand, the SetNthControlPointPosition called PointModifiedEvent but maybe it’s an other issue…

Is it clearer @lassoan ?

If you move the slice views wherever the markup point is then it is important to exclude the view that you are interacting with. You can use the 'Markups.MovingInSliceView attribute of the markup node, which is set during moving a control point. See for example how it is done in SlicerHeart.

Hi @lassoan ,
Thanks for your answer. Finally, it seems that there was an error with the code which computes the intersection point between my three slices, and that’s why the markup was trapped in the Z axis…
FYI, I took this code here SlicerHeart/ValveView.py at master · SlicerHeart/SlicerHeart · GitHub
It seems that the extracted normal aren’t correct.

Since the slice rotation feature is now built into Slicer core and for defining the annulus curve we use a more comprehensive module, we don’t use this module or fix errors that occur for special cases.

We made the more robust (see here) by making sure that only currently visible slices in the same view group are taken into account and slices that are nearly parallel are excluded from the computation (as the intersection line can be computed mathematically for nearly-parallel planes but the result is a random line position/orientation).

1 Like