Create curve from many input points

Hi, Andras
I have a numpy array that contains some points. I want to create a vtkMRMLMarkupsCurveNode. So, I call the function curveNode.AddControlPoint() to add every point coordinate. But that’s too slow. What’s the better way to do this?
Thank you.

for pointIndex in range(len(centerlinePoints)):
    centerlineCurveNode.AddControlPoint(vtk.vtkVector3d(centerlinePoints[pointIndex][0], centerlinePoints[pointIndex][1], centerlinePoints[pointIndex][2]))

How many control points are you trying to add?

You may speed up node updates if you call wasModify=centerlineCurveNode.StartModify() before starting to add points and call centerlineCurveNode.EndModify(wasModify) when you are done.

If you have hundreds or thousands of points then you can update them all at once using
SetControlPointPositionsWorld (if you have your inputs as a numpy array then you need to convert the array to vtkPoints object first).

If you have thousands of points then probably you also want to reduce number of interpolated points using SetNumberOfPointsPerInterpolatingSegment().

1 Like

Hundreds of control points.
I adopt your sencond solution: SetControlPointPositionsWorld, That’s run fast. Thank you Andras.
Some code:

points = vtk.vtkPoints()
vtkpointsData = vtk.util.numpy_support.numpy_to_vtk(centerlinePoints, deep=1)
points.SetNumberOfPoints(len(centerlinePoints))
points.SetData(vtkpointsData)
centerlineCurveNode.SetControlPointPositionsWorld(points)
2 Likes

Hello! When I input your code in the python interrupter , I get “name ‘centerlineCurveNode’ is not defined”. Can you tell me how to import centerlineCurveNode? Thank you in advance.

Replace centerlineCurveNode with your curve node. You can get a curve node from its name by calling:

centerlineCurveNode = getNode('NameOfMyCurveNode')
1 Like

Hello! I run the code above , but I didn’t see anything in 3Dslicer, how to show the curve? Thank you in advance!

Here is a complete example that works fine in recent Slicer versions:

# Create random numpy array to use as input
import numpy as np
pointPositions = np.random.uniform(-50,50,size=[15,3])

# Create curve from numpy array
curveNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsCurveNode")
slicer.util.updateMarkupsControlPointsFromArray(curveNode, pointPositions)

image

3 Likes

How would you then assign labels to the points? Would you iterate through each Nth point to add the label (via SetNthControlPointLabel)?

I have hundreds of points but also need to label each one.

Greydon