pyvista / pyvista-support

[moved] Please head over to the Discussions tab of the PyVista repository
https://github.com/pyvista/pyvista/discussions
59 stars 4 forks source link

Extracting mesh boundary as ordered polyline #499

Closed danwbean closed 2 years ago

danwbean commented 3 years ago

Hello,

I want to export a boundary polyline of a mesh as an ordered set of vertices in numpy. I get the vertices, but they are unordered when exported to numpy. How do I preserve vertex order?

The task is to extract the yellow bi-facial edge of a stone projectile point as a 3D polyline.

ppt

The mesh is a watertight triangular mesh loaded from a ply file.

Code:

mesh = pv.read(full_ply_fn)

top_ids = np.arange(mesh.n_cells)[mesh['Normals'][:,2] > 0.0] # select upward normals top = mesh.extract_cells(top_ids) # upper half

boundary = top.extract_feature_edges(boundary_edges=True, feature_edges=False, non_manifold_edges=False, manifold_edges=False) # find bifacial edge (as PolyData)

boundary.extract_largest(inplace=True)

vtk_pts = boundary.GetPoints() # this is vtkPoints object polyline_npy = numpy_support.vtk_to_numpy(vtk_pts.GetData())

This approach loses the ordering of the vertices of the polyline. Again, the goal is to extract the bi-facial edge as a closed polyline.

danwbean commented 3 years ago

Addition:

After reading Issue #169 I see that .strip filter has been added (vtkStripper).

So after boundary.extract_largest(inplace=True) I tried:

assert not boundary.lines.shape[0] % 3, 'cells must all be edges'

bf_poly = boundary.strip()

This worked and as long as you used the vertex sequence specified in bf.poly.lines, you come close, but with multiple segments.

extract_result

The resulting polyline (bf_poly) has two issues:

1) several small loops resulting in duplicated vertices (an artifact of edge faces on original mesh being near vertical) 2) after eliminating the small loops, there were three segments, sharing endpoints, but some were flipped head-to-tail and the segments were not in the same order.

So the purple segment had to be reversed, hooked to the green, then hooked to the orange.

The result was a single loop polyline with ordered vertices.

Hope this helps someone else similarly stuck. Please close this issue. All is well.