measure_curvature2.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import numpy as np
  2. from vedo import Mesh, Plotter, Points, Point, Arrows
  3. from vedo import dataurl, project_point_on_variety, progressbar
  4. #################################################################
  5. def onclick(event):
  6. if not event.object:
  7. return
  8. pid = event.object.closest_point(event.picked3d, return_point_id=True)
  9. ids = msh1.find_adjacent_vertices(pid, depth=depth, adjacency_list=adlist)
  10. print(f"Clicked point {pid} with {len(ids)} adjacent vertices", end='')
  11. print(f" -> curvatures: {curvs_g[pid]:.3f}, {curvs_m[pid]:.3f}")
  12. bpts = pts1[ids]
  13. _, res = project_point_on_variety(
  14. pts1[pid], bpts, degree=2, compute_surface=True, compute_curvature=True
  15. )
  16. vpts = Points(bpts, r=3).rename("onclick")
  17. vpt = Point(pts1[pid], c="green4").rename("onclick")
  18. res[0].color("green7").alpha(1).rename("onclick")
  19. plt.remove("onclick").add(vpts, vpt, res[0]).render()
  20. ################################################################
  21. msh1 = Mesh(dataurl + "270_flank.vtk").normalize()
  22. # msh1.subdivide()
  23. msh1.smooth()
  24. msh1.compute_normals()
  25. vrange = [-10, 10]
  26. depth = 5 # how many layers of adjacent vertices to consider
  27. # Compute adjacency list for the mesh vertices
  28. adlist = msh1.compute_adjacency()
  29. ################################################################
  30. # Compute curvature at all points by fitting a quadratic surface
  31. curvs_g = []
  32. curvs_m = []
  33. pts1 = msh1.points
  34. for i in progressbar(range(msh1.npoints)):
  35. ids = msh1.find_adjacent_vertices(i, depth=depth, adjacency_list=adlist)
  36. bpts = msh1.points[ids]
  37. _, res = project_point_on_variety(pts1[i], bpts, degree=2, compute_curvature=True)
  38. curvs_g.append(res[4])
  39. curvs_m.append(res[5])
  40. msh1.pointdata["Gauss_Curvature"] = curvs_g
  41. msh1.cmap("coolwarm", "Gauss_Curvature", vmin=vrange[0], vmax=vrange[1]).add_scalarbar()
  42. msh1.lighting("glossy")
  43. msh2 = msh1.clone()
  44. msh2.pointdata["Mean_Curvature"] = curvs_m
  45. msh2.cmap("Reds", "Mean_Curvature", vmin=0, vmax=3*vrange[1]).add_scalarbar()
  46. msh3 = msh1.clone().lighting("off").alpha(0.5)
  47. msh3.pointdata.select("Gauss_Curvature")
  48. isolines = msh3.isolines(n=10, vmin=vrange[0], vmax=vrange[1]).c("black")
  49. vgrad = msh3.gradient("Gauss_Curvature")
  50. vgrad /= np.linalg.norm(vgrad, axis=1)[:, np.newaxis] # normalize
  51. arrows = Arrows(msh3.points, msh3.points + vgrad / 40, c="black")
  52. plt = Plotter(N=3, axes=4, size=(2400, 800))
  53. plt.add_callback("mouse click", onclick)
  54. plt.at(0).show("Gaussian curvature\nCLICK on a point to see its curvature", msh1)
  55. plt.at(1).show("Mean curvature", msh2)
  56. plt.at(2).show("Gradient Vectors and Isolines", msh3, arrows, isolines)
  57. plt.interactive().close()