def render_mesh(mesh_trimesh, camera_center, camera_transl, focal_length, img_width, img_height): import pyrender import trimesh material = pyrender.MetallicRoughnessMaterial( metallicFactor=0.0, alphaMode='OPAQUE', baseColorFactor=(1.0, 1.0, 0.9, 1.0)) script_dir = os.path.dirname(os.path.realpath(__file__)) vertex_colors = np.loadtxt(os.path.join(script_dir, 'smplx_verts_colors.txt')) mesh_new = trimesh.Trimesh(vertices=mesh_trimesh.vertices, faces=mesh_trimesh.faces, vertex_colors=vertex_colors) mesh_new.vertex_colors = vertex_colors print("mesh visual kind: %s" % mesh_new.visual.kind) #mesh = pyrender.Mesh.from_points(out_mesh.vertices, colors=vertex_colors) mesh = pyrender.Mesh.from_trimesh(mesh_new, smooth=False, wireframe=False) scene = pyrender.Scene(bg_color=[1.0, 1.0, 1.0, 0.0], ambient_light=(0.3, 0.3, 0.3)) #scene = pyrender.Scene(bg_color=[0.0, 0.0, 0.0, 0.0]) scene.add(mesh, 'mesh') camera_pose = np.eye(4) camera_pose[:3, 3] = camera_transl camera = pyrender.camera.IntrinsicsCamera( fx=focal_length, fy=focal_length, cx=camera_center[0], cy=camera_center[1]) scene.add(camera, pose=camera_pose) light = pyrender.light.DirectionalLight() scene.add(light) r = pyrender.OffscreenRenderer(viewport_width=img_width, viewport_height=img_height, point_size=1.0) color, _ = r.render(scene, flags=pyrender.RenderFlags.RGBA) color = color.astype(np.float32) / 255.0 output_img = color[:, :, 0:3] output_img = (output_img * 255).astype(np.uint8) return output_img
def binary_to_trimesh(binary, step=1): """ Convert binary voxel image to a mesh Marching cubes meshed output from http://scikit-image.org/docs/dev/api/skimage.measure.html#marching-cubes-lewiner Parameters ---------- binary: i-by-j-by-k array array to mesh, assumed to be binary segmentation step: int (default 1) number of voxels to step over when generating mesh, larger is courser """ verts, faces, _, _ = skimage.measure.marching_cubes(binary, step_size=step) mesh = trimesh.Trimesh(verts, faces) mesh.fix_normals() return mesh
def random_triangles(n=3): """ Create n triangles which can overlap """ coords = [] for i in range(n * 3): coords.append( [random.random() * 5, random.random() * 5, random.random() * 5]) coords = np.array(coords) faces = [] for i in range(n): faces.append([i * 3, i * 3 + 1, i * 3 + 2]) faces = np.array(faces) return trimesh.Trimesh(faces=faces, vertices=coords, process=False)
def ConvertToSTL(): pointcloud = o3d.io.read_point_cloud("temps\pointCloudTest.ply") pointcloud.estimate_normals() # estimate radius voor de rolling ball distances = pcd.compute_nearest_neighbor_distance() avg_dist = np.mean(distances) radius = 1.5 * avg_dist mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting( pcd, o3d.utility.DoubleVector([radius, radius * 2])) output = trimesh.Trimesh(np.asarray(mesh.vertices), np.asarray(mesh.triangles), vertex_normals=np.asarray(mesh.vertex_normals)) output.export('eindresultaat.stl')
def compute_geodesic_matrix(verts, faces, NN): # get adjacency matrix mesh = trimesh.Trimesh(vertices=verts, faces=faces, process=False) vertex_adjacency = mesh.vertex_adjacency_graph vertex_adjacency_matrix = nx.adjacency_matrix(vertex_adjacency, range(verts.shape[0])) # get adjacency distance matrix graph_x_csr = neighbors.kneighbors_graph(verts, n_neighbors=NN, mode='distance', include_self=False) distance_adj = csr_matrix((verts.shape[0], verts.shape[0])).tolil() distance_adj[vertex_adjacency_matrix != 0] = graph_x_csr[ vertex_adjacency_matrix != 0] # compute geodesic matrix geodesic_x = graph_shortest_path(distance_adj, directed=False) return geodesic_x
def load_mesh(gifti_file): """ load gifti_file and create a trimesh object :param gifti_file: str, path to the gifti file on the disk :return: the corresponding trimesh object """ g = nb.load(gifti_file) coords, faces = g.get_arrays_from_intent( nb.nifti1.intent_codes['NIFTI_INTENT_POINTSET'])[0].data, \ g.get_arrays_from_intent( nb.nifti1.intent_codes['NIFTI_INTENT_TRIANGLE'])[0].data metadata = g.meta.metadata metadata['filename'] = gifti_file return trimesh.Trimesh(faces=faces, vertices=coords, metadata=metadata, process=False)
def load_scene(path=None, scene_id=0): scene = V2aScene(scene_id=scene_id) base_path = os.path.dirname(os.path.abspath(__file__)) if path is None: path = os.path.join(base_path, 'SHOP_VRB_scenes_V2A.json') f = open(path) data = json.load(f) scene.objects = [] for idx, obj in enumerate(data['scenes'][scene_id]['objects']): index = idx fname = str(obj['file']) point = obj['3d_coords'] rotation = obj['rotation'] rot = obj['orientation'] quat = Quaternion(rot[1], rot[2], rot[3], rot[0]) # # bb_dim = [obj['bbox']['x'], obj['bbox']['y'], obj['bbox']['z']] # bb_pos = copy.copy(point) # bb_pos[2] += 0.5*bb_dim[2] #TODO: thig objects is only valid for standing objects vert = np.linspace(0, 7, 7, dtype=int) mesh = trimesh.Trimesh( vertices=obj['bbox_robot_coords'], faces=[[t1, t2, t3] for t1, t2, t3 in zip(vert[0:-2], vert[1:-1], vert[2:]) ]) bb_dim = mesh.bounding_box.extents bb_pos = mesh.bounding_box.center_mass # bb_rot = [0, 0, 0, 1.0] scale = obj['scale_factor'] scene.objects.append( myObject(index, fname, point, rotation, bb_dim, bb_pos, scale, orientation=quat, gripper_setting=getGripperSetting(fname))) for obj in scene.objects: print(obj.ID, ': {}'.format(obj.fname)) return scene
def visualize_query_points(query_pts_ms, query_dist_ms, file_out_off): import trimesh # grey-scale distance query_dist_abs_ms = np.abs(query_dist_ms) query_dist_abs_normalized_ms = query_dist_abs_ms / query_dist_abs_ms.max() # red-green: inside-outside query_dist_col = np.zeros((query_dist_ms.shape[0], 3)) pos_dist = query_dist_ms < 0.0 neg_dist = query_dist_ms > 0.0 query_dist_col[pos_dist, 0] = 0.5 + 0.5 * query_dist_abs_normalized_ms[pos_dist] query_dist_col[neg_dist, 1] = 0.5 + 0.5 * query_dist_abs_normalized_ms[neg_dist] mesh = trimesh.Trimesh(vertices=query_pts_ms, vertex_colors=query_dist_col) mesh.export(file_out_off)
def main(): global OUTPUT_DIR os.makedirs(OUTPUT_DIR, exist_ok=True) data_dir = download_maybe(output_dir=OUTPUT_DIR) dataset = tf.data.Dataset.list_files(os.path.join(data_dir, "**", "**", "**.off"), shuffle=True) dataset = dataset.map(read_OFF_file, num_parallel_calls=tf.data.experimental.AUTOTUNE) # dataset = dataset.batch(1) dataset = dataset.prefetch(1) for x in dataset: (points, faces), path = x path = path.numpy().decode() tm = trimesh.Trimesh(vertices=points, faces=faces) tm.show(caption=path)
def marching_cube_mesh(cube_lattice, tiles_path): # extract cube indices cube_ind = np.transpose(np.indices(cube_lattice.shape), (1, 2, 3, 0)).reshape(-1, 3) # extract cube positions cube_pos = (cube_ind + 0.5) * cube_lattice.unit + cube_lattice.minbound # extract cube tid cube_tid = cube_lattice.ravel() # remove the cube position and tid where tid is 0 filled_cube_pos = cube_pos[cube_tid > 0] filled_cube_tid = cube_tid[cube_tid > 0] # load tiles tiles = [0] for i in range(1, 256): tile_path = os.path.join(tiles_path, 't_' + f'{i:03}' + '.obj') tile = tm.load(tile_path) tile.vertices *= cube_lattice.unit tiles.append(tile) last_v_count = 0 vertice_list = [] face_list = [] # place tiles for i in range(1, filled_cube_tid.size): # extract current tile tile = tiles[filled_cube_tid[i]] # append the vertices vertice_list.append(tile.vertices + filled_cube_pos[i]) face_list.append(tile.faces + last_v_count) last_v_count += len(tile.vertices) vs = [] fs = [] # if len(vertice_list): vs = np.vstack(vertice_list) fs = np.vstack(face_list) tile_mesh = tm.Trimesh(vs, fs) return tile_mesh
def to_trimesh(self) -> 'trimesh.Trimesh': """ Returns trimesh representation of this volume. See Also -------- https://github.com/mikedh/trimesh trimesh GitHub page. """ try: import trimesh except ImportError: raise ImportError('Unable to import trimesh. Please make sure it ' 'is installed properly') return trimesh.Trimesh(vertices=self.vertices, faces=self.faces) # type ignore
def render(self, img, verts, cam, angle=None, axis=None, color=[1.0, 1.0, 0.9]): mesh = trimesh.Trimesh(vertices=verts, faces=self.faces) Rx = trimesh.transformations.rotation_matrix(math.radians(180), [1, 0, 0]) mesh.apply_transform(Rx) if angle and axis: R = trimesh.transformations.rotation_matrix(math.radians(angle), axis) mesh.apply_transform(R) sx, sy, tx, ty = cam camera = WeakPerspectiveCamera( scale=[sx, sy], translation=[tx, ty], zfar=1000. ) material = pyrender.MetallicRoughnessMaterial( metallicFactor=0.0, alphaMode='OPAQUE', baseColorFactor=(color[0], color[1], color[2], 1.0) ) mesh = pyrender.Mesh.from_trimesh(mesh, material=material) mesh_node = self.scene.add(mesh, 'mesh') camera_pose = np.eye(4) cam_node = self.scene.add(camera, pose=camera_pose) if self.wireframe: render_flags = RenderFlags.RGBA | RenderFlags.ALL_WIREFRAME else: render_flags = RenderFlags.RGBA rgb, _ = self.renderer.render(self.scene, flags=render_flags) valid_mask = (rgb[:, :, -1] > 0)[:, :, np.newaxis] output_img = rgb[:, :, :-1] * valid_mask + (1 - valid_mask) * img image = output_img.astype(np.uint8) self.scene.remove_node(mesh_node) self.scene.remove_node(cam_node) return image
def test_x_distance(): import trimesh vertices = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [-1, 0, 0]]) faces = np.array([[2, 1, 0], [0, 3, 2]]) mesh = trimesh.Trimesh(vertices=vertices, faces=faces) points = np.array([[0, 1, 0]]) R = points[:, None, None, :] - mesh.vertices[faces][None, :, :, :] x = integrals.x_distance(R, mesh.face_normals, mesh.area_faces) assert_allclose(x, np.array([[[0.0, 1.0, 0.0], [2.0, -1.0, -1.0]]]))
def get_surface_curvature(verts, faces, normals, radius=1, num_sampled_points=300, mode='grid'): """ compute the shortest path between random two random points on the surface. if mode is grid the points are sampled regularly, else random the points are sampled randomly """ num_nodes = verts.shape[0] - 1 sampled_nodes = node_sampling(mode, sample_size=num_sampled_points, total_nodes=num_nodes) x = trimesh.Trimesh(vertices=verts, faces=faces, vertex_normals=normals) return curvature.discrete_mean_curvature_measure(x, verts[sampled_nodes], radius)
def to_mesh(self, color=colors['red']): v = np.array([[0.0000, -1.000, 0.0000], [0.7236, -0.447, 0.5257], [-0.278, -0.447, 0.8506], [-0.894, -0.447, 0.0000], [-0.278, -0.447, -0.850], [0.7236, -0.447, -0.525], [0.2765, 0.4472, 0.8506], [-0.723, 0.4472, 0.5257], [-0.720, 0.4472, -0.525], [0.2763, 0.4472, -0.850], [0.8945, 0.4472, 0.0000], [0.0000, 1.0000, 0.0000], [-0.165, -0.850, 0.4999], [0.4253, -0.850, 0.3090], [0.2629, -0.525, 0.8090], [0.4253, -0.850, -0.309], [0.8508, -0.525, 0.0000], [-0.525, -0.850, 0.0000], [-0.688, -0.525, 0.4999], [-0.162, -0.850, -0.499], [-0.688, -0.525, -0.499], [0.2628, -0.525, -0.809], [0.9518, 0.0000, -0.309], [0.9510, 0.0000, 0.3090], [0.5876, 0.0000, 0.8090], [0.0000, 0.0000, 1.0000], [-0.588, 0.0000, 0.8090], [-0.951, 0.0000, 0.3090], [-0.955, 0.0000, -0.309], [-0.587, 0.0000, -0.809], [0.0000, 0.0000, -1.000], [0.5877, 0.0000, -0.809], [0.6889, 0.5257, 0.4999], [-0.262, 0.5257, 0.8090], [-0.854, 0.5257, 0.0000], [-0.262, 0.5257, -0.809], [0.6889, 0.5257, -0.499], [0.5257, 0.8506, 0.0000], [0.1626, 0.8506, 0.4999], [-0.425, 0.8506, 0.3090], [-0.422, 0.8506, -0.309], [0.1624, 0.8506, -0.499]]) f = np.array( [[15, 3, 13], [13, 14, 15], [2, 15, 14], [13, 1, 14], [17, 2, 14], [14, 16, 17], [6, 17, 16], [14, 1, 16], [19, 4, 18], [18, 13, 19], [3, 19, 13], [18, 1, 13], [21, 5, 20], [20, 18, 21], [4, 21, 18], [20, 1, 18], [22, 6, 16], [16, 20, 22], [5, 22, 20], [16, 1, 20], [24, 2, 17], [17, 23, 24], [11, 24, 23], [23, 17, 6], [26, 3, 15], [15, 25, 26], [7, 26, 25], [25, 15, 2], [28, 4, 19], [19, 27, 28], [8, 28, 27], [27, 19, 3], [30, 5, 21], [21, 29, 30], [9, 30, 29], [29, 21, 4], [32, 6, 22], [22, 31, 32], [10, 32, 31], [31, 22, 5], [33, 7, 25], [25, 24, 33], [11, 33, 24], [24, 25, 2], [34, 8, 27], [27, 26, 34], [7, 34, 26], [26, 27, 3], [35, 9, 29], [29, 28, 35], [8, 35, 28], [28, 29, 4], [36, 10, 31], [31, 30, 36], [9, 36, 30], [30, 31, 5], [37, 11, 23], [23, 32, 37], [10, 37, 32], [32, 23, 6], [39, 7, 33], [33, 38, 39], [12, 39, 38], [38, 33, 11], [40, 8, 34], [34, 39, 40], [12, 40, 39], [39, 34, 7], [41, 9, 35], [35, 40, 41], [12, 41, 40], [40, 35, 8], [42, 10, 36], [36, 41, 42], [12, 42, 41], [41, 36, 9], [38, 11, 37], [37, 42, 38], [12, 38, 42], [42, 37, 10]]) - 1 # return Mesh(v=v * self.radius + self.center, f=f, vc=np.tile(color, (v.shape[0], 1))) return trimesh.Trimesh(vertices=v * self.radius + self.center, faces=f, vertex_colors=np.tile(color, (v.shape[0], 1)))
def flatten_mesh(mesh, _lambda=1.0): """Flatten the mesh, return uv coordinates and the mesh in 2D Parameters ---------- mesh : Trimesh object must have boundary _lambda : int <= 1.0 parameter for trading of area-distortion/angle-preservation. The default is 1.0 Returns ------- u : array first coordinate of the paramterization v : array second coordinate of the paramterization mesh2d : Trimesh object with coordinates (u,v,0) _lambda <= 1.0 _lambda == 1.0 => conformal mapping _lambda == 0.5 => not conformal but less area distortion _lambda --> 0 mapping becomes denegerate (real==imag) _lambda > 1 (e.g. 1.01-1.1) folding effects """ vals, uv = eigen_complex_laplacian(mesh, 2, _lambda) # Coordinates with initial phase u = uv[:, 1].real v = uv[:, 1].imag # Determine "phase" by matching the uv coordinate function with mesh coordinates theta = np.linspace(0, 2 * np.pi, 50) yy = np.imag(np.exp(1j * theta)[:, None] * uv[:, 1]) # plt.plot(np.sum(mesh.vertices[:,0]*xx, axis=1)) ii = np.argmax(np.sum(mesh.vertices[:, 1] * yy, axis=1)) theta = theta[ii] u = np.real(np.exp(1j * theta) * uv[:, 1]) v = np.imag(np.exp(1j * theta) * uv[:, 1]) mesh2d = trimesh.Trimesh(np.array([u, v, 0 * u]).T, mesh.faces, process=False) return u, v, mesh2d
def _generate_gel_trimesh(self): # Load config g = self.conf.sensor.gel origin = g.origin X0, Y0, Z0 = origin[0], origin[1], origin[2] W, H = g.width, g.height if g.mesh is not None: gel_trimesh = trimesh.load(g.mesh) # scale up for clearer indentation matrix = np.eye(4) matrix[[0, 1, 2], [0, 1, 2]] = 1.02 gel_trimesh = gel_trimesh.apply_transform(matrix) elif not g.curvature: # Flat gel surface gel_trimesh = trimesh.Trimesh( vertices=[ [X0, Y0 + W / 2, Z0 + H / 2], [X0, Y0 + W / 2, Z0 - H / 2], [X0, Y0 - W / 2, Z0 - H / 2], [X0, Y0 - W / 2, Z0 + H / 2], ], faces=[[0, 1, 2], [2, 3, 0]], ) else: # Curved gel surface N = g.countW M = int(N * H / W) R = g.R zrange = g.curvatureMax y = np.linspace(Y0 - W / 2, Y0 + W / 2, N) z = np.linspace(Z0 - H / 2, Z0 + H / 2, M) yy, zz = np.meshgrid(y, z) h = R - np.maximum(0, R**2 - (yy - Y0)**2 - (zz - Z0)**2)**0.5 xx = X0 - zrange * h / h.max() gel_trimesh = self._generate_trimesh_from_depth(xx) return gel_trimesh
def createMesh(size, n, omino_set): ominos = generateOminos(n) vertices = [] triangles = [] baseTriangles = [(i,(i+1)%4,(i+1)%4+4) for i in range(4)]+[(i,(i+1)%4+4,i+4) for i in range(4)]+[(5,6,7),(5,7,4)] for i in range(len(omino_set)*5): for triangle in baseTriangles: triangles.append((triangle[0]+8*i,triangle[1]+8*i,triangle[2]+8*i)) sideLength = 7 bevelWidth = .2 bevelHeight = .2 for ominoIndex, coord in omino_set: omino = list(ominos)[ominoIndex] for tile in omino: bevelSides = [] for x in [-1,0,1]: for y in [y for y in [-1,0,1] if abs(x)+abs(y)==1]: if not (tile[0]+x,tile[1]+y) in omino: bevelSides.append((x,y)) for x,y in [(0,0),(0,1),(1,1),(1,0)]: vertices.append((x+coord[0]+tile[0],y+coord[1]+tile[1],0)) for x,y in [(0,0),(0,1),(1,1),(1,0)]: xOffset = 0 yOffset = 0 if x == 0: if (-1,0) in bevelSides: xOffset = bevelWidth elif (1,0) in bevelSides: xOffset = -bevelWidth if y == 0: if (0,-1) in bevelSides: yOffset = bevelWidth elif (0,1) in bevelSides: yOffset = -bevelWidth if xOffset == 0 and yOffset == 0: if not (tile[0]+[-1,1][x],tile[1]+[-1,1][y]) in omino: xOffset = [1,-1][x]*bevelWidth yOffset = [1,-1][y]*bevelWidth vertices.append((x+xOffset+coord[0]+tile[0],y+yOffset+coord[1]+tile[1],bevelHeight)) for i,vertex in enumerate(vertices): vertices[i]=[vertex[0]*sideLength,vertex[1]*sideLength,vertex[2]] mesh = trimesh.Trimesh(vertices=vertices,faces=triangles) mesh.export("test.stl")
def mesh_from_logits(self, logits): logits = np.reshape(logits, (self.resolution,) * 3) # padding to ba able to retrieve object close to bounding box bondary logits = np.pad(logits, ((1, 1), (1, 1), (1, 1)), 'constant', constant_values=0) threshold = np.log(self.threshold) - np.log(1. - self.threshold) vertices, triangles = mcubes.marching_cubes( logits, threshold) # remove translation due to padding vertices -= 1 # rescale to original scale step = (self.max - self.min) / (self.resolution - 1) vertices = np.multiply(vertices, step) vertices += [self.min, self.min, self.min] return trimesh.Trimesh(vertices, triangles)
def vis_all(self, split, shuffle=False, learning_phase=0): import matplotlib.pyplot as plt tf.keras.backend.set_learning_phase(learning_phase) dataset = self.problem.get_base_dataset(split) if shuffle: dataset = dataset.shuffle(self.problem.shuffle_buffer) for image, label in dataset: label = label.numpy() vertices, faces, cloud = self(image) mesh = trimesh.Trimesh(vertices=vertices, faces=faces) scene = mesh.scene() scene.add_geometry(point_cloud(cloud, [0, 0, 255])) scene.add_geometry(point_cloud(label, [0, 255, 0])) image = image.numpy() image -= np.min(image) image /= np.max(image) plt.imshow(image) scene.show(background=(0, 0, 0, 0))
def generate_env(obj_index, out_path): # step 0: read file obj_index = str(obj_index).zfill(3) mesh = trimesh.load(os.path.join(obj_index, obj_index + '_coll.obj')) # step 1: create convex mesh vertices_lst = [] for m in mesh: vertices_lst.append(m.vertices) vertices_lst = np.vstack(vertices_lst) convex_mesh = trimesh.Trimesh(vertices=vertices_lst).convex_hull # step 2: write convex hull as stl file convex_mesh.export(os.path.join(obj_index, obj_index + '_coll.stl')) # step 3: record center of mass and box size convex_com = convex_mesh.center_mass half_length = convex_mesh.bounding_box_oriented.primitive.extents
def as_mesh(scene_or_mesh): """ Convert a possible scene to a mesh. If conversion occurs, the returned mesh has only vertex and face data. """ if isinstance(scene_or_mesh, trimesh.Scene): if len(scene_or_mesh.geometry) == 0: mesh = None # empty scene else: # we lose texture information here mesh = trimesh.util.concatenate( tuple( trimesh.Trimesh(vertices=g.vertices, faces=g.faces) for g in scene_or_mesh.geometry.values())) else: # assert(isinstance(mesh, trimesh.Trimesh)) mesh = scene_or_mesh return mesh
def generate_tetrahedral_hollowed_mesh(self, mesh, density, grid=None, thresh=0.25): # density in points per square unit, # Does the whole generation process. If grid is None, generates a random one extents = mesh.bounding_box.extents center = mesh.bounds.mean(axis=0) if grid is not None: self.set_grid(grid, thresh, extents, density, center) else: self.generate_random(thresh, extents, density, center) self.clear_close_points(mesh, thresh) self.march() hollow = trimesh.Trimesh(vertices=self.vertices, faces=self.tris) verts, tets = generate_dual_tetrahedrons(mesh, hollow) new_volume = mesh.volume - hollow.volume return verts, tets, new_volume
def to_mesh(self, color=colors['red']): v = np.array([[-1., -1., -1.], [-1., -1., 1.], [-1., 1., 1.], [-1., 1., -1.], [-1., 1., -1.], [-1., 1., 1.], [1., 1., 1.], [1., 1., -1.], [1., 1., -1.], [1., 1., 1.], [1., -1., 1.], [1., -1., -1.], [-1., -1., 1.], [-1., -1., -1.], [1., -1., -1.], [1., -1., 1.], [1., -1., -1.], [-1., -1., -1.], [-1., 1., -1.], [1., 1., -1.], [1., 1., 1.], [-1., 1., 1.], [-1., -1., 1.], [1., -1., 1.]]) f = np.array([[0, 1, 2], [0, 2, 3], [4, 5, 6], [4, 6, 7], [8, 9, 10], [8, 10, 11], [12, 13, 14], [12, 14, 15], [16, 17, 18], [16, 18, 19], [20, 21, 22], [20, 22, 23]]) # return Mesh(v=v * self.radius + self.center, f=f, point_color=np.tile(color, (v.shape[0], 1))) return trimesh.Trimesh(vertices=v * self.radius + self.center, faces=f, vertex_colors=np.tile(color, (v.shape[0], 1)))
def color_mesh(mesh, mesh_col): # mesh_color = trimesh.visual.ColorVisuals(mesh, vertex_colors=color) # # mesh.visual = mesh_colore # mesh = trimesh.Trimesh(mesh.vertices, mesh.faces, visuals=mesh_color) # breakpoint() nverts = len(mesh.vertices) if len(mesh_col.shape) == 1: vertex_colors = mesh_col[None, ] * np.ones((nverts, 1)) else: vertex_colors = mesh_col * 1 trimesh.visual.color.ColorVisuals(mesh, vertex_colors=vertex_colors) mesh = trimesh.Trimesh(mesh.vertices, mesh.faces, vertex_colors=vertex_colors) return mesh, vertex_colors
def o3d2trimesh(mesh): ''' Takes o3d mesh and converts it to trimesh object ''' vertices = np.asarray(mesh.vertices) faces = np.asarray(mesh.triangles) face_normals = np.asarray(mesh.triangle_normals) vertex_normals = np.asarray(mesh.vertex_normals) vertex_colors = np.asarray(mesh.vertex_colors) print(len(vertices), len(faces), len(face_normals), len(face_normals)) mesh = trimesh.Trimesh(vertices=vertices, faces=faces, face_normals=face_normals, vertex_normals=vertex_normals, vertex_colors=vertex_colors) #print(mesh) return mesh
def mesh_to_grid(mesh, pitch): # gridscale: ((min, max), (min, max), (min, max)) where each point i becomes i/i_size*(max-min) + min #scale mesh properly to match grid #iterate through all points in grid centers! # if point is inside the mesh, set grid corners to 1, 0 otherwise true_faces = [] for i in range(1, len(mesh.faces), 4): true_faces.append( [mesh.faces[i], mesh.faces[i + 1], mesh.faces[i + 2]]) tri_version = trimesh.Trimesh(mesh.points, true_faces) # TODO, pick the smallest cell size voxels = tri_version.voxelized(pitch) voxels.fill() mat = voxels.encoding.dense return np.array(mat, dtype=np.int)
def load_mesh(gii_file): """ load gifti_file and create a trimesh object :param gifti_file: str, path to the gifti file :return: the corresponding trimesh object """ g = nib.gifti.read(gii_file) vertices, faces = g.getArraysFromIntent( nib.nifti1.intent_codes['NIFTI_INTENT_POINTSET'])[0].data, \ g.getArraysFromIntent( nib.nifti1.intent_codes['NIFTI_INTENT_TRIANGLE'])[0].data metadata = g.get_meta().metadata metadata['filename'] = gii_file return trimesh.Trimesh(faces=faces, vertices=vertices, metadata=metadata, process=False)
def export_ply(self, ply_path): vertices = self.dims["shape"]["vals"] # this brings them into about the [-15, +15] range vertices /= 10_000 faces = self._tl - 1 colours = self.dims["tex"]["vals"] mesh = trimesh.Trimesh(vertices=vertices, faces=faces, vertex_colors=colours) mesh.invert() mesh.export(file_obj=ply_path)
def clean(input_mesh): """ This function remove faces, and vertex that doesn't belong to any face. Intended to be used before a feed forward pass in pointNet Input : mesh output : cleaned mesh """ print("cleaning ...") print("number of point before : ", np.shape(input_mesh.vertices)[0]) pts = input_mesh.vertices faces = input_mesh.faces faces = faces.reshape(-1) unique_points_index = np.unique(faces) unique_points = pts[unique_points_index] print("number of point after : ", np.shape(unique_points)[0]) mesh = trimesh.Trimesh(vertices=unique_points, faces=np.array([[0, 0, 0]]), process=False) return mesh