# How can I split a polyline into its linear segments?

**URL:** https://discourse.vtk.org/t/how-can-i-split-a-polyline-into-its-linear-segments/2434
**Category:** Support
**Created:** [January 15, 2020, 5:47pm UTC](https://discourse.vtk.org/t/how-can-i-split-a-polyline-into-its-linear-segments/2434 "2020-01-15T17:47:27Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![normanius](https://discourse.vtk.org/user_avatar/discourse.vtk.org/normanius/32/611_2.png) [@normanius](https://discourse.vtk.org/u/normanius)
#### Post date: [January 15, 2020, 5:47pm UTC](https://discourse.vtk.org/t/how-can-i-split-a-polyline-into-its-linear-segments/2434/1 "2020-01-15T17:47:27Z")

</div>

A simple question that hopefully can be answered with a single link:

How to split a polyline into its `n` linear segments?

Let’s be given a polyline like the one that results from the [PolyLine example](https://lorensen.github.io/VTKExamples/site/Cxx/GeometricObjects/PolyLine/). Is there a vtk filter producing a `vtkPolyData` object with `n` lines from this input? It’s sort of the inverse filter of [`vtkStripper`](https://vtk.org/doc/nightly/html/classvtkStripper.html) that is able to join multiple line segments into a single polyline.

Thanks!

---

<div class="post-metadata">

### Author: ![normanius](https://discourse.vtk.org/user_avatar/discourse.vtk.org/normanius/32/611_2.png) [@normanius](https://discourse.vtk.org/u/normanius)
#### Post date: [January 17, 2020, 1:20am UTC](https://discourse.vtk.org/t/how-can-i-split-a-polyline-into-its-linear-segments/2434/2 "2020-01-17T01:20:25Z")

</div>

Here’s what I came up with, though I’m pretty convinced that there’re better approaches:

```
def polylineToMultiline(polyline):
    # Assumption: points appear in the correct order: p0->p1->p2->p3...
    points = polyline.GetPoints()
    nPoints = points.GetNumberOfPoints()
    cells = vtk.vtkCellArray()
    for i in range(nPoints-1):
        line = vtk.vtkLine()
        line.GetPointIds().SetId(0,i)
        line.GetPointIds().SetId(1,i+1)
        cells.InsertNextCell(line)
    poly = vtk.vtkPolyData()
    poly.SetPoints(points)
    poly.SetLines(cells)
    return poly

```

The above code assumes that the points from the polyline appear in the correct order. Note that this is not the case in general! To extract the points in the correct order, you would have to do something like the following:

```
def extractConsecutivePoints(poly):
    # Travers the line(s) and add points while keeping their order.
    cells = poly.GetLines()
    cells.InitTraversal()
    idList = vtk.vtkIdList()
    points = vtk.vtkPoints()
    while cells.GetNextCell(idList):
        for i in range(0, idList.GetNumberOfIds()):
            pId = idList.GetId(i)
            points.InsertNextPoint(poly.GetPoint(pId))
    return points
```

---

<div class="post-metadata">

### Author: ![banesullivan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/banesullivan/32/7143_2.png) [@banesullivan](https://discourse.vtk.org/u/banesullivan)
#### Post date: [January 18, 2020, 12:42am UTC](https://discourse.vtk.org/t/how-can-i-split-a-polyline-into-its-linear-segments/2434/3 "2020-01-18T00:42:25Z")

</div>

Here is a routine to do it with [PyVista](https://docs.pyvista.org) since you are using Python. This will work regardless of point ordering.

```auto
import pyvista as pv
import numpy as np

def segment_poly_cells(mesh):
    """`mesh` is a PyVista PolyData object 
    (wrapped vtkPolyData)
    """
    if not pv.is_pyvista_dataset(mesh):
        mesh = pv.wrap(mesh)
    polylines = []
    i, offset = 0, 0
    cc = mesh.lines # fetch up front
    while i < mesh.n_cells:
        nn = cc[offset]
        polylines.append(cc[offset+1:offset+1+nn])
        offset += nn + 1
        i += 1
    #
    lines = []
    for poly in polylines:
        lines.append(np.column_stack((poly[:-1], poly[1:])))
    lines = np.vstack(lines)
    cells = np.column_stack((np.full(len(lines), 2), lines))

    segmented = pv.PolyData()
    segmented.points = mesh.points
    segmented.lines = cells
    return segmented

```

So if you have some `vtkPolyData` already, just do the folling and a new `vtkPolyData` mesh will be returned.

```auto
segmented = segment_poly_cells(polyline)

```

---

<div class="post-metadata">

### Author: ![normanius](https://discourse.vtk.org/user_avatar/discourse.vtk.org/normanius/32/611_2.png) [@normanius](https://discourse.vtk.org/u/normanius)
#### Post date: [January 18, 2020, 2:48am UTC](https://discourse.vtk.org/t/how-can-i-split-a-polyline-into-its-linear-segments/2434/4 "2020-01-18T02:48:41Z")

</div>

PyVista is nice, thanks!

What exactly does `mesh.lines` represent? A container of cells/points that belong to a line?

```
mesh.lines = [n0, c00, c01, ..., n1, c10, c11, ...]
```

---

<div class="post-metadata">

### Author: ![banesullivan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/banesullivan/32/7143_2.png) [@banesullivan](https://discourse.vtk.org/u/banesullivan)
#### Post date: [January 18, 2020, 6:30am UTC](https://discourse.vtk.org/t/how-can-i-split-a-polyline-into-its-linear-segments/2434/5 "2020-01-18T06:30:55Z")

</div>

The `lines` property on `pyvista.PolyData` objects is just a NumPy wrapper around [`vtk.vtkPolyData.GetLines().GetData()`](https://vtk.org/doc/nightly/html/classvtkPolyData.html#ae0074614e7a9e3a52dc2c8c7505659f3) and it is exactly what you have listed above. As a way to get all of the point IDs for each line in the mesh

```auto
[n0, c00, c01, ..., n1, c10, c11, ...]

```

---

<div class="post-metadata">

### Author: ![normanius](https://discourse.vtk.org/user_avatar/discourse.vtk.org/normanius/32/611_2.png) [@normanius](https://discourse.vtk.org/u/normanius)
#### Post date: [January 19, 2020, 11:32pm UTC](https://discourse.vtk.org/t/how-can-i-split-a-polyline-into-its-linear-segments/2434/6 "2020-01-19T23:32:39Z")

</div>

Here’s the best answer to this question. Just use a triangle filter:

```
def polylineToMultiline(source):
    triangles = vtk.vtkTriangleFilter()
    triangles.SetInputData(source)
    triangles.Update()
    return ensurePolyData(triangles)

```

The documentation of [vtkTriangleFilter](https://vtk.org/doc/nightly/html/classvtkTriangleFilter.html#details) states:

> … [vtkTriangleFilter] also generates line segments from polylines unless PassLines is off, and generates individual vertex cells from [vtkVertex](https://vtk.org/doc/nightly/html/classvtkVertex.html) point lists unless PassVerts is off.

The remaining question: vtkTriangleFilter to apply an operation on a polyline, what the hack?! It’s sometimes so difficult to find the right method in vtk. 😕 😪

---

<div class="post-metadata">

### Author: ![banesullivan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/banesullivan/32/7143_2.png) [@banesullivan](https://discourse.vtk.org/u/banesullivan)
#### Post date: [January 20, 2020, 8:12pm UTC](https://discourse.vtk.org/t/how-can-i-split-a-polyline-into-its-linear-segments/2434/7 "2020-01-20T20:12:51Z")

</div>

Huh! I didn’t realize that, good find!

FYI: PyVista has direct access to that filter:

```auto
import pyvista as pv
from pyvista import examples

# Example mesh with a single PolyLine cell
polyline = examples.load_spline()
# use vtk.vtkTriangleFilter to create lines
lines = polyline.triangulate()

```
