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.