Voxel Grid#

voxel_grid_carving.py#

  1# ----------------------------------------------------------------------------
  2# -                        CloudViewer: www.cloudViewer.org                  -
  3# ----------------------------------------------------------------------------
  4# Copyright (c) 2018-2024 www.cloudViewer.org
  5# SPDX-License-Identifier: MIT
  6# ----------------------------------------------------------------------------
  7
  8import cloudViewer as cv3d
  9import numpy as np
 10
 11
 12def xyz_spherical(xyz):
 13    x = xyz[0]
 14    y = xyz[1]
 15    z = xyz[2]
 16    r = np.sqrt(x * x + y * y + z * z)
 17    r_x = np.arccos(y / r)
 18    r_y = np.arctan2(z, x)
 19    return [r, r_x, r_y]
 20
 21
 22def get_rotation_matrix(r_x, r_y):
 23    rot_x = np.asarray([[1, 0, 0], [0, np.cos(r_x), -np.sin(r_x)],
 24                        [0, np.sin(r_x), np.cos(r_x)]])
 25    rot_y = np.asarray([[np.cos(r_y), 0, np.sin(r_y)], [0, 1, 0],
 26                        [-np.sin(r_y), 0, np.cos(r_y)]])
 27    return rot_y.dot(rot_x)
 28
 29
 30def get_extrinsic(xyz):
 31    rvec = xyz_spherical(xyz)
 32    r = get_rotation_matrix(rvec[1], rvec[2])
 33    t = np.asarray([0, 0, 2]).transpose()
 34    trans = np.eye(4)
 35    trans[:3, :3] = r
 36    trans[:3, 3] = t
 37    return trans
 38
 39
 40def preprocess(model):
 41    min_bound = model.get_min_bound()
 42    max_bound = model.get_max_bound()
 43    center = min_bound + (max_bound - min_bound) / 2.0
 44    scale = np.linalg.norm(max_bound - min_bound) / 2.0
 45    vertices = np.asarray(model.vertices())
 46    vertices -= center
 47    model.set_vertices(cv3d.utility.Vector3dVector(vertices / scale))
 48    return model
 49
 50
 51def voxel_carving(mesh, cubic_size, voxel_resolution, w=300, h=300):
 52    mesh.compute_vertex_normals()
 53    camera_sphere = cv3d.geometry.ccMesh.create_sphere(radius=1.0,
 54                                                       resolution=10)
 55
 56    # Setup dense voxel grid.
 57    voxel_carving = cv3d.geometry.VoxelGrid.create_dense(
 58        width=cubic_size,
 59        height=cubic_size,
 60        depth=cubic_size,
 61        voxel_size=cubic_size / voxel_resolution,
 62        origin=[-cubic_size / 2.0, -cubic_size / 2.0, -cubic_size / 2.0],
 63        color=[1.0, 0.7, 0.0])
 64
 65    # Rescale geometry.
 66    camera_sphere = preprocess(camera_sphere)
 67    mesh = preprocess(mesh)
 68
 69    # Setup visualizer to render depthmaps.
 70    vis = cv3d.visualization.Visualizer()
 71    vis.create_window(width=w, height=h, visible=False)
 72    vis.add_geometry(mesh)
 73    vis.get_render_option().mesh_show_back_face = True
 74    ctr = vis.get_view_control()
 75    param = ctr.convert_to_pinhole_camera_parameters()
 76
 77    # Carve voxel grid.
 78    vertices = np.asarray(camera_sphere.vertices())
 79    centers_pts = np.zeros((len(vertices), 3))
 80    for cid, xyz in enumerate(vertices):
 81        # Get new camera pose.
 82        trans = get_extrinsic(xyz)
 83        param.extrinsic = trans
 84        c = np.linalg.inv(trans).dot(np.asarray([0, 0, 0, 1]).transpose())
 85        centers_pts[cid, :] = c[:3]
 86        ctr.convert_from_pinhole_camera_parameters(param)
 87
 88        # Capture depth image and make a point cloud.
 89        vis.poll_events()
 90        vis.update_renderer()
 91        depth = vis.capture_depth_float_buffer(False)
 92
 93        # Depth map carving method.
 94        voxel_carving.carve_depth_map(cv3d.geometry.Image(depth), param)
 95        print("Carve view %03d/%03d" % (cid + 1, len(vertices)))
 96    vis.destroy_window()
 97
 98    return voxel_carving
 99
100
101if __name__ == "__main__":
102    armadillo_data = cv3d.data.ArmadilloMesh()
103    mesh = cv3d.io.read_triangle_mesh(armadillo_data.path)
104    cubic_size = 2.0
105    voxel_resolution = 128.0
106
107    carved_voxels = voxel_carving(mesh, cubic_size, voxel_resolution)
108    print("Carved voxels ...")
109    print(carved_voxels)
110    cv3d.visualization.draw([carved_voxels])

voxel_grid_from_point_cloud.py#

 1# ----------------------------------------------------------------------------
 2# -                        CloudViewer: www.cloudViewer.org                  -
 3# ----------------------------------------------------------------------------
 4# Copyright (c) 2018-2024 www.cloudViewer.org
 5# SPDX-License-Identifier: MIT
 6# ----------------------------------------------------------------------------
 7
 8import cloudViewer as cv3d
 9import numpy as np
10
11if __name__ == "__main__":
12
13    N = 2000
14    armadillo_data = cv3d.data.ArmadilloMesh()
15    pcd = cv3d.io.read_triangle_mesh(
16        armadillo_data.path).sample_points_poisson_disk(N)
17    # Fit to unit cube.
18    pcd.scale(1 / np.max(pcd.get_max_bound() - pcd.get_min_bound()),
19              center=pcd.get_center())
20    pcd.set_colors(
21        cv3d.utility.Vector3dVector(np.random.uniform(0, 1, size=(N, 3))))
22    print('Displaying input point cloud ...')
23    cv3d.visualization.draw([pcd])
24
25    print('Displaying voxel grid ...')
26    voxel_grid = cv3d.geometry.VoxelGrid.create_from_point_cloud(
27        pcd, voxel_size=0.05)
28    cv3d.visualization.draw([voxel_grid])

voxel_grid_from_triangle_mesh.py#

 1# ----------------------------------------------------------------------------
 2# -                        CloudViewer: www.cloudViewer.org                  -
 3# ----------------------------------------------------------------------------
 4# Copyright (c) 2018-2024 www.cloudViewer.org
 5# SPDX-License-Identifier: MIT
 6# ----------------------------------------------------------------------------
 7
 8import cloudViewer as cv3d
 9import numpy as np
10
11if __name__ == "__main__":
12    bunny = cv3d.data.BunnyMesh()
13    mesh = cv3d.io.read_triangle_mesh(bunny.path)
14    mesh.compute_vertex_normals()
15
16    # Fit to unit cube.
17    mesh.scale(1 / np.max(mesh.get_max_bound() - mesh.get_min_bound()),
18               center=mesh.get_center())
19    print('Displaying input mesh ...')
20    cv3d.visualization.draw([mesh])
21
22    voxel_grid = cv3d.geometry.VoxelGrid.create_from_triangle_mesh(
23        mesh, voxel_size=0.05)
24    print('Displaying voxel grid ...')
25    cv3d.visualization.draw([voxel_grid])