Пример #1
0
 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)
Пример #2
0
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)
Пример #3
0
    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'))
Пример #4
0
 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()
Пример #5
0
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)
Пример #6
0
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))