Craniosynostosis surgery planning

Hi,

I’m trying to do craniosynostosis surgery planning in Slicer. Basically I need to accurately define two intersecting planes by fiducials and then separate a piece of the skull like on the first image -->
So far I have not managed to figure out how to do it in a manner that allows easily modifying the cut planes.
I have tried this python script --> https://www.slicer.org/wiki/Documentation/Nightly/ScriptRepository#Set_slice_position_and_orientation_from_3_markup_fiducials
But I have not figured out how to use it for defining two planes. It would be perfect if I could define two intersecting surfaces with 4 fiducials.
Also, the Angle Planes module seems to almost do just what I need, but I can’t use the planes it generates to cut the model.

The last time I did it in Meshmixer. Not much fun, but the cut planes are easy to manipulate at least.


Do you have any ideas on how to do it Slicer?

Best Regards,
Martin

1 Like

Maybe Easy clip extension can fulfill all your requirements.

If you prefer to position planes using markup fiducials then the script needs only a small modification to place 2 planes using 4 fiducials:

# Update plane from fiducial points
def UpdateSlicePlane(param1=None, param2=None):
  # Get point positions as numpy array
  import numpy as np
  nOfFiduciallPoints = markups.GetNumberOfFiducials()
  if nOfFiduciallPoints < 3:
    return  # not enough points
  points = np.zeros([3,nOfFiduciallPoints])
  for i in range(0, nOfFiduciallPoints):
    markups.GetNthFiducialPosition(i, points[:,i])
  # Compute plane1 position and normal
  planePosition = points[:,0]
  planeX = points[:,1] - points[:,0]
  planeNormal1 = np.cross(points[:,1] - points[:,0], points[:,2] - points[:,0])
  sliceNode1.SetSliceToRASByNTP(planeNormal1[0], planeNormal1[1], planeNormal1[2],
    planeX[0], planeX[1], planeX[2],
    planePosition[0], planePosition[1], planePosition[2], 0)
  if nOfFiduciallPoints>3:
    planeNormal2 = np.cross(points[:,1] - points[:,0], points[:,3] - points[:,0])
    sliceNode2.SetSliceToRASByNTP(planeNormal2[0], planeNormal2[1], planeNormal2[2],
        planeX[0], planeX[1], planeX[2],
        planePosition[0], planePosition[1], planePosition[2], 0)

# Get markup node from scene
sliceNode1 = slicer.app.layoutManager().sliceWidget('Red').mrmlSliceNode()
sliceNode2 = slicer.app.layoutManager().sliceWidget('Green').mrmlSliceNode()
markups = slicer.util.getNode('F')

# Update slice plane manually
UpdateSlicePlane()

# Update slice plane automatically whenever points are changed
markupObservation = [markups, markups.AddObserver(slicer.vtkMRMLMarkupsNode.PointModifiedEvent, UpdateSlicePlane, 2)]

If you cut solid objects then you can use Segment editor module’s Scissors effect. Scissors effect has the option to restrict the cut to one side of the current slice. You can also use Scissors effect to separate segments along arbitrarily drawn lines, not just planes.

1 Like

Andras,

Thank you for the suggestions and the modification to the script. The 4 fiducials for 2 planes work perfectly. The issue with Easy Clip is that it’s quite difficult to exactly position the planes in relation to features of the skull. For me it is easiest if the edges of the planes pass through the points I have defined.

Best Regards,
Martin

1 Like

Do you know if its possible to export the result of Clipping Planes feature under the Models module?
This is exactly what I would need as output.

I noticed that the Easy Clip planes and the planes generated by the Python script can go out of sync. Is it possible to resynchronise them?

Best Regards,
Martin