def iou_pymesh(mesh_src, mesh_pred, dim=FLAGS.dim): try: mesh1 = pymesh.load_mesh(mesh_src) grid1 = pymesh.VoxelGrid(2. / dim) grid1.insert_mesh(mesh1) grid1.create_grid() ind1 = ((grid1.mesh.vertices + 1.1) / 2.4 * dim).astype(np.int) v1 = np.zeros([dim, dim, dim]) v1[ind1[:, 0], ind1[:, 1], ind1[:, 2]] = 1 mesh2 = pymesh.load_mesh(mesh_pred) grid2 = pymesh.VoxelGrid(2. / dim) grid2.insert_mesh(mesh2) grid2.create_grid() ind2 = ((grid2.mesh.vertices + 1.1) / 2.4 * dim).astype(np.int) v2 = np.zeros([dim, dim, dim]) v2[ind2[:, 0], ind2[:, 1], ind2[:, 2]] = 1 intersection = np.sum(np.logical_and(v1, v2)) union = np.sum(np.logical_or(v1, v2)) return [float(intersection) / union, mesh_pred] except: print("error mesh {} / {}".format(mesh_src, mesh_pred))
def iou_pymesh(mesh1, mesh2, dim=110): # mesh1 = (vertices1, triangles1) # mesh2 = (vertices2, triangles2) mesh1 = pymesh.form_mesh(mesh1[0], mesh1[1]) grid1 = pymesh.VoxelGrid(2. / dim) grid1.insert_mesh(mesh1) grid1.create_grid() ind1 = ((grid1.mesh.vertices + 1.1) / 2.4 * dim).astype(np.int) v1 = np.zeros([dim, dim, dim]) v1[ind1[:, 0], ind1[:, 1], ind1[:, 2]] = 1 mesh2 = pymesh.form_mesh(mesh2[0], mesh2[1]) grid2 = pymesh.VoxelGrid(2. / dim) grid2.insert_mesh(mesh2) grid2.create_grid() ind2 = ((grid2.mesh.vertices + 1.1) / 2.4 * dim).astype(np.int) v2 = np.zeros([dim, dim, dim]) v2[ind2[:, 0], ind2[:, 1], ind2[:, 2]] = 1 intersection = np.sum(np.logical_and(v1, v2)) union = np.sum(np.logical_or(v1, v2)) return float(intersection) / union
def main(): args = parse_args() mesh = pymesh.load_mesh(args.input_mesh) grid = pymesh.VoxelGrid(args.cell_size, mesh.dim) grid.insert_mesh(mesh) out_mesh = grid.mesh pymesh.save_mesh(args.output_mesh, out_mesh)
def voxelize_mesh(): mesh = load_mesh("models/cube.obj") grid = pymesh.VoxelGrid(0.05, mesh.dim) grid.insert_mesh(mesh) grid.create_grid() out_mesh = grid.mesh centers = np.mean(out_mesh.vertices[out_mesh.elements], axis=1) np.save("models/voxels.npy", centers) visualize_cloud(centers)
def main(): args = parse_args() mesh = pymesh.load_mesh(args.input_mesh) grid = pymesh.VoxelGrid(args.cell_size, mesh.dim) grid.insert_mesh(mesh) grid.create_grid() grid.dilate(args.dilate) grid.erode(args.erode) out_mesh = grid.mesh pymesh.save_mesh(args.output_mesh, out_mesh)
def process_obj(obj_file, dir_in, dir_out, grid_size, max_faces, make_convex=False, fit_cylinder=False, quality='low'): mesh_path = join(dir_in, obj_file) print('---------------------------------------------------------------------------') print('Processing: ' + obj_file) print('---------------------------------------------------------------------------') # load the mesh print('Loading mesh...') mesh = pymesh.load_mesh(mesh_path) print('Mesh verts: ' + str(mesh.vertices.shape)) print('Mesh faces: ' + str(mesh.faces.shape)) # filter out those that have too many faces if (mesh.faces.shape[0] > max_faces): print('Over max faces...continuing to next shape!') return # cleanup surf_mesh = mesh if make_convex: # first tet to get just outer surface print('Tetrahedralizing mesh...') tetgen = pymesh.tetgen() tetgen.points = mesh.vertices; # Input points tetgen.triangles = np.empty(0) tetgen.verbosity = 0 tetgen.run(); # Execute tetgen surf_mesh = tetgen.mesh elif fit_cylinder: # same top and bottom radius # want to center around origin # first find radius (max of all x and z) # print (mesh.bbox) # print(mesh.bbox[0][0]) cyl_rad = max([abs(mesh.bbox[0][0]), abs(mesh.bbox[1][0]), abs(mesh.bbox[0][2]), abs(mesh.bbox[1][2])]) # find height max y - min y cyl_half_height = (mesh.bbox[1][1] - mesh.bbox[0][1]) / 2.0 surf_mesh = pymesh.generate_cylinder(np.array([0, -cyl_half_height, 0]), np.array([0, cyl_half_height, 0]), cyl_rad, cyl_rad) # print('Tet verts: ' + str(tet_mesh.vertices.shape)) # print('Tet faces: ' + str(tet_mesh.faces.shape)) # remesh to improve vertex distribution for moment calculation # print('Remeshing...') # surf_mesh = tet_mesh #fix_mesh(tet_mesh, quality) print('Surface verts: ' + str(surf_mesh.vertices.shape)) print('Surface faces: ' + str(surf_mesh.faces.shape)) # voxelize to find volume print('Voxelizing...') grid = pymesh.VoxelGrid(grid_size, surf_mesh.dim) grid.insert_mesh(surf_mesh) grid.create_grid() vox_mesh = grid.mesh # save sim information # the number of voxels will be used for the volume (mass) num_voxels = vox_mesh.voxels.shape[0] vol = num_voxels * grid_size*grid_size*grid_size # move mesh to true COM based on voxelization (centroid of the center of all voxels) centroid = np.array([0., 0., 0.]) for i in range(0, num_voxels): # find average position of all vertices defining voxel vox_pos = np.mean(vox_mesh.vertices[vox_mesh.voxels[i], :], axis=0) centroid += vox_pos centroid /= num_voxels print('Centroid: (%f, %f, %f)' % (centroid[0], centroid[1], centroid[2])) centroid_vox_mesh = pymesh.form_mesh(vox_mesh.vertices - np.reshape(centroid, (1, -1)), vox_mesh.faces, vox_mesh.voxels) centroid_surf_mesh = pymesh.form_mesh(surf_mesh.vertices - np.reshape(centroid, (1, -1)), surf_mesh.faces) # also calculate moment of inertia around principal axes for a DENSITY of 1 (mass = volume) inertia = np.array([0., 0., 0.]) point_mass = vol / float(num_voxels) print('Point mass: %f' % (point_mass)) for i in range(0, num_voxels): # find average position of all vertices defining voxel vox_pos = np.mean(centroid_vox_mesh.vertices[centroid_vox_mesh.voxels[i], :], axis=0) x2 = vox_pos[0]*vox_pos[0] y2 = vox_pos[1]*vox_pos[1] z2 = vox_pos[2]*vox_pos[2] # inertia += np.array([point_mass*(y2+z2),point_mass*(x2+z2),point_mass*(x2+y2)]) inertia += np.array([x2*point_mass,y2*point_mass,z2*point_mass]) print('Num voxels: ' + str(num_voxels)) print('Volume: ' + str(vol)) print('Moment of inertia: (%f, %f, %f)' % (inertia[0], inertia[1], inertia[2])) json_dict = {'num_vox' : num_voxels, 'vol' : vol, 'inertia' : inertia.tolist()} json_out_path = join(dir_out, obj_file.replace('.obj', '.json')) with open(json_out_path, 'w') as outfile: json_str = json.dump(json_dict, outfile) # save surface mesh mesh_out_path = join(dir_out, obj_file) pymesh.save_mesh(mesh_out_path, centroid_surf_mesh) # sample point cloud on surface mesh print('Sampling point cloud...') points_out_path = join(dir_out, obj_file.replace('.obj', '.pts')) subprocess.check_output(['./MeshSample', '-n1024', '-s3', mesh_out_path, points_out_path])