def _show_tangent_spheres(mesh, centers, radii, normals=False): """Visualize tangent spheres (debuggin).""" mesh = make_trimesh(mesh, validate=False) fac = 5 / mesh.bounds[1].max() mesh = mesh.copy() mesh.vertices *= fac spheres = [] for c, r in zip(centers, radii): s = tm.primitives.Sphere(center=c * fac, radius=r * fac, subdivisions=0) spheres.append(s) # Make mesh semi-transparent mesh.visual.face_colors = [100, 100, 100, 100] # Generate the scene if not normals: scene = tm.Scene([mesh] + spheres) else: scene = tm.Scene([mesh, _make_normals(mesh)] + spheres) return scene.show()
def visualize(occupied, empty, K, width, height, rgb, pcd, mask, resolution, aabb): window = pyglet.window.Window(width=int(640 * 0.9 * 3), height=int(480 * 0.9)) @window.event def on_key_press(symbol, modifiers): if modifiers == 0: if symbol == pyglet.window.key.Q: window.on_close() gui = glooey.Gui(window) hbox = glooey.HBox() hbox.set_padding(5) camera = trimesh.scene.Camera( resolution=(width, height), focal=(K[0, 0], K[1, 1]), transform=np.eye(4), ) camera_marker = trimesh.creation.camera_marker(camera, marker_height=0.1) # initial camera pose camera.transform = np.array( [[0.73256052, -0.28776419, 0.6168848, 0.66972396], [-0.26470017, -0.95534823, -0.13131483, -0.12390466], [0.62712751, -0.06709345, -0.77602162, -0.28781298], [ 0., 0., 0., 1., ]], ) aabb_min, aabb_max = aabb bbox = trimesh.path.creation.box_outline( aabb_max - aabb_min, tf.translation_matrix((aabb_min + aabb_max) / 2), ) geom = trimesh.PointCloud(vertices=pcd[mask], colors=rgb[mask]) scene = trimesh.Scene(camera=camera, geometry=[bbox, geom, camera_marker]) hbox.add(labeled_scene_widget(scene, label='pointcloud')) geom = trimesh.voxel.multibox(occupied, pitch=resolution, colors=[1., 0, 0, 0.5]) scene = trimesh.Scene(camera=camera, geometry=[bbox, geom, camera_marker]) hbox.add(labeled_scene_widget(scene, label='occupied')) geom = trimesh.voxel.multibox(empty, pitch=resolution, colors=[0.5, 0.5, 0.5, 0.5]) scene = trimesh.Scene(camera=camera, geometry=[bbox, geom, camera_marker]) hbox.add(labeled_scene_widget(scene, label='empty')) gui.add(hbox) pyglet.app.run()
def render_mesh(meshes, fileprefix): mesh_list = [] for i in range(len(meshes)): # m = meshes[i].copy() # R = trimesh.transformations.rotation_matrix(0.0, [1,0,1]) # m.apply_transform(R) # m.apply_translation([i*2.0, 0, 0]) # mesh_list.append(m) m = meshes[i].copy() R = trimesh.transformations.rotation_matrix(1.0, [1, 1, 0]) m.apply_transform(R) m.apply_translation([i * 2.0, 1.5, 0]) mesh_list.append(m) scene = trimesh.Scene(mesh_list) try: # increment the file name file_name = fileprefix + '.png' png = scene.save_image(resolution=[1920, 1080], visible=True) with open(file_name, 'wb') as f: f.write(png) f.close() except BaseException as E: print("unable to save image", str(E))
def show_color_mesh(mesh, images, X, Y, Z, h, w, Ps, is_zf=False): camera_directions = get_camera_direction(h, w, Ps) vertices = mesh.vertices num_vertices = vertices.shape[0] vertex_colors = np.ones((num_vertices, 4), np.uint8) * 255 normals = mesh.vertex_normals for ii in range(num_vertices): angles = np.matmul(normals[ii, :], camera_directions) / np.linalg.norm( normals[ii, :]) cam_idx = np.argmin(angles) #TODO: find a way to locate the accurate xyz location for the vertices x, y, z = int(vertices[ii, 0]), int(vertices[ii, 1]), int(vertices[ii, 2]) imx, imy = projection(Ps[cam_idx], X[x, y, z], Y[x, y, z], Z[x, y, z]) if is_zf: vertex_colors[ii, :3] = images[cam_idx][np.int64(imy - 1) - 387, np.int64(imx - 1), :] else: vertex_colors[ii, :3] = images[cam_idx][np.int64(imy - 1), np.int64(imx - 1), :] mesh.visual.vertex_colors = vertex_colors mesh.vertices -= np.mean(mesh.vertices) scene = trimesh.Scene(mesh) scene.show(smooth=False)
def vis(coords, node_indices, point_indices=None): import trimesh depth = len(coords) scale_factor = np.max(np.linalg.norm(coords[0], axis=-1)) for c in coords: c /= scale_factor if point_indices is None: point_indices = [0] * depth for i, point_index in enumerate(point_indices): ci = coords[i] center = ci[point_index] for j in range(i + 1): cj = coords[j] ni = node_indices[i][j] neighbors = ni[point_index] print(i, j, ci.shape, cj.shape, neighbors.shape) print(np.max(np.linalg.norm(cj[neighbors] - center, axis=-1))) scene = trimesh.Scene() scene.add_geometry(trimesh.PointCloud(cj, color=(0, 255, 0))) scene.add_geometry(trimesh.PointCloud(ci, color=(0, 0, 255))) scene.add_geometry( trimesh.PointCloud(cj[neighbors], color=(255, 0, 0))) scene.add_geometry( trimesh.primitives.Sphere(center=center, radius=0.01)) scene.show(background=(0, 0, 0))
def update_visualisation(self, dt): if self.is_changed: if self.point_cloud is not None: self.octree.insertPointCloud( pointcloud=np.double(self.point_cloud), origin=np.array([0, 0, 0], dtype=float), # TODO this maxrange=2, ) occupied, _ = self.octree.extractPointCloud() aabb_min = self.octree.getMetricMin() aabb_max = self.octree.getMetricMax() bbox = trimesh.path.creation.box_outline( aabb_max - aabb_min, tf.translation_matrix((aabb_min + aabb_max) / 2), ) geom = trimesh.voxel.ops.multibox( occupied, pitch=self.resolution, colors=[1., 0, 0, 0.5] ) self.scene = trimesh.Scene(geometry=[bbox, geom]) # self.update_hbox(occupied, aabb_min, aabb_max) self.is_changed = False else: print("Didn't changed") pass
def __init__(self, update_time=1 / 30, resolution=0.01): self.update_time = update_time self.resolution = resolution self.octree = octomap.OcTree(resolution) self.point_cloud = None self.is_changed = False self.window = pyglet.window.Window(width=1024, height=720) @self.window.event def on_key_press(symbol, modifiers): if modifiers == 0: if symbol == pyglet.window.key.Q: self.window.on_close() # self.gui = None aabb_min = np.array([-1.4, -1., 0.]) aabb_max = np.array([0.45, 0.75, 2.]) initial_bbox = trimesh.path.creation.box_outline( aabb_max - aabb_min, tf.translation_matrix((aabb_min + aabb_max) / 2), ) self.scene = trimesh.Scene(geometry=[initial_bbox]) # initial_bbox print(self.scene) # self.scene = None self.app_visualiser = None self.start_visualiser()
def show_overlap(objfile1, objfile2): mesh1 = trimesh.load_mesh(objfile1) mesh2 = trimesh.load_mesh(objfile2) mesh1.visual.face_colors = [0, 255, 155, 255] mesh2.visual.face_colors = [0, 155, 255, 255] scene = trimesh.Scene([mesh1, mesh2]) scene.show()
def visualize_normals(mesh, le='auto', show=True): """Visualize vertex normals. Parameters ---------- mesh : trimesh.Trimesh le : float Scale factor for length of normal vectors. show : bool Whether to show the scene right away or just to return. Returns ------- trimesh.Scene """ mesh = make_trimesh(mesh, validate=False) # Make mesh semi-transparent mesh.visual.face_colors = [100, 100, 100, 100] # Generate the scene path = _make_normals(mesh, le=le) scene = tm.Scene([mesh.copy(), path]) # I encountered some issues if object space is big and the easiest # way to work around this is to apply a transform such that the # coordinates have -5 to +5 bounds fac = 5 / mesh.bounds[1].max() scene.apply_transform(np.diag([fac, fac, fac, 1])) if show: return scene.show() else: return scene
def show_error_map(gender, predfile, truefile): #null_vertex = np.loadtxt('./data/input/{}/nodes.txt'.format(gender)) #null_vertex = null_vertex.astype(int) null_vertex = [] error_vlist = vertex_to_vertex_error(predfile, truefile, null_vertex) predMesh = trimesh.load_mesh(predfile, process=False) maxV = 0.01 minV = 0.00001 #maxV, minV = error_vlist.max(), error_vlist.min() # maxV and minV can be specified by datasets or other bad results #print('max error:{:.3f}, min error:{:.3f}'.format(maxV*100, minV*100)) error_normalize = (error_vlist - minV) / (maxV - minV) # color_range = [[0, 255, 0, 255],[255, 0, 0, 255]] # vertex_color = trimesh.visual.color.linear_color_map(error_normalize, color_range=color_range) vertex_color = define_color_map(error_normalize) for j in null_vertex: vertex_color[j - 1] = [240, 240, 240, 255] predMesh.visual.vertex_colors = vertex_color predMesh.show() # show overlap trueMesh = trimesh.load_mesh(truefile) trueMesh.visual.vertex_colors = [240, 240, 240, 255] scene = trimesh.Scene([predMesh, trueMesh]) scene.show()
def get_renders(self, file_path, obj_type, transformations): renders = [] obj = trimesh.load(file_path, process=False) try: meshes_list = obj.dump() scene = trimesh.Scene(meshes_list) except: mesh = obj scene = mesh.scene() scene.centroid #scene.show() for i in range(10): scene.apply_transform(transformations[i]) try: file_name = 'renders/render_' + obj_type + str( i) + '.png' #fix it add mkdir renders.append(file_name) png = scene.save_image(resolution=[500, 500], visible=True) with open(file_name, 'wb') as f: f.write(png) f.close() except BaseException as E: print("unable to save image", str(E)) return renders
def __init__(self): # create window with padding self.width, self.height = 480 * 3, 360 window = self._create_window(width=self.width, height=self.height) gui = glooey.Gui(window) hbox = glooey.HBox() hbox.set_padding(5) # scene widget for changing camera location scene = create_scene() self.scene_widget1 = trimesh.viewer.SceneWidget(scene) self.scene_widget1._angles = [np.deg2rad(45), 0, 0] hbox.add(self.scene_widget1) # scene widget for changing scene scene = trimesh.Scene() geom = trimesh.path.creation.box_outline((0.6, 0.6, 0.6)) scene.add_geometry(geom) self.scene_widget2 = trimesh.viewer.SceneWidget(scene) hbox.add(self.scene_widget2) # integrate with other widget than SceneWidget self.image_widget = glooey.Image() hbox.add(self.image_widget) gui.add(hbox) pyglet.clock.schedule_interval(self.callback, 1. / 20) pyglet.app.run()
def create_scene2(): scene = trimesh.Scene() for _ in range(5): geom = trimesh.load('models/fuze.obj') R = tf.random_rotation_matrix() T = tf.translation_matrix(np.random.uniform(-0.3, 0.3, (3, ))) scene.add_geometry(geom, transform=T @ R) return scene
def meshVisualization(mesh): worldMeshList = getWorldMeshList(planeWidth=0.2, axisHeight=0.05, axisRadius=0.001) mesh.visual.face_colors = [255, 128, 255, 200] worldMeshList.append(mesh) scene = trimesh.Scene(worldMeshList) scene.show()
def create_scene1(): scene = trimesh.Scene() for _ in range(20): geom = trimesh.creation.axis(0.02) R = tf.random_rotation_matrix() T = tf.translation_matrix(np.random.uniform(-1, 1, (3, ))) scene.add_geometry(geom, transform=T @ R) return scene
def preview_tree(tree, other_objects=None): if other_objects is None: other_objects = [] scene = trimesh.Scene() for leaf in tree.leaves + other_objects: leaf.part.visual.face_colors = np.random.rand(3) * 255 scene.add_geometry(leaf.part) scene.camera.z_far = 10_000 scene.show()
def __init__(self, path, load_materials=False): scene = trimesh.load(str(path)) if isinstance(scene, trimesh.Trimesh): scene = trimesh.Scene(scene) self.meshes: typing.List[trimesh.Trimesh] = list(scene.dump()) self.path = path self.scale = 1.0
def get_mesh_scene(mesh, boundary=None, editable_vertices=None): scene = [mesh] if boundary: scene.append(trimesh.load_path(mesh.vertices[boundary + [boundary[0]]])) if editable_vertices: scene.append( trimesh.points.PointCloud(mesh.vertices[editable_vertices + boundary])) return trimesh.Scene(scene)
def visualize(self, scene_grasps, scene_contacts=None): """ Visualizes table top scene with grasps Arguments: scene_grasps {np.ndarray} -- Nx4x4 grasp transforms scene_contacts {np.ndarray} -- Nx2x3 grasp contacts """ print('Visualizing scene and grasps.. takes time') gripper_marker = create_gripper_marker(color=[0, 255, 0]) gripper_markers = [gripper_marker.copy().apply_transform(t) for t in scene_grasps] colors = np.ones((scene_contacts.shape[0]*2,4))*255 colors[:,0:2] = 0 scene_contact_scene = trimesh.Scene(trimesh.points.PointCloud(scene_contacts.reshape(-1,3), colors=colors)) # show scene together with successful and collision-free grasps of all objects trimesh.scene.scene.append_scenes( [self.colorize().as_trimesh_scene(), trimesh.Scene(gripper_markers), scene_contact_scene] ).show()
def _make_glb_from_polys(self, polygons): scene = trimesh.Scene() vertices, faces = [], [] point_dict = dict() current_point_index = 0 # Trimesh's API require a list of vertices and a list of faces, where each # face contains three indexes into the vertices list. Ideally, the vertices # are all unique and the faces list references the same indexes as needed. # TODO: Batch the polygon processing. for poly in polygons: # Collect all the points on the shape to reduce checks by 3 times for x, y in poly.exterior.coords: p = (x, y, 0) if p not in point_dict: vertices.append(p) point_dict[p] = current_point_index current_point_index += 1 triangles = SumoRoadNetwork._triangulate(poly) for triangle in triangles: face = np.array([ point_dict.get((x, y, 0), -1) for x, y in triangle.exterior.coords ]) # Add face if not invalid if -1 not in face: faces.append(face) mesh = trimesh.Trimesh(vertices=vertices, faces=faces) # Trimesh doesn't support a coordinate-system="z-up" configuration, so we # have to apply the transformation manually. mesh.apply_transform( trimesh.transformations.rotation_matrix(math.pi / 2, [-1, 0, 0])) # Attach additional information for rendering as metadata in the map glb metadata = {} # <2D-BOUNDING_BOX>: four floats separated by ',' (<FLOAT>,<FLOAT>,<FLOAT>,<FLOAT>), # which describe x-minimum, y-minimum, x-maximum, and y-maximum metadata["bounding_box"] = self.graph.getBoundary() # lane markings information lane_dividers, edge_dividers = self.compute_traffic_dividers() metadata["lane_dividers"] = lane_dividers metadata["edge_dividers"] = edge_dividers mesh.visual = trimesh.visual.TextureVisuals( material=trimesh.visual.material.PBRMaterial()) scene.add_geometry(mesh) return GLBData( gltf.export_glb(scene, extras=metadata, include_normals=True))
def main(argv=sys.argv[1:]): parser = make_parser() args = parser.parse_args(argv) # load object meshes object_meshes = [load_mesh(o, mesh_root_dir=args.mesh_root) for o in args.objects] support_mesh = load_mesh( args.support, mesh_root_dir=args.mesh_root, scale=args.support_scale ) scene = Scene.random_arrangement(object_meshes, support_mesh) # show the random scene in 3D viewer scene.colorize().as_trimesh_scene().show() if args.show_grasps: # load gripper mesh for collision check gripper_mesh = trimesh.load( Path(__file__).parent.parent / "data/franka_gripper_collision_mesh.stl" ) gripper_markers = [] for i, fname in enumerate(args.objects): T, success = load_grasps(fname) obj_pose = scene._poses["obj{}".format(i)] # check collisions collision_free = np.array( [ i for i, t in enumerate(T[success == 1][: args.num_grasps_per_object]) if not scene.in_collision_with( gripper_mesh, transform=np.dot(obj_pose, t) ) ] ) if len(collision_free) == 0: continue # add a gripper marker for every collision free grasp gripper_markers.extend( [ create_gripper_marker(color=[0, 255, 0]).apply_transform( np.dot(obj_pose, t) ) for t in T[success == 1][collision_free] ] ) # show scene together with successful and collision-free grasps of all objects trimesh.scene.scene.append_scenes( [scene.colorize().as_trimesh_scene(), trimesh.Scene(gripper_markers)] ).show()
def scene(self, mesh=False, **kwargs): """Return a Scene object containing the skeleton. Returns ------- scene : trimesh.scene.scene.Scene Contains the skeleton and optionally the mesh. """ if mesh: if isinstance(self.mesh, type(None)): raise ValueError('Skeleton has no mesh.') self.mesh.visual.face_colors = [100, 100, 100, 100] # Note the copy(): without it the transform in show() changes # the original meshes sc = tm.Scene([self.mesh.copy(), self.skeleton.copy()], **kwargs) else: sc = tm.Scene(self.skeleton, **kwargs) return sc
def meshVisualization(mesh): worldMeshList = getWorldMeshList(planeWidth=0.2, axisHeight=0.05, axisRadius=0.001) if isinstance(mesh, trimesh.base.Trimesh): mesh.visual.face_colors = [255, 128, 255, 200] worldMeshList.append(mesh) elif isinstance(mesh, list): for meshItem in mesh: meshItem.visual.face_colors = [255, 128, 255, 200] worldMeshList.append(meshItem) scene = trimesh.Scene(worldMeshList) scene.show()
def visual(self): """ visual Crea una imagen visual del satelite con unos ejes funciona muy bien en notebook y en linux tambien deberia de poder funcionar Returns: (scene): retoma una escena con los ejes """ ax = trimesh.creation.axis(axis_radius=25, axis_length=200) scene = trimesh.Scene([self.mesh.apply_scale(1), ax]) return scene.show()
def contactVisualization(mesh, contact1, contact2): worldMeshList = getWorldMeshList(planeWidth=2, axisHeight=0.5, axisRadius=0.01) contact1Mesh = trimesh.primitives.Box(extents=[0.005, 0.005, 0.005]) contact1Mesh.apply_translation(contact1) contact2Mesh = trimesh.primitives.Box(extents=[0.005, 0.005, 0.005]) contact2Mesh.apply_translation(contact2) mesh.visual.face_colors = [255, 128, 255, 200] worldMeshList.append(mesh) worldMeshList.append(contact1Mesh) worldMeshList.append(contact2Mesh) scene = trimesh.Scene(worldMeshList) scene.show()
def visualize_mesh(self, faces_to_colour, vector_origins=[], vector_normals=[], scale=2.0): """ Debugging plot for visualizing intersecting faces and vectors Parameters ---------- faces_to_colour : (n,1) array array of face indexes that need to be coloured differently vector_origins : (n,3) np.array set of vector origins to plot vector_normals : (n,3) np.array List of normal vectors corresponding to vector_origins scale: float, optional Amount to scale the vector normal plot by """ mesh = self.mesh.copy() # unmerge so viewer doesn't smooth mesh.unmerge_vertices() # make base_mesh white- ish mesh.visual.face_colors = [105, 105, 105, 105] mesh.visual.face_colors[faces_to_colour] = [255, 0, 0, 255] if vector_origins != [] and vector_normals != []: # stack rays into line segments for visualization as Path3D ray_visualize = trimesh.load_path( np.hstack((vector_origins, vector_origins + vector_normals * scale)).reshape(-1, 2, 3)) ray_visualize.merge_vertices() scene = trimesh.Scene([mesh, ray_visualize]) else: scene = trimesh.Scene([mesh]) scene.show()
def algorithm(): gpu = 0 if gpu >= 0: cuda.get_device_from_id(gpu).use() instance_id = 3 # == class_id models = morefusion.datasets.YCBVideoModels() pcd_cad = models.get_pcd(class_id=instance_id) dataset = morefusion.datasets.YCBVideoDataset("train") example = dataset.get_example(1000) depth = example["depth"] instance_label = example["label"] K = example["meta"]["intrinsic_matrix"] pcd_depth = morefusion.geometry.pointcloud_from_depth(depth, fx=K[0, 0], fy=K[1, 1], cx=K[0, 2], cy=K[1, 2]) nonnan = ~np.isnan(pcd_depth).any(axis=2) mask = (instance_label == instance_id) & nonnan pcd_depth_target = pcd_depth[mask] # ------------------------------------------------------------------------- quaternion_init = np.array([1, 0, 0, 0], dtype=np.float32) translation_init = np.median(pcd_depth_target, axis=0) transform_init = morefusion.functions.transformation_matrix( quaternion_init, translation_init).array pcd_cad = morefusion.extra.open3d.voxel_down_sample(pcd_cad, voxel_size=0.01) pcd_depth_target = morefusion.extra.open3d.voxel_down_sample( pcd_depth_target, voxel_size=0.01) registration = ICPRegistration(pcd_depth_target, pcd_cad, transform_init) for T_cad2cam in registration.register_iterative(): scene = trimesh.Scene() geom = trimesh.PointCloud(pcd_depth_target, colors=[1.0, 0, 0]) scene.add_geometry(geom, geom_name="a", node_name="a") geom = trimesh.PointCloud(pcd_cad, colors=[0, 1.0, 0]) scene.add_geometry(geom, geom_name="b", node_name="b", transform=T_cad2cam) scene.camera_transform = morefusion.extra.trimesh.to_opengl_transform() yield scene
def get_scenes(): dataset = morefusion.datasets.YCBVideoDataset("train") index = 0 video_id_prev = None scene = trimesh.Scene() while index < len(dataset): example = dataset[index] video_id, frame_id = dataset.ids[index].split("/") clear = False if video_id_prev is not None and video_id_prev != video_id: clear = True for node_name in scene.graph.nodes_geometry: scene.graph.transforms.remove_node(node_name) video_id_prev = video_id rgb = example["color"] depth = example["depth"] K = example["meta"]["intrinsic_matrix"] T_world2cam = np.r_[example["meta"]["rotation_translation_matrix"], [[0, 0, 0, 1]]] T_cam2world = np.linalg.inv(T_world2cam) pcd = morefusion.geometry.pointcloud_from_depth(depth, fx=K[0, 0], fy=K[1, 1], cx=K[0, 2], cy=K[1, 2]) nonnan = ~np.isnan(depth) geom = trimesh.PointCloud(vertices=pcd[nonnan], colors=rgb[nonnan]) scene.add_geometry(geom, transform=T_cam2world) # A kind of current camera view, but a bit far away to see whole scene. scene.camera.resolution = (rgb.shape[1], rgb.shape[0]) scene.camera.focal = (K[0, 0], K[1, 1]) scene.camera_transform = morefusion.extra.trimesh.to_opengl_transform( T_cam2world @ tf.translation_matrix([0, 0, -0.5])) # scene.set_camera() geom = trimesh.creation.camera_marker(scene.camera, marker_height=0.05)[1] geom.colors = [(0, 1.0, 0)] * len(geom.entities) scene.add_geometry(geom, transform=T_cam2world) index += 15 print(f"[{index:08d}] video_id={video_id}") yield {"__clear__": clear, "rgb": rgb, "scene": scene}
def visualizeMesh(mesh, data=None, colors=None, color_map='seismic', int_color_map=None, save=True, max_width=4, shift_axis='x', **kwargs): # figure out where to get color information if (data is None and colors is None): # just visualize the mesh geometry return mesh.show(**kwargs) elif (colors is None): # compute colors from the data array vertex_colors = [] for i in range(len(data)): if (data[i].dtype == np.int64 or data[i].dtype == np.bool): vertex_colors.append( trimesh.visual.to_rgba(int_color_map[data[i] + 1])) else: vertex_colors.append( trimesh.visual.interpolate(data[i], color_map=color_map)) else: # use the given colors if (isinstance(colors, list)): vertex_colors = colors else: vertex_colors = [colors] scene = [] # hold a list of meshes that determine the scene # determine how to arrange multiple copies of the mesh si = ['x', 'y', 'z'].index(shift_axis) offset = 0.0 # cumulative distance we translate new meshes shift = np.array([0.0, 0.0, 0.0]) # direction to translate meshes shift[si] = 1.0 # loop over each mesh copy for i in range(len(vertex_colors)): # add meshes to scene list m = mesh.copy() m.apply_translation(offset * shift) m.visual.vertex_colors = vertex_colors[i] offset += 1.1 * m.bounding_box.extents[si] scene.append(m) print("returning scene") if save and len(scene) == 1: scene[0].export("mesh.ply") #, encoding="ascii") return trimesh.Scene(scene).show(**kwargs)
def pointCloudViewer(pointCloud, boxScale=0.0005): worldMeshList = getWorldMeshList(planeWidth=0.2, axisHeight=0.05, axisRadius=0.001) boxColor = [255, 128, 255, 180] for point in pointCloud: transform = np.eye(4) transform[:3, 3] = point temp = trimesh.primitives.Box(extents=[boxScale, boxScale, boxScale], transform=transform) temp.visual.face_colors = boxColor worldMeshList.append(temp) scene = trimesh.Scene(worldMeshList) scene.show()