Visualize transform between moving and fixed points

Hello! I wanted a way to visualize the connections between ‘moving’ and ‘fixed’ points (vtkMRMLMarkupsFiducialNode) and wrote a script that created a vtkMRMLMarkupsLineNode for each connection, but this was very slow over hundreds of points. Then I wrote a script to draw the lines using vtkPolyData / vtkCellArray, and this is super fast to update, but Slicer crashes shortly after creating the mesh Node.

Here’s what my script looks like:

fixedPoints_node = slicer.util.getNode('fixed_landmarks')
movingPoints_node = slicer.util.getNode('moving_landmarks')
num_landmarks = fixedPoints_node.GetNumberOfControlPoints()
fixed_points = vtkPoints()
points = vtkPoints()
for i in range(num_landmarks):
    fixed_pos = [0, 0, 0]
    fixedPoints_node.GetNthControlPointPosition(i, fixed_pos)
    moving_pos = [0, 0, 0]
    movingPoints_node.GetNthControlPointPosition(i, moving_pos)
    points.InsertNextPoint(moving_pos)
    points.InsertNextPoint(fixed_pos)
# Build PolyData from Points
lines = vtk.vtkCellArray()
for i in range(200):
    line = vtk.vtkLine()
    line.GetPointIds().SetId(0, i*2)
    line.GetPointIds().SetId(1, i*2+1)
    lines.InsertNextCell(line)
polydata = vtk.vtkPolyData()
polydata.SetPoints(points)
polydata.SetLines(lines)
# Build Model from PolyData
modelNode = slicer.vtkMRMLModelNode()
modelNode.SetAndObservePolyData(polydata)
slicer.mrmlScene.AddNode(modelNode)

This will draw the lines correctly, but after you click anywhere in Slicer, the app will hang for a second, then crash silently. No information is available logs related to the crash. Using Slicer 5.3.0 (2023-02-17).
I have confirmed that the points stored in the markupNodes are all valid, all line segments have a non-zero length, all points within 60mm from origin.

I also notice that the docs for SetAndObservePolyData say “Deprecated: Use SetAndObserveMesh instead.
I tried this variation, which also successfully draws the correct mesh, but also crashes Slicer.

polydata = vtk.vtkPolyData()
polydata.SetPoints(points)
polydata.SetLines(lines)
mesh = vtk.vtkPolyData()
mesh.DeepCopy(polydata)
modelNode = slicer.vtkMRMLModelNode()
mesh = vtk.vtkPolyData()
mesh.DeepCopy(polydata)
modelNode.SetAndObserveMesh(mesh)
slicer.mrmlScene.AddNode(modelNode)

nevermind… this was user error :man_facepalming:

When setting the lines, I should have used
for i in range(num_landmarks):
instead of:
for i in range(200):

I was originally testing this with 200 random points, but only have 132 control points, so my vtkLine ends up with some invalid PointIDs. Correcting my script produces a good mesh without the crash.

2 Likes

This features is available in Transforms module. It is a bit hidden - in Display → Visualization → Advanced → set your fixed (“from”) points in Source points.

wrote a script that created a vtkMRMLMarkupsLineNode for each connection, but this was very slow over hundreds of points

When you add hundreds of markup nodes then the view may slow down because each line markup is interactive. If you don’t need interaction (you don’t need the control points to be clickable, you don’t want to drag the control points) then lock the markup and the rendering will be a magnitude faster.

2 Likes