Display VTK Wedge in Slicer as Segmentation

I’m trying to split a segment based on its rotational position (e.g. only getting a 15 deg wedge of the segmentation). I’m thinking the way to do this is to create a vtkWedge shape and take its intersection with the existing segmentation.

I’m creating a vtkWedge right now but I’m looking for something like “GetOutput()” that exists for a vtkSphere (example), so that I can assign my wedge shape to a segmentation node. Any suggestions? Here’s my existing code to create a wedge:

#Create Wedge Shape
wedge = vtk.vtkWedge()
wedge.GetPoints().SetPoint(0,0,0,0)
wedge.GetPoints().SetPoint(1,0,1,1)
wedge.GetPoints().SetPoint(2,0,1,1)
wedge.GetPoints().SetPoint(3,1,0,0)
wedge.GetPoints().SetPoint(4,1,0,1)
wedge.GetPoints().SetPoint(5,1,1,1)

#Create segmentation node from Wedge - can't figure this out

Thanks in advance!

vtkWedge is just a cell. You need to create a vtkPolyData, add points to it, then create a vtkWedge cell, add the point IDs to it, and then add the cell to the polydata. You can check out VTK examples for details, for example this example that adds a triangle cell.

You can create a segment from polydata using AddSegmentFromClosedSurfaceRepresentation as shown in this example in the script repository.

Hi Andras, thanks - that was very helpful - I’m close but I can’t get my wedge to work out - it seems like the vtkPolyData isn’t getting the correct faces, so from my 6 points defining the wedge, I get faces/triangles (0,1,2), (0,2,3), (0,3,4), (0,4,5) rather than my wedge shape.
image

Here’s my code:

modelNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLModelNode")

# Create segmentation
segmentationNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")
segmentationNode.CreateDefaultDisplayNodes() # only needed for display

wedge = vtk.vtkWedge()
points = vtk.vtkPoints()

pt0 = np.array([0,0,0])
dx = np.array([1,0,0])
dx = np.array([0,1,0])
dx = np.array([0,0,1])

#define 6 coordinates for wedge
pts = [pt0, pt0 + dx + dy, pt0 + dx, pt0 + dz, pt0 + dx + dy + dz, pt0 + dx + dz]

for i in range(6):
  points.InsertNextPoint(pts[i])
  #slicer.modules.markups.logic().AddControlPoint(pts[i][0],pts[i][1],pts[i][2])

for i in range(6):
  wedge.GetPointIds().SetId(i,i)

wedges = vtk.vtkCellArray()
wedges.InsertNextCell(wedge)

wedgePD = vtk.vtkPolyData()
wedgePD.SetPoints(points)
wedgePD.SetPolys(wedges)
modelNode.SetAndObservePolyData(wedgePD)

# Import the model into the segmentation node
slicer.modules.segmentations.logic().ImportModelToSegmentationNode(wedgeMN, segmentationNode)

I’ve also tried to manually define the faces without any impact:

faces = [5,  # number of faces
             3, 0, 1, 2,  # number of ids on face, ids
             3, 3, 5, 4,
             4, 1, 4, 5, 2,
             4, 0, 2, 5, 3,
             4, 1, 0, 3, 4]

wedge.SetFaces(faces)
wedge.Initialize()

Thanks for the help!

Wedge is a volumetric cell, so it may need to be placed in a vtkUnstructuredGrid. However, I’m not sure if unstructured grid can be imported into a segmentation.

Overall, it may be simpler to create a wedge out of triangle cells and add them to a vtkPolyData.

Took your approach and just made wedge of triangles and it works great. Thank you!

1 Like