Triangle Mesh#

triangle_mesh_connected_components.py#

 1# ----------------------------------------------------------------------------
 2# -                        Open3D: www.open3d.org                            -
 3# ----------------------------------------------------------------------------
 4# Copyright (c) 2018-2024 www.open3d.org
 5# SPDX-License-Identifier: MIT
 6# ----------------------------------------------------------------------------
 7
 8import open3d as o3d
 9import numpy as np
10import copy
11
12if __name__ == "__main__":
13    bunny = o3d.data.BunnyMesh()
14    mesh = o3d.io.read_triangle_mesh(bunny.path)
15    mesh.compute_vertex_normals()
16
17    mesh = mesh.subdivide_midpoint(number_of_iterations=2)
18    vert = np.asarray(mesh.vertices)
19    min_vert, max_vert = vert.min(axis=0), vert.max(axis=0)
20    for _ in range(30):
21        cube = o3d.geometry.TriangleMesh.create_box()
22        cube.scale(0.005, center=cube.get_center())
23        cube.translate(
24            (
25                np.random.uniform(min_vert[0], max_vert[0]),
26                np.random.uniform(min_vert[1], max_vert[1]),
27                np.random.uniform(min_vert[2], max_vert[2]),
28            ),
29            relative=False,
30        )
31        mesh += cube
32    mesh.compute_vertex_normals()
33    print("Displaying input mesh ...")
34    o3d.visualization.draw([mesh])
35
36    print("Clustering connected triangles ...")
37    with o3d.utility.VerbosityContextManager(
38            o3d.utility.VerbosityLevel.Debug) as cm:
39        triangle_clusters, cluster_n_triangles, cluster_area = (
40            mesh.cluster_connected_triangles())
41    triangle_clusters = np.asarray(triangle_clusters)
42    cluster_n_triangles = np.asarray(cluster_n_triangles)
43    cluster_area = np.asarray(cluster_area)
44
45    print("Displaying mesh with small clusters removed ...")
46    mesh_0 = copy.deepcopy(mesh)
47    triangles_to_remove = cluster_n_triangles[triangle_clusters] < 100
48    mesh_0.remove_triangles_by_mask(triangles_to_remove)
49    o3d.visualization.draw([mesh_0])

triangle_mesh_cropping.py#

 1# ----------------------------------------------------------------------------
 2# -                        Open3D: www.open3d.org                            -
 3# ----------------------------------------------------------------------------
 4# Copyright (c) 2018-2024 www.open3d.org
 5# SPDX-License-Identifier: MIT
 6# ----------------------------------------------------------------------------
 7
 8import open3d as o3d
 9import numpy as np
10import copy
11
12if __name__ == "__main__":
13    knot_mesh = o3d.data.KnotMesh()
14    mesh = o3d.io.read_triangle_mesh(knot_mesh.path)
15    mesh.compute_vertex_normals()
16    print("Displaying original mesh ...")
17    o3d.visualization.draw([mesh])
18
19    print("Displaying mesh of only the first half triangles ...")
20    mesh_cropped = copy.deepcopy(mesh)
21    mesh_cropped.triangles = o3d.utility.Vector3iVector(
22        np.asarray(mesh_cropped.triangles)[:len(mesh_cropped.triangles) //
23                                           2, :])
24    mesh_cropped.triangle_normals = o3d.utility.Vector3dVector(
25        np.asarray(mesh_cropped.triangle_normals)
26        [:len(mesh_cropped.triangle_normals) // 2, :])
27    print(mesh_cropped.triangles)
28    o3d.visualization.draw([mesh_cropped])

triangle_mesh_deformation.py#

 1# ----------------------------------------------------------------------------
 2# -                        Open3D: www.open3d.org                            -
 3# ----------------------------------------------------------------------------
 4# Copyright (c) 2018-2024 www.open3d.org
 5# SPDX-License-Identifier: MIT
 6# ----------------------------------------------------------------------------
 7
 8import numpy as np
 9import open3d as o3d
10import time
11import os
12import sys
13
14pyexample_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
15sys.path.append(pyexample_path)
16
17import open3d_example as o3dex
18
19
20def problem0():
21    mesh = o3dex.get_plane_mesh(height=1, width=1)
22    mesh = mesh.subdivide_midpoint(3)
23    vertices = np.asarray(mesh.vertices)
24    static_ids = [
25        1, 46, 47, 48, 16, 51, 49, 50, 6, 31, 33, 32, 11, 26, 27, 25, 0, 64, 65,
26        20, 66, 68, 67, 7, 69, 71, 70, 22, 72, 74, 73, 3, 15, 44, 43, 45, 5, 41,
27        40, 42, 13, 39, 37, 38, 2, 56, 55, 19, 61, 60, 59, 8, 76, 75, 77, 23
28    ]
29    static_positions = []
30    for id in static_ids:
31        static_positions.append(vertices[id])
32    handle_ids = [4]
33    handle_positions = [vertices[4] + np.array((0, 0, 0.4))]
34
35    return mesh, static_ids + handle_ids, static_positions + handle_positions
36
37
38def problem1():
39    mesh = o3dex.get_plane_mesh(height=1, width=1)
40    mesh = mesh.subdivide_midpoint(3)
41    vertices = np.asarray(mesh.vertices)
42    static_ids = [
43        1, 46, 15, 43, 5, 40, 13, 38, 2, 56, 37, 39, 42, 41, 45, 44, 48, 47
44    ]
45    static_positions = []
46    for id in static_ids:
47        static_positions.append(vertices[id])
48    handle_ids = [21]
49    handle_positions = [vertices[21] + np.array((0, 0, 0.4))]
50
51    return mesh, static_ids + handle_ids, static_positions + handle_positions
52
53
54def problem2():
55    armadillo_data = o3d.data.ArmadilloMesh()
56    mesh = o3d.io.read_triangle_mesh(armadillo_data.path)
57    vertices = np.asarray(mesh.vertices)
58    static_ids = [idx for idx in np.where(vertices[:, 1] < -30)[0]]
59    static_positions = []
60    for id in static_ids:
61        static_positions.append(vertices[id])
62    handle_ids = [2490]
63    handle_positions = [vertices[2490] + np.array((-40, -40, -40))]
64
65    return mesh, static_ids + handle_ids, static_positions + handle_positions
66
67
68if __name__ == "__main__":
69    o3d.utility.set_verbosity_level(o3d.utility.Debug)
70
71    for mesh, constraint_ids, constraint_pos in [
72            problem0(), problem1(), problem2()
73    ]:
74        constraint_ids = np.array(constraint_ids, dtype=np.int32)
75        constraint_pos = o3d.utility.Vector3dVector(constraint_pos)
76        tic = time.time()
77        mesh_prime = mesh.deform_as_rigid_as_possible(
78            o3d.utility.IntVector(constraint_ids), constraint_pos, max_iter=50)
79        print("deform took {}[s]".format(time.time() - tic))
80        mesh_prime.compute_vertex_normals()
81
82        mesh.paint_uniform_color((1, 0, 0))
83        handles = o3d.geometry.PointCloud()
84        handles.points = constraint_pos
85        handles.paint_uniform_color((0, 1, 0))
86        o3d.visualization.draw_geometries([mesh, mesh_prime, handles])
87
88    o3d.utility.set_verbosity_level(o3d.utility.Info)

triangle_mesh_filtering_average.py#

 1# ----------------------------------------------------------------------------
 2# -                        Open3D: www.open3d.org                            -
 3# ----------------------------------------------------------------------------
 4# Copyright (c) 2018-2024 www.open3d.org
 5# SPDX-License-Identifier: MIT
 6# ----------------------------------------------------------------------------
 7
 8from numpy.random.mtrand import laplace
 9import open3d as o3d
10import numpy as np
11
12
13def average_filtering():
14    # Create noisy mesh.
15    knot_mesh = o3d.data.KnotMesh()
16    mesh_in = o3d.io.read_triangle_mesh(knot_mesh.path)
17    vertices = np.asarray(mesh_in.vertices)
18    noise = 5
19    vertices += np.random.uniform(0, noise, size=vertices.shape)
20    mesh_in.vertices = o3d.utility.Vector3dVector(vertices)
21    mesh_in.compute_vertex_normals()
22    print("Displaying input mesh ...")
23    o3d.visualization.draw_geometries([mesh_in])
24
25    print("Displaying output of average mesh filter after 1 iteration ...")
26    mesh_out = mesh_in.filter_smooth_simple(number_of_iterations=1)
27    mesh_out.compute_vertex_normals()
28    o3d.visualization.draw_geometries([mesh_out])
29
30    print("Displaying output of average mesh filter after 5 iteration ...")
31    mesh_out = mesh_in.filter_smooth_simple(number_of_iterations=5)
32    mesh_out.compute_vertex_normals()
33    o3d.visualization.draw_geometries([mesh_out])
34
35
36def laplace_filtering():
37    # Create noisy mesh.
38    knot_mesh = o3d.data.KnotMesh()
39    mesh_in = o3d.io.read_triangle_mesh(knot_mesh.path)
40    vertices = np.asarray(mesh_in.vertices)
41    noise = 5
42    vertices += np.random.uniform(0, noise, size=vertices.shape)
43    mesh_in.vertices = o3d.utility.Vector3dVector(vertices)
44    mesh_in.compute_vertex_normals()
45    print("Displaying input mesh ...")
46    o3d.visualization.draw_geometries([mesh_in])
47
48    print("Displaying output of Laplace mesh filter after 10 iteration ...")
49    mesh_out = mesh_in.filter_smooth_laplacian(number_of_iterations=10)
50    mesh_out.compute_vertex_normals()
51    o3d.visualization.draw_geometries([mesh_out])
52
53    print("Displaying output of Laplace mesh filter after 50 iteration ...")
54    mesh_out = mesh_in.filter_smooth_laplacian(number_of_iterations=50)
55    mesh_out.compute_vertex_normals()
56    o3d.visualization.draw_geometries([mesh_out])
57
58
59def taubin_filtering():
60    # Create noisy mesh.
61    knot_mesh = o3d.data.KnotMesh()
62    mesh_in = o3d.io.read_triangle_mesh(knot_mesh.path)
63    vertices = np.asarray(mesh_in.vertices)
64    noise = 5
65    vertices += np.random.uniform(0, noise, size=vertices.shape)
66    mesh_in.vertices = o3d.utility.Vector3dVector(vertices)
67    mesh_in.compute_vertex_normals()
68    print("Displaying input mesh ...")
69    o3d.visualization.draw_geometries([mesh_in])
70
71    print("Displaying output of Taubin mesh filter after 10 iteration ...")
72    mesh_out = mesh_in.filter_smooth_taubin(number_of_iterations=10)
73    mesh_out.compute_vertex_normals()
74    o3d.visualization.draw_geometries([mesh_out])
75
76    print("Displaying output of Taubin mesh filter after 100 iteration ...")
77    mesh_out = mesh_in.filter_smooth_taubin(number_of_iterations=100)
78    mesh_out.compute_vertex_normals()
79    o3d.visualization.draw_geometries([mesh_out])
80
81
82if __name__ == "__main__":
83    average_filtering()
84    laplace_filtering()
85    taubin_filtering()

triangle_mesh_from_point_cloud_alpha_shapes.py#

 1# ----------------------------------------------------------------------------
 2# -                        Open3D: www.open3d.org                            -
 3# ----------------------------------------------------------------------------
 4# Copyright (c) 2018-2024 www.open3d.org
 5# SPDX-License-Identifier: MIT
 6# ----------------------------------------------------------------------------
 7
 8import open3d as o3d
 9
10if __name__ == "__main__":
11    bunny = o3d.data.BunnyMesh()
12    mesh = o3d.io.read_triangle_mesh(bunny.path)
13    mesh.compute_vertex_normals()
14
15    pcd = mesh.sample_points_poisson_disk(750)
16    print("Displaying input pointcloud ...")
17    o3d.visualization.draw_geometries([pcd])
18    alpha = 0.03
19    print(f"alpha={alpha:.3f}")
20    print('Running alpha shapes surface reconstruction ...')
21    mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_alpha_shape(
22        pcd, alpha)
23    mesh.compute_triangle_normals(normalized=True)
24    print("Displaying reconstructed mesh ...")
25    o3d.visualization.draw_geometries([mesh], mesh_show_back_face=True)

triangle_mesh_from_point_cloud_ball_pivoting.py#

 1# ----------------------------------------------------------------------------
 2# -                        Open3D: www.open3d.org                            -
 3# ----------------------------------------------------------------------------
 4# Copyright (c) 2018-2024 www.open3d.org
 5# SPDX-License-Identifier: MIT
 6# ----------------------------------------------------------------------------
 7
 8import open3d as o3d
 9
10if __name__ == "__main__":
11    bunny = o3d.data.BunnyMesh()
12    gt_mesh = o3d.io.read_triangle_mesh(bunny.path)
13    gt_mesh.compute_vertex_normals()
14
15    pcd = gt_mesh.sample_points_poisson_disk(3000)
16    print("Displaying input pointcloud ...")
17    o3d.visualization.draw([pcd], point_size=5)
18
19    radii = [0.005, 0.01, 0.02, 0.04]
20    print('Running ball pivoting surface reconstruction ...')
21    rec_mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(
22        pcd, o3d.utility.DoubleVector(radii))
23    print("Displaying reconstructed mesh ...")
24    o3d.visualization.draw([rec_mesh])

triangle_mesh_from_point_cloud_poisson.py#

 1# ----------------------------------------------------------------------------
 2# -                        Open3D: www.open3d.org                            -
 3# ----------------------------------------------------------------------------
 4# Copyright (c) 2018-2024 www.open3d.org
 5# SPDX-License-Identifier: MIT
 6# ----------------------------------------------------------------------------
 7
 8import open3d as o3d
 9import numpy as np
10
11if __name__ == "__main__":
12    eagle = o3d.data.EaglePointCloud()
13    pcd = o3d.io.read_point_cloud(eagle.path)
14    R = pcd.get_rotation_matrix_from_xyz((np.pi, -np.pi / 4, 0))
15    pcd.rotate(R, center=(0, 0, 0))
16    print('Displaying input pointcloud ...')
17    o3d.visualization.draw([pcd])
18
19    print('Running Poisson surface reconstruction ...')
20    mesh, densities = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(
21        pcd, depth=9)
22    print('Displaying reconstructed mesh ...')
23    o3d.visualization.draw([mesh])

triangle_mesh_normal_estimation.py#

 1# ----------------------------------------------------------------------------
 2# -                        Open3D: www.open3d.org                            -
 3# ----------------------------------------------------------------------------
 4# Copyright (c) 2018-2024 www.open3d.org
 5# SPDX-License-Identifier: MIT
 6# ----------------------------------------------------------------------------
 7
 8import open3d as o3d
 9import numpy as np
10
11if __name__ == "__main__":
12    knot_mesh = o3d.data.KnotMesh()
13    mesh = o3d.io.read_triangle_mesh(knot_mesh.path)
14    print("Displaying mesh without normals ...")
15    # Invalidate existing normals.
16    mesh.triangle_normals = o3d.utility.Vector3dVector(np.zeros((1, 3)))
17    print("normals: \n", np.asarray(mesh.triangle_normals))
18    o3d.visualization.draw([mesh])
19
20    print("Computing normals and rendering it ...")
21    mesh.compute_vertex_normals()
22    print("normals: \n", np.asarray(mesh.triangle_normals))
23    o3d.visualization.draw([mesh])

triangle_mesh_properties.py#

 1# ----------------------------------------------------------------------------
 2# -                        Open3D: www.open3d.org                            -
 3# ----------------------------------------------------------------------------
 4# Copyright (c) 2018-2024 www.open3d.org
 5# SPDX-License-Identifier: MIT
 6# ----------------------------------------------------------------------------
 7
 8import open3d as o3d
 9import numpy as np
10import os
11import sys
12
13pyexample_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
14sys.path.append(pyexample_path)
15
16import open3d_example as o3dex
17
18
19def check_properties(name, mesh):
20    mesh.compute_vertex_normals()
21
22    edge_manifold = mesh.is_edge_manifold(allow_boundary_edges=True)
23    edge_manifold_boundary = mesh.is_edge_manifold(allow_boundary_edges=False)
24    vertex_manifold = mesh.is_vertex_manifold()
25    self_intersecting = mesh.is_self_intersecting()
26    watertight = mesh.is_watertight()
27    orientable = mesh.is_orientable()
28
29    print(name)
30    print(f"  edge_manifold:          {edge_manifold}")
31    print(f"  edge_manifold_boundary: {edge_manifold_boundary}")
32    print(f"  vertex_manifold:        {vertex_manifold}")
33    print(f"  self_intersecting:      {self_intersecting}")
34    print(f"  watertight:             {watertight}")
35    print(f"  orientable:             {orientable}")
36
37    geoms = [mesh]
38    if not edge_manifold:
39        edges = mesh.get_non_manifold_edges(allow_boundary_edges=True)
40        geoms.append(o3dex.edges_to_lineset(mesh, edges, (1, 0, 0)))
41    if not edge_manifold_boundary:
42        edges = mesh.get_non_manifold_edges(allow_boundary_edges=False)
43        geoms.append(o3dex.edges_to_lineset(mesh, edges, (0, 1, 0)))
44    if not vertex_manifold:
45        verts = np.asarray(mesh.get_non_manifold_vertices())
46        pcl = o3d.geometry.PointCloud(
47            points=o3d.utility.Vector3dVector(np.asarray(mesh.vertices)[verts]))
48        pcl.paint_uniform_color((0, 0, 1))
49        geoms.append(pcl)
50    if self_intersecting:
51        intersecting_triangles = np.asarray(
52            mesh.get_self_intersecting_triangles())
53        intersecting_triangles = intersecting_triangles[0:1]
54        intersecting_triangles = np.unique(intersecting_triangles)
55        print("  # visualize self-intersecting triangles")
56        triangles = np.asarray(mesh.triangles)[intersecting_triangles]
57        edges = [
58            np.vstack((triangles[:, i], triangles[:, j]))
59            for i, j in [(0, 1), (1, 2), (2, 0)]
60        ]
61        edges = np.hstack(edges).T
62        edges = o3d.utility.Vector2iVector(edges)
63        geoms.append(o3dex.edges_to_lineset(mesh, edges, (1, 0, 1)))
64    o3d.visualization.draw_geometries(geoms, mesh_show_back_face=True)
65
66
67if __name__ == "__main__":
68    knot_mesh = o3d.data.KnotMesh()
69    mesh = o3d.io.read_triangle_mesh(knot_mesh.path)
70    check_properties('KnotMesh', mesh)
71    check_properties('Mobius',
72                     o3d.geometry.TriangleMesh.create_mobius(twists=1))
73    check_properties("non-manifold edge", o3dex.get_non_manifold_edge_mesh())
74    check_properties("non-manifold vertex",
75                     o3dex.get_non_manifold_vertex_mesh())
76    check_properties("open box", o3dex.get_open_box_mesh())
77    check_properties("intersecting_boxes", o3dex.get_intersecting_boxes_mesh())

triangle_mesh_sampling.py#

 1# ----------------------------------------------------------------------------
 2# -                        Open3D: www.open3d.org                            -
 3# ----------------------------------------------------------------------------
 4# Copyright (c) 2018-2024 www.open3d.org
 5# SPDX-License-Identifier: MIT
 6# ----------------------------------------------------------------------------
 7
 8import open3d as o3d
 9
10if __name__ == "__main__":
11    bunny = o3d.data.BunnyMesh()
12    mesh = o3d.io.read_triangle_mesh(bunny.path)
13    mesh.compute_vertex_normals()
14
15    print("Displaying input mesh ...")
16    o3d.visualization.draw([mesh])
17
18    print("Displaying pointcloud using uniform sampling ...")
19    pcd = mesh.sample_points_uniformly(number_of_points=1000)
20    o3d.visualization.draw([pcd], point_size=5)
21
22    print("Displaying pointcloud using Poisson disk sampling ...")
23    pcd = mesh.sample_points_poisson_disk(number_of_points=1000, init_factor=5)
24    o3d.visualization.draw([pcd], point_size=5)

triangle_mesh_simplification_decimation.py#

 1# ----------------------------------------------------------------------------
 2# -                        Open3D: www.open3d.org                            -
 3# ----------------------------------------------------------------------------
 4# Copyright (c) 2018-2024 www.open3d.org
 5# SPDX-License-Identifier: MIT
 6# ----------------------------------------------------------------------------
 7
 8import open3d as o3d
 9
10if __name__ == "__main__":
11    bunny = o3d.data.BunnyMesh()
12    mesh_in = o3d.io.read_triangle_mesh(bunny.path)
13    mesh_in.compute_vertex_normals()
14
15    print("Before Simplification: ", mesh_in)
16    o3d.visualization.draw_geometries([mesh_in])
17
18    mesh_smp = mesh_in.simplify_quadric_decimation(
19        target_number_of_triangles=6500)
20    print("After Simplification target number of triangles = 6500:\n", mesh_smp)
21    o3d.visualization.draw_geometries([mesh_smp])
22
23    mesh_smp = mesh_in.simplify_quadric_decimation(
24        target_number_of_triangles=1700)
25    print("After Simplification target number of triangles = 1700:\n", mesh_smp)
26    o3d.visualization.draw_geometries([mesh_smp])

triangle_mesh_simplification_vertex_clustering.py#

 1# ----------------------------------------------------------------------------
 2# -                        Open3D: www.open3d.org                            -
 3# ----------------------------------------------------------------------------
 4# Copyright (c) 2018-2024 www.open3d.org
 5# SPDX-License-Identifier: MIT
 6# ----------------------------------------------------------------------------
 7
 8import open3d as o3d
 9
10if __name__ == "__main__":
11    bunny = o3d.data.BunnyMesh()
12    mesh_in = o3d.io.read_triangle_mesh(bunny.path)
13    mesh_in.compute_vertex_normals()
14
15    print("Before Simplification: ", mesh_in)
16    o3d.visualization.draw_geometries([mesh_in])
17
18    voxel_size = max(mesh_in.get_max_bound() - mesh_in.get_min_bound()) / 32
19    mesh_smp = mesh_in.simplify_vertex_clustering(
20        voxel_size=voxel_size,
21        contraction=o3d.geometry.SimplificationContraction.Average)
22    print("After Simplification with voxel size =", voxel_size, ":\n", mesh_smp)
23    o3d.visualization.draw_geometries([mesh_smp])
24
25    voxel_size = max(mesh_in.get_max_bound() - mesh_in.get_min_bound()) / 16
26    mesh_smp = mesh_in.simplify_vertex_clustering(
27        voxel_size=voxel_size,
28        contraction=o3d.geometry.SimplificationContraction.Average)
29    print("After Simplification with voxel size =", voxel_size, ":\n", mesh_smp)
30    o3d.visualization.draw_geometries([mesh_smp])

triangle_mesh_subdivision.py#

 1# ----------------------------------------------------------------------------
 2# -                        Open3D: www.open3d.org                            -
 3# ----------------------------------------------------------------------------
 4# Copyright (c) 2018-2024 www.open3d.org
 5# SPDX-License-Identifier: MIT
 6# ----------------------------------------------------------------------------
 7
 8import open3d as o3d
 9
10if __name__ == "__main__":
11    knot_mesh = o3d.data.KnotMesh()
12    mesh = o3d.io.read_triangle_mesh(knot_mesh.path)
13    mesh.compute_vertex_normals()
14    print("Before Subdivision: ", mesh)
15    print("Displaying input mesh ...")
16    o3d.visualization.draw_geometries([mesh], mesh_show_wireframe=True)
17    mesh = mesh.subdivide_loop(number_of_iterations=1)
18    print("After Subdivision: ", mesh)
19    print("Displaying subdivided mesh ...")
20    o3d.visualization.draw_geometries([mesh], mesh_show_wireframe=True)

triangle_mesh_transformation.py#

 1# ----------------------------------------------------------------------------
 2# -                        Open3D: www.open3d.org                            -
 3# ----------------------------------------------------------------------------
 4# Copyright (c) 2018-2024 www.open3d.org
 5# SPDX-License-Identifier: MIT
 6# ----------------------------------------------------------------------------
 7
 8import open3d as o3d
 9import numpy as np
10import copy
11
12
13def translate():
14    mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()
15    mesh_tx = copy.deepcopy(mesh).translate((1.3, 0, 0))
16    mesh_ty = copy.deepcopy(mesh).translate((0, 1.3, 0))
17    print('Displaying original and translated geometries ...')
18    o3d.visualization.draw([{
19        "name": "Original Geometry",
20        "geometry": mesh
21    }, {
22        "name": "Translated (in X) Geometry",
23        "geometry": mesh_tx
24    }, {
25        "name": "Translated (in Y) Geometry",
26        "geometry": mesh_ty
27    }],
28                           show_ui=True)
29
30
31def rotate():
32    mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()
33    mesh_r = copy.deepcopy(mesh)
34    R = mesh.get_rotation_matrix_from_xyz((np.pi / 2, 0, np.pi / 4))
35    mesh_r.rotate(R, center=(0, 0, 0))
36    print('Displaying original and rotated geometries ...')
37    o3d.visualization.draw([{
38        "name": "Original Geometry",
39        "geometry": mesh
40    }, {
41        "name": "Rotated Geometry",
42        "geometry": mesh_r
43    }],
44                           show_ui=True)
45
46
47def scale():
48    mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()
49    mesh_s = copy.deepcopy(mesh).translate((2, 0, 0))
50    mesh_s.scale(0.5, center=mesh_s.get_center())
51    print('Displaying original and scaled geometries ...')
52    o3d.visualization.draw([{
53        "name": "Original Geometry",
54        "geometry": mesh
55    }, {
56        "name": "Scaled Geometry",
57        "geometry": mesh_s
58    }],
59                           show_ui=True)
60
61
62def transform():
63    mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()
64    T = np.eye(4)
65    T[:3, :3] = mesh.get_rotation_matrix_from_xyz((0, np.pi / 3, np.pi / 2))
66    T[0, 3] = 1
67    T[1, 3] = 1.3
68    print(T)
69    mesh_t = copy.deepcopy(mesh).transform(T)
70    print('Displaying original and transformed geometries ...')
71    o3d.visualization.draw([{
72        "name": "Original Geometry",
73        "geometry": mesh
74    }, {
75        "name": "Transformed Geometry",
76        "geometry": mesh_t
77    }],
78                           show_ui=True)
79
80
81if __name__ == "__main__":
82
83    translate()
84    rotate()
85    scale()
86    transform()

triangle_mesh_with_numpy.py#

 1# ----------------------------------------------------------------------------
 2# -                        Open3D: www.open3d.org                            -
 3# ----------------------------------------------------------------------------
 4# Copyright (c) 2018-2024 www.open3d.org
 5# SPDX-License-Identifier: MIT
 6# ----------------------------------------------------------------------------
 7
 8import open3d as o3d
 9import numpy as np
10
11if __name__ == "__main__":
12    # Read a mesh and get its data as numpy arrays.
13    knot_mesh = o3d.data.KnotMesh()
14    mesh = o3d.io.read_triangle_mesh(knot_mesh.path)
15    mesh.paint_uniform_color([0.5, 0.1, 0.3])
16    print('Vertices:')
17    print(np.asarray(mesh.vertices))
18    print('Vertex Colors:')
19    print(np.asarray(mesh.vertex_colors))
20    print('Vertex Normals:')
21    print(np.asarray(mesh.vertex_normals))
22    print('Triangles:')
23    print(np.asarray(mesh.triangles))
24    print('Triangle Normals:')
25    print(np.asarray(mesh.triangle_normals))
26    print("Displaying mesh ...")
27    print(mesh)
28    o3d.visualization.draw([mesh])
29
30    # Create a mesh using numpy arrays with random colors.
31    N = 5
32    vertices = o3d.utility.Vector3dVector(
33        np.array([[0, 0, 0], [1, 0, 0], [1, 0, 1], [0, 0, 1], [0.5, 0.5, 0.5]]))
34    triangles = o3d.utility.Vector3iVector(
35        np.array([[0, 1, 2], [0, 2, 3], [0, 4, 1], [1, 4, 2], [2, 4, 3],
36                  [3, 4, 0]]))
37    mesh_np = o3d.geometry.TriangleMesh(vertices, triangles)
38    mesh_np.vertex_colors = o3d.utility.Vector3dVector(
39        np.random.uniform(0, 1, size=(N, 3)))
40    mesh_np.compute_vertex_normals()
41    print(np.asarray(mesh_np.triangle_normals))
42    print("Displaying mesh made using numpy ...")
43    o3d.visualization.draw_geometries([mesh_np])