def load_sample(self, path): """Load and normalize a mesh." Arguments: path {string} -- path to mesh file. Returns: torch.Tensor -- Tensor containing vertices of shape. Size: `n_points x 3` """ verts, _ = read_mesh(path) return torch.Tensor(verts)
def create_pcd_dataset_from_mesh(fpath): mesh = utils.read_mesh(fpath) pcd = mesh.sample_points_poisson_disk(len(mesh.vertices), use_triangle_normal=True, seed=412) dpath = "/".join(fpath.split("/")[:-1]) fname = fpath.split("/")[-1] fname = "{}_pcd.ply".format(os.path.splitext(fname)[0]) fpath = os.path.join(dpath, fname) logger.info("PointCloud data ({}) is being created.".format(fpath)) utils.write_pcd(fpath, pcd)
def process(self): extract_zip(self.raw_paths[0], self.raw_dir, log=False) path = osp.join(self.raw_dir, 'MPI-FAUST', 'training', 'registrations') path = osp.join(path, 'tr_reg_{0:03d}.ply') data_list = [] for i in range(100): data = read_mesh(path.format(i)) data.y = torch.tensor([i % 10], dtype=torch.long) if self.pre_filter is not None and not self.pre_filter(data): continue if self.pre_transform is not None: data = self.pre_transform(data) data_list.append(data) torch.save(self.collate(data_list[:80]), self.processed_paths[0]) torch.save(self.collate(data_list[80:]), self.processed_paths[1]) shutil.rmtree(osp.join(self.raw_dir, 'MPI-FAUST'))
def __getitem__(self, index): shape = self.shape_list[index] num_verts, num_edge, num_faces, points, faces = utils.read_mesh( shape['mesh']) # print(shape['shape_name']) feature = np.array(points) label = shape['label'] adj = np.eye(num_verts) for _i in range(num_faces): adj[faces[_i][1], faces[_i][2]], adj[faces[_i][2], faces[_i][1]] = 1, 1 adj[faces[_i][1], faces[_i][3]], adj[faces[_i][3], faces[_i][1]] = 1, 1 adj[faces[_i][2], faces[_i][3]], adj[faces[_i][3], faces[_i][2]] = 1, 1 feature = self.normalize_ft(feature) adj = self.normalize_adj(adj) return torch.Tensor(feature), torch.Tensor(adj), torch.Tensor( [label]).long()
def main(args): # Context ctx = get_extension_context("cudnn", device_id=args.device_id) nn.set_default_context(ctx) # Dataset (input is normalized in [-1, 1]) ds = point_cloud_data_source(args.fpath, knn=-1, test=True) pts_true = ds.points # Sample from mesh (unnormalized) mesh = utils.read_mesh(args.mesh_data_path) pcd = mesh.sample_points_poisson_disk(ds.size, seed=412) pts_pred = np.asarray(pcd.points) pts_pred = utils.normalize(pts_pred) # Pair-wise distance cd0, cd1, cd, hd0, hd1, hd = utils.chamfer_hausdorff_dists( pts_pred, pts_true) # Chamfer distance print("----- Chamfer distance -----") log = """ One-sided Chamfer distance (Pred, True): {} One-sided Chamfer distance (True, Pred): {} Chamfer distance: {} """.format(cd0, cd1, cd) print(log) # Hausdorff distance print("----- Hausdorff distance -----") log = """ One-sided Hausdorff distance (Pred, True): {} One-sided Hausdorff distance (True, Pred): {} Hausdorff distance: {} """.format(hd0, hd1, hd) print(log)
def trans_std_file(src_filename, des_filename): num_verts, num_edge, num_faces, points, faces = utils.read_mesh( src_filename) utils.write_mesh(des_filename, num_verts, num_edge, num_faces, points, faces)
def main(): parser = argparse.ArgumentParser() parser.add_argument('model_weights_path', type=str, help='path to the model checkpoint') parser.add_argument('input_path', type=str, help='path to the input') parser.add_argument('--disable_cuda', action='store_true', help='disable cuda') parser.add_argument('--sample_cloud', type=int, help='run on sampled points') parser.add_argument('--n_rounds', type=int, default=5, help='number of rounds') parser.add_argument('--prob_thresh', type=float, default=.9, help='threshold for final surface') parser.add_argument( '--output', type=str, help='path to save the resulting high prob mesh to. also disables viz') parser.add_argument('--output_trim_unused', action='store_true', help='trim unused vertices when outputting') # Parse arguments args = parser.parse_args() set_args_defaults(args) viz = not args.output args.polyscope = False # Initialize polyscope if viz: polyscope.init() # === Load the input if args.input_path.endswith(".npz"): record = np.load(args.input_path) verts = torch.tensor(record['vert_pos'], dtype=args.dtype, device=args.device) surf_samples = torch.tensor(record['surf_pos'], dtype=args.dtype, device=args.device) samples = verts.clone() faces = torch.zeros((0, 3), dtype=torch.int64, device=args.device) polyscope.register_point_cloud("surf samples", toNP(surf_samples)) if args.input_path.endswith(".xyz"): raw_pts = np.loadtxt(args.input_path) verts = torch.tensor(raw_pts, dtype=args.dtype, device=args.device) samples = verts.clone() faces = torch.zeros((0, 3), dtype=torch.int64, device=args.device) polyscope.register_point_cloud("surf samples", toNP(verts)) else: print("reading mesh") verts, faces = utils.read_mesh(args.input_path) print(" {} verts {} faces".format(verts.shape[0], faces.shape[0])) verts = torch.tensor(verts, dtype=args.dtype, device=args.device) faces = torch.tensor(faces, dtype=torch.long, device=args.device) # verts = verts[::10,:] if args.sample_cloud: samples = mesh_utils.sample_points_on_surface( verts, faces, args.sample_cloud) else: samples = verts.clone() # === Load the model print("loading model weights") model = PointTriNet_Mesher() model.load_state_dict(torch.load(args.model_weights_path)) model.eval() with torch.no_grad(): # Sample lots of faces from the vertices print("predicting") candidate_triangles, candidate_probs = model.predict_mesh( samples.unsqueeze(0), n_rounds=args.n_rounds) candidate_triangles = candidate_triangles.squeeze(0) candidate_probs = candidate_probs.squeeze(0) print("done predicting") # Visualize high_prob = args.prob_thresh high_faces = candidate_triangles[candidate_probs > high_prob] closed_faces = mesh_utils.fill_holes_greedy(high_faces) if viz: polyscope.register_point_cloud("input points", toNP(samples)) spmesh = polyscope.register_surface_mesh("all faces", toNP(samples), toNP(candidate_triangles), enabled=False) spmesh.add_scalar_quantity("probs", toNP(candidate_probs), defined_on='faces') spmesh = polyscope.register_surface_mesh( "high prob mesh " + str(high_prob), toNP(samples), toNP(high_faces)) spmesh.add_scalar_quantity( "probs", toNP(candidate_probs[candidate_probs > high_prob]), defined_on='faces') spmesh = polyscope.register_surface_mesh("hole-closed mesh " + str(high_prob), toNP(samples), toNP(closed_faces), enabled=False) polyscope.show() # Save output if args.output: high_prob = args.prob_thresh out_verts = toNP(samples) out_faces = toNP(high_faces) out_faces_closed = toNP(closed_faces) if args.output_trim_unused: out_verts, out_faces, _, _ = igl.remove_unreferenced( out_verts, out_faces) igl.write_triangle_mesh(args.output + "_mesh.ply", out_verts, out_faces) write_ply_points(args.output + "_samples.ply", toNP(samples)) igl.write_triangle_mesh(args.output + "_pred_mesh.ply", out_verts, out_faces) igl.write_triangle_mesh(args.output + "_pred_mesh_closed.ply", out_verts, out_faces_closed) write_ply_points(args.output + "_samples.ply", toNP(samples))