How to show a polyline with arbitrary width and nice joins between the nodes?

Hi

Have a look at the sample below. I’ve got a polyline and want to show that line with an arbitrary width.

In the sample, I essentially follow this example to achieve this, for a polyline that I extracted with vtkFeatureEdges. It appears that the line is drawn using quads per line-segment, however the result doesn’t look satisfactory.

Is it possible to create a polyline with nice joins? I found the ribbon filter, but it requires me to set a normal. Instead, I would rather like to see a tube that goes along that line.

I could possibly use vmtkcenterlinemodeller, but wondered if there is a pure VTK option. I need this just for visualization.

Thanks


Update: I found vtkTubeFilter that does the job much better. But still, it lacks the possibility to create nice joins.

def polylineToTube(edges, radius, resolution=10):
    tube = vtk.vtkTubeFilter()
    tube.SetInputData(edges)
    tube.SetRadius(radius)
    tube.SetNumberOfSides(resolution)
    tube.SidesShareVerticesOff()
    tube.Update()
    return tube


Update 2: If really desperate, one could use implicit functions to compute the tube. It’s super slow, but it works :slight_smile:

def polylineToTube(edges, radius, resolution=10, sampling=400):
    modeller = vtk.vtkImplicitModeller()
    modeller.SetSampleDimensions(sampling, sampling, sampling)
    modeller.SetInputData(edges)
    contours = vtk.vtkContourFilter()
    contours.SetInputConnection(modeller.GetOutputPort())
    contours.SetValue(0, radius) # generate iso-surface at radius
    contours.Update()
    return contours

1 Like

Okay. I finally figured out what was wrong. :man_facepalming:

vtkTubeFilter is perfectly able to join the segments. But the issue was with vtkFeatureEdges, which was returning a multi-line (that is a vtkPolyData containing multiple line-segments, instead of one single polyline. Flattening this polyline fixed the problem for me.

This is how I did it:

    edges = vtk.vtkFeatureEdges()
    edges.SetInputData(source)
    edges.BoundaryEdgesOn()
    edges.ManifoldEdgesOff()
    edges.NonManifoldEdgesOff()
    edges.FeatureEdgesOff()
    edges.Update()

    stripped = vtk.vtkStripper()
    stripped.SetInputData(edges.GetOutput())
    stripped.Update()

    tube = vtk.vtkTubeFilter()
    tube.SetInputData(stripped.GetOutput())
    tube.SetRadius(radius)
    tube.SetNumberOfSides(resolution)
    tube.Update()

2 Likes

Hi, what is the input of edge? Could you repost the link for the example because the original one is down.

Thanks!

What do you mean by “What is the input of edge”?

The LineWidth example is now here.

Hi, thanks a lot for your reply! I mean the input parameter for the function polylineToTube . Is radius just a list of float number? But what is the edges ?

Hi Padix

edges is a vtkPolyData object representing a line. As I wrote in the OP, I extracted edges with vtkFeatureEdges. See here for an example.

Yes, radius is a float representing the radius of the line to “draw”.

HTH