marcomusy / vedo

A python module for scientific analysis of 3D data based on VTK and Numpy
https://vedo.embl.es
MIT License
2.04k stars 265 forks source link

Round or smooth the boundary edges #938

Open 1939938853 opened 1 year ago

1939938853 commented 1 year ago

Hello,

Just wonder if it is possible that vedo can round or smooth the boundary edges like this and how.

Thank you!

image

marcomusy commented 1 year ago

Hi have you tried already with smooth()and smooth_mls_2d() ? Check out https://github.com/marcomusy/vedo/blob/master/examples/advanced/moving_least_squares2D.py https://github.com/marcomusy/vedo/blob/master/examples/advanced/mesh_smoother2.py

JeffreyWardman commented 1 year ago

I have a similar issue. Here are the boundaries of my object. image (ignore the line down the middle)

Neither smooth(boundary=True) nor smooth_mls_2d(f=1) seem to work. I will DM the STL file of the boundary mesh (both flattened to XY plane and with varying Z-axis values). Maybe contour offsetting by eroding N times and dilating M times might work?

marcomusy commented 1 year ago

Hi - for some reasons I could not download correctly your STL files from the direct message you sent (they show empty?) I will try again later maybe I've messed up something.. smooth(boundary=True) will not work for lines, it needs a mesh.. so either you triangulate() the contour first, then you can use smooth(), or one other possibility is to use https://vedo.embl.es/docs/vedo/pointcloud.html#Points.smooth_mls_1d

JeffreyWardman commented 1 year ago

My bad. I thought I checked the files locally beforehand. I came into two issues along the way:

  1. It turns out you can't save vedo.Lines meshes as STLs.
  2. It also doesn't error out or return any information if you chose an incorrect file type. e.g. by mesh.write("test.json").
  3. It isn't clear if boundaries creates a vedo.Mesh or vedo.Lines. It looks like a vedo.Mesh but I can't see how to create the lines if initializing a new vedo.Mesh object. I could only find how to create it with vedo.Lines but using border.triangulate() ends up filling in the gap in the U rather than the line creating the U itself. In my actual mesh, border.triangulate() fills in

I've shared a NPZ file with the points and lines as pts and lines respectively.

npzfile = np.load("flat_border_noisy.npz")
pts = npzfile["pts"]
lines = npzfile["lines"]

pts1, pts2 = np.split(np.array(lines), indices_or_sections=2, axis=1)
pts1 = [pts[i] for i in pts1.squeeze()]
pts2 = [pts[i] for i in pts2.squeeze()]
recreated_border = vedo.Lines(pts1, pts2)

mesh triangulation image

vedo lines triangulation in recreation image

JeffreyWardman commented 1 year ago

smooth_mls_1d with radius helped for my use case :+1:

marcomusy commented 1 year ago

I should definitely set an error message about the format, thanks for pointing that out.

You should be able to save them as vtk files, that preserve lines.

Also consider methods .join() and .join_semgments()

JeffreyWardman commented 6 months ago

@marcomusy is it possible to add functionality to smooth just a section of the mesh (e.g. the boundary) via e.g. point ids?

JeffreyWardman commented 6 months ago

I could potentially do the below, however this results in a weird output. Another way to solve this would be to allow only cutting via the smoothing only if it goes inside the mesh, or to create additional faces for when it goes out of the mesh.

mesh_smoothed = mesh.copy().smooth(boundary=True, edge_angle=60)
m = mesh.copy()
boundaries_smoothed = mesh_smoothed.boundaries()
m.copy().cut_with_cookiecutter(boundaries_smoothed).show().close()

If there was a way to fill the two dips in this image and cut the peak that exceeds the line would be ideal.

image

Note that in this situation, cut_with_cookiecutter goes haywire as it doesn't seem to know what's internal and external.

Output (dark gray are the remaining faces, light gray are also in the original mesh):

image

marcomusy commented 6 months ago

Uhm i'm not sure this is possible.. but add_ids() should be able to keep track of vertices identities...

what in definitely not possible is to just smooth only a region of a mesh.

JeffreyWardman commented 6 months ago

What about the cookiecutter approach? It seems to fail when taking the smoothed boundary because of going in and out of the original boundary?