(WIKI)Compared to the Point Cloud geometry type, a Polygon Mesh is a collection of Vertices, Edges, Faces(triangles and quadrilaterals), Polygons and Surfaces
the study of Polygon Meshes is a large sub-field 3D Computer Graphics and Geometric Modeling
2. Read a 3D Mesh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
importopen3daso3dimportnumpyasnpknot_mesh=o3d.data.KnotMesh()mesh=o3d.io.read_triangle_mesh(knot_mesh.path)mesh.paint_uniform_color([0.5,0.1,0.3])print("Displaying mesh ...")print(mesh)# TriangleMesh with 1440 vertices and 2880 triangles.print("Try to render a mesh with normals (exist: "+str(mesh.has_vertex_normals())+") and colors (exist: "+str(mesh.has_vertex_colors())+")")# mesh.has_vertex_normals() = False# mesh.has_vertex_colors() = Falseo3d.visualization.draw([mesh])
Since the current mesh does not have normals for Vertices or Triangle faces. So uniform color shading is used instead of a more sophisticated Phong shading.
3. Surface Normal Estimation and Paint
Use mesh.compute_vertex_normals() and paint_uniform_color()
1
2
3
4
5
print("Computing normals and rendering it.")mesh.compute_vertex_normals()print(np.asarray(mesh.triangle_normals))mesh.paint_uniform_color([1,0.706,0])o3d.visualization.draw_geometries([mesh])
print('filter with average with 1 iteration')mesh_out=mesh_in.filter_smooth_simple(number_of_iterations=1)mesh_out.compute_vertex_normals()o3d.visualization.draw_geometries([mesh_out])
4.2. Laplacian Filter
1
2
3
4
print('filter with Laplacian with 50 iterations')mesh_out=mesh_in.filter_smooth_laplacian(number_of_iterations=50)mesh_out.compute_vertex_normals()o3d.visualization.draw_geometries([mesh_out])
4.3. Taubin Filter
The problem with the Average and Laplacian Filter is that they lead to a shrinkage of the triangle mesh.
[Taubin1995] showed that the application of two Laplacian filters with different $\lambda$ parameters can prevent the mesh shrinkage.
1
2
3
4
print('filter with Taubin with 100 iterations')mesh_out=mesh_in.filter_smooth_taubin(number_of_iterations=100)mesh_out.compute_vertex_normals()o3d.visualization.draw_geometries([mesh_out])
5. Sampling
The simplest method is sample_points_uniformly that uniformly samples points from the 3D surface based on the triangle area.
The parameter number_of_points defines how many points are sampled from the triangle surface.
1
2
3
print("Displaying pointcloud using uniform sampling ...")pcd=mesh.sample_points_uniformly(number_of_points=1000)o3d.visualization.draw_geometries([pcd])
Uniform sampling can yield clusters of points on the surface, while a method called Poisson disk sampling can evenly distribute the points on the surface.
1
2
3
4
print("Displaying pointcloud using Poisson disk sampling ...")pcd=mesh.sample_points_poisson_disk(number_of_points=1000,init_factor=5)o3d.visualization.draw_geometries([pcd])
6. Mesh Simplification
Mesh Simplification methods are used to represent a high-resolution mesh with fewer triangles and vertices, but the low-resolution mesh should still be close to the high-resolution mesh.
6.1. Vertex Clustering
This method pools all vertices that fall into a voxel of a given size to a single vertex.
print(f'Input mesh has {len(mesh_in.vertices)} vertices and {len(mesh_in.triangles)} triangles')# Input mesh has 1440 vertices and 2880 triangleso3d.visualization.draw_geometries([mesh_in])voxel_size=max(mesh_in.get_max_bound()-mesh_in.get_min_bound())/32print(f'voxel_size = {voxel_size:e}')# voxel_size = 5.66mesh_smp=mesh_in.simplify_vertex_clustering(voxel_size=voxel_size,contraction=o3d.geometry.SimplificationContraction.Average)print(f'Simplified mesh has {len(mesh_smp.vertices)} vertices and {len(mesh_smp.triangles)} triangles')# Simplified mesh has 1355 vertices and 2720 triangleso3d.visualization.draw_geometries([mesh_smp])voxel_size=max(mesh_in.get_max_bound()-mesh_in.get_min_bound())/16print(f'voxel_size = {voxel_size:e}')# voxel_size = 11.332mesh_smp=mesh_in.simplify_vertex_clustering(voxel_size=voxel_size,contraction=o3d.geometry.SimplificationContraction.Average)print(f'Simplified mesh has {len(mesh_smp.vertices)} vertices and {len(mesh_smp.triangles)} triangles')# Simplified mesh has 860 vertices and 1773 triangleso3d.visualization.draw_geometries([mesh_smp])
6.2. Mesh Decimation
Open3D implements simplify_quadric_decimation that minimizes error quadrics (distances to neighboring planes).
1
2
3
4
5
6
7
8
9
10
11
12
13
mesh_smp=mesh_in.simplify_quadric_decimation(target_number_of_triangles=6500)print(f'Simplified mesh has {len(mesh_smp.vertices)} vertices and {len(mesh_smp.triangles)} triangles')# Simplified mesh has 1440 vertices and 2880 triangleso3d.visualization.draw_geometries([mesh_smp])mesh_smp=mesh_in.simplify_quadric_decimation(target_number_of_triangles=1700)print(f'Simplified mesh has {len(mesh_smp.vertices)} vertices and {len(mesh_smp.triangles)} triangles')# Simplified mesh has 850 vertices and 1700 triangleso3d.visualization.draw_geometries([mesh_smp])