# Mesh¶

Open3D has a data structure for triangle mesh.

  5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 # examples/Python/Basic/mesh.py import copy import numpy as np from open3d import * if __name__ == "__main__": print("Testing mesh in open3d ...") mesh = read_triangle_mesh("../../TestData/knot.ply") print(mesh) print(np.asarray(mesh.vertices)) print(np.asarray(mesh.triangles)) print("") print("Try to render a mesh with normals (exist: " + str(mesh.has_vertex_normals()) + ") and colors (exist: " + str(mesh.has_vertex_colors()) + ")") draw_geometries([mesh]) print("A mesh with no normals and no colors does not seem good.") print("Computing normal and rendering it.") mesh.compute_vertex_normals() print(np.asarray(mesh.triangle_normals)) draw_geometries([mesh]) print("We make a partial mesh of only the first half triangles.") mesh1 = copy.deepcopy(mesh) mesh1.triangles = Vector3iVector( np.asarray(mesh1.triangles)[:len(mesh1.triangles)//2, :]) mesh1.triangle_normals = Vector3dVector( np.asarray(mesh1.triangle_normals) [:len(mesh1.triangle_normals)//2, :]) print(mesh1.triangles) draw_geometries([mesh1]) print("Painting the mesh") mesh1.paint_uniform_color([1, 0.706, 0]) draw_geometries([mesh1]) 

## Visualize 3D mesh¶

 20 21 22 23 24  print("Try to render a mesh with normals (exist: " + str(mesh.has_vertex_normals()) + ") and colors (exist: " + str(mesh.has_vertex_colors()) + ")") draw_geometries([mesh]) print("A mesh with no normals and no colors does not seem good.") 

The GUI visualizes a mesh.

You can rotate and move the mesh but it is painted with uniform gray color and does not look “3d”. The reason is that the current mesh does not have normals for vertices or faces. So uniform color shading is used instead of a more sophisticated Phong shading.

## Surface normal estimation¶

Let’s draw the mesh with surface normal.

 26 27 28 29  print("Computing normal and rendering it.") mesh.compute_vertex_normals() print(np.asarray(mesh.triangle_normals)) draw_geometries([mesh]) 

It uses compute_vertex_normals and paint_uniform_color which are member functions of mesh. Now it looks like:

## Crop mesh¶

We remove half of the surface by directly operate on the triangle and triangle_normals data fields of the mesh. This is done via numpy array.

 31 32 33 34 35 36 37 38 39  print("We make a partial mesh of only the first half triangles.") mesh1 = copy.deepcopy(mesh) mesh1.triangles = Vector3iVector( np.asarray(mesh1.triangles)[:len(mesh1.triangles)//2, :]) mesh1.triangle_normals = Vector3dVector( np.asarray(mesh1.triangle_normals) [:len(mesh1.triangle_normals)//2, :]) print(mesh1.triangles) draw_geometries([mesh1]) 

Outputs:

## Paint mesh¶

Painting mesh is the same as how it worked for point cloud.

 41 42 43  print("Painting the mesh") mesh1.paint_uniform_color([1, 0.706, 0]) draw_geometries([mesh1]) 

Outputs: