meshlib1.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import numpy as np
  2. import vedo
  3. from meshlib import mrmeshpy as mm
  4. from meshlib import mrmeshnumpy as mn
  5. ################################################################################
  6. # Example of mesh relaxation
  7. path = vedo.download(vedo.dataurl + "mouse_brain.stl")
  8. mesh = mm.loadMesh(path)
  9. relax_params = mm.MeshRelaxParams()
  10. relax_params.iterations = 5
  11. mm.relax(mesh, relax_params)
  12. props = mm.SubdivideSettings()
  13. props.maxDeviationAfterFlip = 0.5
  14. mm.subdivideMesh(mesh, props)
  15. plus_z = mm.Vector3f()
  16. plus_z.z = 1.0
  17. rotation_xf = mm.AffineXf3f.linear(mm.Matrix3f.rotation(plus_z, 3.1415 * 0.5))
  18. mesh.transform(rotation_xf)
  19. vedo.Mesh(mesh).show().close()
  20. ################################################################################
  21. # Simple triangulation
  22. u, v = np.mgrid[0 : 2 * np.pi : 100j, 0 : np.pi : 100j]
  23. x = np.cos(u) * np.sin(v)
  24. y = np.sin(u) * np.sin(v)
  25. z = np.cos(v)
  26. # Prepare for MeshLib PointCloud
  27. verts = np.stack((x.flatten(), y.flatten(), z.flatten()), axis=-1).reshape(-1, 3)
  28. # verts = vedo.Mesh(vedo.dataurl+"bunny.obj").subdivide(2).vertices
  29. # Create MeshLib PointCloud from np ndarray
  30. pc = mn.pointCloudFromPoints(verts)
  31. # Remove duplicate points
  32. pc.validPoints = mm.pointUniformSampling(pc, 0.1)
  33. pc.invalidateCaches()
  34. # Triangulate it
  35. triangulated_pc = mm.triangulatePointCloud(pc)
  36. # Fix possible issues
  37. triangulated_pc = mm.offsetMesh(triangulated_pc, 0.0)
  38. vedo.show(vedo.Points(pc), vedo.Mesh(triangulated_pc, alpha=0.4)).close()
  39. ################################################################################
  40. # Example of Boolean operation
  41. # create first sphere with radius of 1 unit
  42. sphere1 = mm.makeUVSphere(1.0, 64, 64)
  43. # create second sphere by cloning the first sphere and moving it in X direction
  44. sphere2 = mm.copyMesh(sphere1)
  45. xf = mm.AffineXf3f.translation(mm.Vector3f(0.7, 0.0, 0.0))
  46. sphere2.transform(xf)
  47. # perform boolean operation
  48. result = mm.boolean(sphere1, sphere2, mm.BooleanOperation.Intersection)
  49. if not result.valid():
  50. print(result.errorString)
  51. vedo.show(vedo.Mesh(result.mesh, alpha=0.4)).close()
  52. ################################################################################
  53. # Example of mesh offset
  54. mesh = mm.loadMesh(path)
  55. # Setup parameters
  56. params = mm.OffsetParameters()
  57. # offset grid precision (algorithm is voxel based)
  58. params.voxelSize = mesh.computeBoundingBox().diagonal() * 5e-3
  59. if mm.findRightBoundary(mesh.topology).empty():
  60. # use if you have holes in mesh
  61. params.signDetectionMode = mm.SignDetectionMode.HoleWindingRule
  62. # Make offset mesh
  63. offset = mesh.computeBoundingBox().diagonal() * 0.025
  64. result_mesh = mm.offsetMesh(mesh, offset, params)
  65. vedo.show(vedo.Mesh(result_mesh).lw(1)).close()
  66. ################################################################################
  67. # Example of fill holes
  68. path = vedo.download(vedo.dataurl + "bunny.obj")
  69. mesh = mm.loadMesh(path)
  70. # Find single edge for each hole in mesh
  71. hole_edges = mesh.topology.findHoleRepresentiveEdges()
  72. for e in hole_edges:
  73. # Setup filling parameters
  74. params = mm.FillHoleParams()
  75. params.metric = mm.getUniversalMetric(mesh)
  76. # Fill hole represented by `e`
  77. mm.fillHole(mesh, e, params)
  78. vedo.show(vedo.Mesh(mesh)).close()
  79. ################################################################################
  80. # Example of stitch holes
  81. mesh_a = vedo.Mesh(vedo.dataurl + "bunny.obj").cut_with_plane(
  82. origin=(+0.01, 0, 0), normal=(+1, 0, 0)
  83. )
  84. mesh_b = vedo.Mesh(vedo.dataurl + "bunny.obj").cut_with_plane(
  85. origin=(-0.01, 0, 0), normal=(-1, 0, 0)
  86. )
  87. mesh_a.write("meshAwithHole.stl")
  88. mesh_b.write("meshBwithHole.stl")
  89. mesh_a = mm.loadMesh("meshAwithHole.stl")
  90. mesh_b = mm.loadMesh("meshBwithHole.stl")
  91. # Unite meshes
  92. mesh = mm.mergeMeshes([mesh_a, mesh_b])
  93. # Find holes
  94. edges = mesh.topology.findHoleRepresentiveEdges()
  95. # Connect two holes
  96. params = mm.StitchHolesParams()
  97. params.metric = mm.getUniversalMetric(mesh)
  98. mm.buildCylinderBetweenTwoHoles(mesh, edges[0], edges[1], params)
  99. vedo.show(vedo.Mesh(mesh).lw(1)).close()