def get_normalize_mesh(model_file, norm_mesh_sub_dir):
    total = 16384
    print("trimesh_load:", model_file)
    mesh_list = trimesh.load_mesh(model_file, process=False)
    if not isinstance(mesh_list, list):
        mesh_list = [mesh_list]
    area_sum = 0
    area_lst = []
    for idx, mesh in enumerate(mesh_list):
        area = np.sum(mesh.area_faces)
        area_lst.append(area)
        area_sum += area
    area_lst = np.asarray(area_lst)
    amount_lst = (area_lst * total / area_sum).astype(np.int32)
    points_all = np.zeros((0, 3), dtype=np.float32)
    for i in range(amount_lst.shape[0]):
        mesh = mesh_list[i]
        print("start sample surface of ", mesh.faces.shape[0])
        points, index = trimesh.sample.sample_surface(mesh, amount_lst[i])
        print("end sample surface")
        points_all = np.concatenate([points_all, points], axis=0)
    centroid = np.mean(points_all, axis=0)
    points_all = points_all - centroid
    m = np.max(np.sqrt(np.sum(points_all**2, axis=1)))
    obj_file = os.path.join(norm_mesh_sub_dir, "pc_norm.obj")
    ori_mesh = pymesh.load_mesh(model_file)
    print("centroid, m", centroid, m)
    pymesh.save_mesh_raw(obj_file, (ori_mesh.vertices - centroid) / float(m),
                         ori_mesh.faces)
    print("export_mesh", obj_file)
    return obj_file, centroid, m
Exemplo n.º 2
0
def separate_single_mesh(src_mesh, tar_mesh):
    src_mesh = pymesh.load_mesh(src_mesh)
    dis_meshes = pymesh.separate_mesh(src_mesh, connectivity_type='auto')
    pymesh.save_mesh_raw(tar_mesh+".obj", src_mesh.vertices, src_mesh.faces)
    count=0
    for dis_mesh in dis_meshes:
        print("dis_mesh.vertices.shape",dis_mesh.vertices.shape)
        print("dis_mesh.faces.shape",dis_mesh.faces.shape)
        pymesh.save_mesh_raw(tar_mesh+"_"+str(count)+".obj", dis_mesh.vertices, dis_mesh.faces)
        count+=1
Exemplo n.º 3
0
def test_one(opt, cage_shape, new_source, new_source_face, new_target, new_target_face):
    states = torch.load(opt.ckpt)
    if "states" in states:
        states = states["states"]

    pymesh.save_mesh_raw(os.path.join(opt.log_dir, opt.subdir, "template-initial.ply"),
                         states["source_vertices"][0].transpose(
                             0, 1).detach().cpu(),
                         states["source_faces"][0].detach().cpu())

    # states["template_vertices"] = cage_shape.transpose(1, 2)
    # states["source_vertices"] = new_source.transpose(1, 2)
    # states["source_faces"] = new_source_face

    pymesh.save_mesh_raw(os.path.join(opt.log_dir, opt.subdir, "template-Sa.ply"),
                         new_source[0].detach().cpu(), new_source_face[0].detach().cpu())
    pymesh.save_mesh_raw(os.path.join(opt.log_dir, opt.subdir, "template-Sb.ply"),
                         new_target[0].detach().cpu(), new_target_face[0].detach().cpu())

    net = networks.FixedSourceDeformer(opt, 3, opt.num_point, bottleneck_size=512,
                                       template_vertices=cage_shape.transpose(1, 2), template_faces=states["template_faces"].cuda(),
                                       source_vertices=new_source.transpose(1, 2), source_faces=new_source_face).cuda()

    net.eval()
    load_network(net, states)

    outputs = net(new_target.transpose(1, 2).contiguous())
    deformed = outputs["deformed"]

    pymesh.save_mesh_raw(os.path.join(opt.log_dir, opt.subdir, "template-Sab.ply"),
                         deformed[0].detach().cpu(), new_target_face[0].detach().cpu())
Exemplo n.º 4
0
def main():
    args = parse_args();
    mesh = pymesh.load_mesh(args.input_mesh);
    offset = np.array(args.offset);
    axis = np.array(args.rotation_axis);
    angle = math.radians(args.rotation_angle);
    rot = pymesh.Quaternion.fromAxisAngle(axis, angle);
    rot = rot.to_matrix();

    vertices = mesh.vertices;
    bbox = mesh.bbox;
    centroid = 0.5 * (bbox[0] + bbox[1]);
    vertices = np.dot(rot, (vertices - centroid).T).T + centroid + offset;

    pymesh.save_mesh_raw(args.output_mesh, vertices, mesh.faces, mesh.voxels);
Exemplo n.º 5
0
def main():
    args = parse_args()
    mesh = pymesh.load_mesh(args.input_mesh)
    offset = np.array(args.offset)
    axis = np.array(args.rotation_axis)
    angle = math.radians(args.rotation_angle)
    rot = pymesh.Quaternion.fromAxisAngle(axis, angle)
    rot = rot.to_matrix()

    vertices = mesh.vertices
    bbox = mesh.bbox
    centroid = 0.5 * (bbox[0] + bbox[1])
    vertices = np.dot(rot, (vertices - centroid).T).T + centroid + offset

    pymesh.save_mesh_raw(args.output_mesh, vertices, mesh.faces, mesh.voxels)
Exemplo n.º 6
0
def clean_single_mesh(src_mesh, tar_mesh, dist_thresh, num_thresh):
    src_mesh_obj = pymesh.load_mesh(src_mesh)
    dis_meshes = pymesh.separate_mesh(src_mesh_obj, connectivity_type='auto')
    max_mesh_verts = 0
    for dis_mesh in dis_meshes:
       if dis_mesh.vertices.shape[0] > max_mesh_verts:
           max_mesh_verts = dis_mesh.vertices.shape[0]

    collection=[]
    for dis_mesh in dis_meshes:
       if dis_mesh.vertices.shape[0] > max_mesh_verts*num_thresh:
           centroid = np.mean(dis_mesh.vertices, axis=0)
           if np.sqrt(np.sum(np.square(centroid))) < dist_thresh:
            collection.append(dis_mesh)
    tar_mesh_obj = pymesh.merge_meshes(collection)
    pymesh.save_mesh_raw(tar_mesh, tar_mesh_obj.vertices, tar_mesh_obj.faces)
    print("threshes:", str(dist_thresh), str(num_thresh), " clean: ", src_mesh, " create: ",tar_mesh)
Exemplo n.º 7
0
def run(in_files, out_dir, ref_file):
    ref_v, ref_f = read_trimesh(ref_file)
    ref_v = torch.from_numpy(ref_v[:, :3]).float()
    ref_f = torch.from_numpy(ref_f).long()
    _, ref_area = compute_face_normals_and_areas(ref_v, ref_f)
    ref_area = torch.sum(ref_area, dim=-1)
    for in_file in in_files:
        v, f = read_trimesh(in_file)
        v = torch.from_numpy(v[:, :3]).float()
        f = torch.from_numpy(f).long()
        v, _, _ = center_bounding_box(v)
        _, area = compute_face_normals_and_areas(v, f)
        area = torch.sum(area, dim=-1)
        ratio = torch.sqrt(ref_area/area)
        ratio = ratio.unsqueeze(-1).unsqueeze(-1)
        v = v * ratio
        out_path = os.path.join(out_dir, os.path.basename(in_file))
        pymesh.save_mesh_raw(out_path, v.numpy(), f.numpy())
        print("saved to {}".format(out_path))
Exemplo n.º 8
0
def get_normalize_mesh(model_dir, norm_mesh_sub_dir, target_dir):
    norm_file = os.path.join(norm_mesh_sub_dir, "pc_norm.obj")
    target_norm_file = os.path.join(target_dir, "pc_norm.obj")
    command_str = "cp " + norm_file + " " + target_norm_file
    print("command:", command_str)
    os.system(command_str)

    model_obj = os.path.join(model_dir, "model.obj")
    target_model_obj = os.path.join(target_dir, "model.obj")
    params = np.loadtxt(os.path.join(norm_mesh_sub_dir, "pc_norm.txt"))
    print("trimesh_load:", model_obj)

    centroid = params[:3]
    m = params[3]
    print("centroid, m", centroid, m)

    ori_mesh = pymesh.load_mesh(model_obj)
    verts = (ori_mesh.vertices - centroid) / float(m)
    pymesh.save_mesh_raw(target_model_obj, verts, ori_mesh.faces)
Exemplo n.º 9
0
def train():
    dataset = build_dataset(opt)
    dataloader = torch.utils.data.DataLoader(
        dataset,
        batch_size=opt.batch_size,
        shuffle=True,
        drop_last=True,
        num_workers=0,
        worker_init_fn=lambda id: np.random.seed(np.random.get_state()[1][0] +
                                                 id))
    source_shape = dataset.mesh_vertex.unsqueeze(0).to(dtype=torch.float)
    source_face = dataset.mesh_face.unsqueeze(0)
    cage_shape = dataset.cage_vertex.unsqueeze(0).to(dtype=torch.float)
    cage_face = dataset.cage_face.unsqueeze(0)
    mesh = Mesh(vertices=cage_shape[0], faces=cage_face[0])
    build_gemm(mesh, cage_face[0])
    cage_edge_points = torch.from_numpy(get_edge_points(mesh)).cuda()
    cage_edges = edge_vertex_indices(cage_face[0])

    # network
    net = networks.FixedSourceDeformer(
        opt,
        3,
        opt.num_point,
        bottleneck_size=opt.bottleneck_size,
        template_vertices=cage_shape.transpose(1, 2),
        template_faces=cage_face,
        source_vertices=source_shape.transpose(1, 2),
        source_faces=source_face).cuda()
    print(net)
    net.apply(weights_init)
    if opt.ckpt:
        load_network(net, opt.ckpt)
    net.train()

    all_losses = losses.AllLosses(opt)

    # optimizer
    optimizer = torch.optim.Adam([{
        'params': net.nd_decoder.parameters()
    }, {
        "params": net.encoder.parameters()
    }],
                                 lr=opt.lr)

    # train
    os.makedirs(opt.log_dir, exist_ok=True)
    shutil.copy2(__file__, opt.log_dir)
    shutil.copy2(os.path.join(os.path.dirname(__file__), "network2.py"),
                 opt.log_dir)
    shutil.copy2(os.path.join(os.path.dirname(__file__), "common.py"),
                 opt.log_dir)
    shutil.copy2(os.path.join(os.path.dirname(__file__), "losses.py"),
                 opt.log_dir)
    shutil.copy2(os.path.join(os.path.dirname(__file__), "datasets.py"),
                 opt.log_dir)
    pymesh.save_mesh_raw(
        os.path.join(opt.log_dir, "t{:06d}_Sa.ply".format(0)),
        net.source_vertices[0].transpose(0, 1).detach().cpu().numpy(),
        net.source_faces[0].detach().cpu())
    pymesh.save_mesh_raw(
        os.path.join(opt.log_dir, "t{:06d}_template.ply".format(0)),
        net.template_vertices[0].transpose(0, 1).detach().cpu().numpy(),
        net.template_faces[0].detach().cpu())

    scheduler = torch.optim.lr_scheduler.StepLR(optimizer,
                                                max(int(opt.nepochs * 0.75),
                                                    1),
                                                gamma=0.5,
                                                last_epoch=-1)

    # train
    net.train()
    t = 0
    start_epoch = 0
    warmed_up = False
    mvc_weight = opt.mvc_weight
    opt.mvc_weight = 0

    os.makedirs(opt.log_dir, exist_ok=True)
    running_avg_loss = -1
    log_file = open(os.path.join(opt.log_dir, "loss_log.txt"), "a")
    log_interval = min(max(len(dataloader) // 5, 50), 200)
    save_interval = max(opt.nepochs // 10, 1)

    with torch.autograd.detect_anomaly():
        if opt.epoch:
            start_epoch = opt.epoch % opt.nepochs
            t += start_epoch * len(dataloader)

        for epoch in range(start_epoch, opt.nepochs):
            for epoch_t, data in enumerate(dataloader):
                progress = epoch_t / len(dataloader) + epoch
                warming_up = progress < opt.warmup_epochs
                if (opt.deform_template or opt.optimize_template) and (
                        progress >= opt.warmup_epochs) and (not warmed_up):
                    if opt.deform_template:
                        optimizer.add_param_group({
                            'params':
                            net.nc_decoder.parameters(),
                            'lr':
                            0.1 * opt.lr
                        })
                    if opt.optimize_template:
                        optimizer.add_param_group({
                            'params': net.template_vertices,
                            'lr': 0.1 * opt.lr
                        })
                    warmed_up = True
                    # start to compute mvc weight
                    opt.mvc_weight = mvc_weight
                    save_network(net,
                                 opt.log_dir,
                                 network_label="net",
                                 epoch_label="warmed_up")

                ############# get data ###########
                data = dataset.uncollate(data)
                data["cage_edge_points"] = cage_edge_points
                data["cage_edges"] = cage_edges
                data["source_shape"] = net.source_vertices.detach()
                data["source_face"] = net.source_faces.detach()

                ############# run network ###########
                optimizer.zero_grad()
                target_shape_t = data["target_shape"].transpose(1, 2)
                sample_idx = None

                if "sample_idx" in data:
                    sample_idx = data["sample_idx"]
                    if data["source_normals"] is not None:
                        data["source_normals"] = torch.gather(
                            data["source_normals"], 1,
                            sample_idx.unsqueeze(-1).expand(-1, -1, 3))

                outputs = net(target_shape_t, sample_idx)
                if opt.sfnormal_weight > 0 and ("source_mesh" in data
                                                and "source_mesh" is not None):
                    if outputs["deformed"].shape[1] == data[
                            "source_mesh"].shape[1]:
                        outputs["deformed_hr"] = outputs["deformed"]
                    else:
                        outputs["deformed_hr"] = deform_with_MVC(
                            outputs["cage"].expand(
                                data["source_mesh"].shape[0], -1, -1).detach(),
                            outputs["new_cage"], outputs["cage_face"].expand(
                                data["source_mesh"].shape[0], -1,
                                -1), data["source_mesh"])
                data["source_shape"] = outputs["source_shape"]

                ############# get losses ###########
                current_loss = all_losses(data, outputs, progress)
                loss_sum = torch.sum(
                    torch.stack([v for v in current_loss.values()], dim=0))
                if running_avg_loss < 0:
                    running_avg_loss = loss_sum
                else:
                    running_avg_loss = running_avg_loss + (
                        loss_sum.item() - running_avg_loss) / (t + 1)

                if (t % log_interval
                        == 0) or (loss_sum > 10 * running_avg_loss):
                    log_str = "warming up {} e {:03d} t {:05d}: {}".format(
                        not warmed_up, epoch, t, ", ".join([
                            "{} {:.3g}".format(k,
                                               v.mean().item())
                            for k, v in current_loss.items()
                        ]))
                    print(log_str)
                    log_file.write(log_str + "\n")
                    log_outputs(opt, t, outputs, data)
                    # save_ply(data["target_shape"][0].detach().cpu().numpy(), os.path.join(opt.log_dir,"step-{:06d}-Sb.ply".format(t)))
                    # save_ply(outputs["deformed"][0].detach().cpu().numpy(), os.path.join(opt.log_dir,"step-{:06d}-Sab.ply".format(t)))
                    # write_trimesh(os.path.join(opt.log_dir, "step-{:06d}-cage1.ply".format(t)),
                    #               outputs["cage"][0].detach().cpu(), outputs["cage_face"][0].detach().cpu(), binary=True)
                    # write_trimesh(os.path.join(opt.log_dir, "step-{:06d}-cage2.ply".format(t)),
                    #               outputs["new_cage"][0].detach().cpu(), outputs["cage_face"][0].detach().cpu(), binary=True)

                if loss_sum > 100 * running_avg_loss:
                    logger.info(
                        "loss ({}) > 10*running_average_loss ({}). Skip without update."
                        .format(loss_sum, 5 * running_avg_loss))
                    torch.cuda.empty_cache()
                    continue

                loss_sum.backward()

                if opt.alternate_cd:
                    optimize_C = (progress > opt.warmup_epochs) and (
                        t % (opt.c_step + opt.d_step)) > opt.d_step
                    if optimize_C:
                        net.nd_decoder.zero_grad()
                        net.encoder.zero_grad()
                    else:
                        try:
                            net.nc_decoder.zero_grad()
                        except AttributeError:
                            net.template_vertices.grad.zero_()

                # clamp_gradient_norm(net, 1)
                optimizer.step()
                if (t + 1) % 500 == 0:
                    save_network(net,
                                 opt.log_dir,
                                 network_label="net",
                                 epoch_label="latest")

                t += 1

            if (epoch + 1) % save_interval == 0:
                save_network(net,
                             opt.log_dir,
                             network_label="net",
                             epoch_label=epoch)

            scheduler.step()

    log_file.close()
    save_network(net, opt.log_dir, network_label="net", epoch_label="final")
    test_all(net=net)
Exemplo n.º 10
0
def test(net=None, subdir="test"):
    opt.phase = "test"
    if isinstance(opt.target_model, str):
        opt.target_model = [opt.target_model]

    if net is None:
        states = torch.load(opt.ckpt)
        if "states" in states:
            states = states["states"]
        if opt.template:
            cage_shape, cage_face = read_trimesh(opt.template)
            cage_shape = torch.from_numpy(
                cage_shape[:, :3]).unsqueeze(0).float()
            cage_face = torch.from_numpy(cage_face).unsqueeze(0).long()
            states["template_vertices"] = cage_shape.transpose(1, 2)
            states["template_faces"] = cage_face

        if opt.source_model:
            source_shape, source_face = read_trimesh(opt.source_model)
            source_shape = torch.from_numpy(
                source_shape[:, :3]).unsqueeze(0).float()
            source_face = torch.from_numpy(source_face).unsqueeze(0).long()
            states["source_vertices"] = source_shape.transpose(1, 2)
            states["source_faces"] = source_shape

        net = networks.FixedSourceDeformer(
            opt,
            3,
            opt.num_point,
            bottleneck_size=opt.bottleneck_size,
            template_vertices=states["template_vertices"],
            template_faces=states["template_faces"],
            source_vertices=states["source_vertices"],
            source_faces=states["source_faces"]).cuda()

        load_network(net, states)
        net = net.cuda()
        net.eval()
    else:
        net.eval()

    print(net)

    test_output_dir = os.path.join(opt.log_dir, subdir)
    os.makedirs(test_output_dir, exist_ok=True)
    with torch.no_grad():
        for target_model in opt.target_model:
            assert (os.path.isfile(target_model))
            target_face = None
            target_shape, target_face = read_trimesh(target_model)
            # target_shape = read_ply(target_model)[:,:3]
            # target_shape, _, scale = normalize_to_box(target_shape)
            # normalize acording to height y axis
            # target_shape = target_shape/2*1.7
            target_shape = torch.from_numpy(
                target_shape[:, :3]).cuda().float().unsqueeze(0)
            if target_face is None:
                target_face = net.source_faces
            else:
                target_face = torch.from_numpy(
                    target_face).cuda().long().unsqueeze(0)
            t_filename = os.path.splitext(os.path.basename(target_model))[0]

            source_mesh = net.source_vertices.transpose(1, 2).detach()
            source_face = net.source_faces.detach()

            # furthest sampling
            target_shape_sampled = furthest_point_sample(
                target_shape, net.source_vertices.shape[2], NCHW=False)[1]
            # target_shape_sampled = (target_shape[:, np.random.permutation(target_shape.shape[1]), :]).contiguous()
            outputs = net(target_shape_sampled.transpose(1, 2),
                          None,
                          cage_only=True)
            # deformed = outputs["deformed"]

            deformed = deform_with_MVC(
                outputs["cage"], outputs["new_cage"],
                outputs["cage_face"].expand(outputs["cage"].shape[0], -1,
                                            -1), source_mesh)

            b = 0

            save_ply(
                target_shape_sampled[b].cpu().numpy(),
                os.path.join(opt.log_dir, subdir,
                             "template-{}-Sb.pts".format(t_filename)))
            pymesh.save_mesh_raw(
                os.path.join(opt.log_dir, subdir,
                             "template-{}-Sa.ply".format(t_filename)),
                source_mesh[0].detach().cpu(), source_face[0].detach().cpu())
            pymesh.save_mesh_raw(
                os.path.join(opt.log_dir, subdir,
                             "template-{}-Sb.ply".format(t_filename)),
                target_shape[b].detach().cpu(), target_face[b].detach().cpu())
            pymesh.save_mesh_raw(
                os.path.join(opt.log_dir, subdir,
                             "template-{}-Sab.ply".format(t_filename)),
                deformed[b].detach().cpu(), source_face[b].detach().cpu())

            pymesh.save_mesh_raw(
                os.path.join(opt.log_dir, subdir,
                             "template-{}-cage1.ply".format(t_filename)),
                outputs["cage"][b].detach().cpu(),
                outputs["cage_face"][b].detach().cpu())
            pymesh.save_mesh_raw(
                os.path.join(opt.log_dir, subdir,
                             "template-{}-cage2.ply".format(t_filename)),
                outputs["new_cage"][b].detach().cpu(),
                outputs["cage_face"][b].detach().cpu())

    PairedSurreal.render_result(test_output_dir)
Exemplo n.º 11
0
def test_all(net=None, subdir="test"):
    opt.phase = "test"
    dataset = build_dataset(opt)

    if net is None:
        source_shape = dataset.mesh_vertex.unsqueeze(0).to(dtype=torch.float)
        source_face = dataset.mesh_face.unsqueeze(0)
        cage_shape = dataset.cage_vertex.unsqueeze(0).to(dtype=torch.float)
        cage_face = dataset.cage_face.unsqueeze(0)
        net = networks.FixedSourceDeformer(
            opt,
            3,
            opt.num_point,
            bottleneck_size=opt.bottleneck_size,
            template_vertices=cage_shape.transpose(1, 2),
            template_faces=cage_face,
            source_vertices=source_shape.transpose(1, 2),
            source_faces=source_face).cuda()

        load_network(net, opt.ckpt)
        net.eval()
    else:
        net.eval()

    print(net)

    dataloader = torch.utils.data.DataLoader(
        dataset,
        batch_size=1,
        shuffle=False,
        drop_last=False,
        num_workers=3,
        worker_init_fn=lambda id: np.random.seed(np.random.get_state()[1][0] +
                                                 id))

    chamfer_distance = losses.LabeledChamferDistance(beta=0, gamma=1)
    mse_distance = torch.nn.MSELoss()
    avg_CD = 0
    avg_EMD = 0
    test_output_dir = os.path.join(opt.log_dir, subdir)
    os.makedirs(test_output_dir, exist_ok=True)
    with open(os.path.join(test_output_dir, "eval.txt"), "w") as f:
        with torch.no_grad():
            source_mesh = net.source_vertices.transpose(1, 2).detach()
            source_face = net.source_faces.detach()
            for i, data in enumerate(dataloader):
                data = dataset.uncollate(data)

                target_shape, target_filename = data["target_shape"], data[
                    "target_file"]

                sample_idx = None
                if "sample_idx" in data:
                    sample_idx = data["sample_idx"]
                outputs = net(target_shape.transpose(1, 2), sample_idx)
                deformed = outputs["deformed"]

                deformed = deform_with_MVC(
                    outputs["cage"], outputs["new_cage"],
                    outputs["cage_face"].expand(outputs["cage"].shape[0], -1,
                                                -1), source_mesh)

                for b in range(outputs["deformed"].shape[0]):
                    t_filename = os.path.splitext(target_filename[b])[0]
                    target_shape_np = target_shape.detach().cpu()[b].numpy()
                    if data["target_face"] is not None and data[
                            "target_mesh"] is not None:
                        pymesh.save_mesh_raw(
                            os.path.join(
                                opt.log_dir, subdir,
                                "template-{}-Sa.ply".format(t_filename)),
                            source_mesh[0].detach().cpu(),
                            source_face[0].detach().cpu())
                        pymesh.save_mesh_raw(
                            os.path.join(
                                opt.log_dir, subdir,
                                "template-{}-Sb.ply".format(t_filename)),
                            data["target_mesh"][b].detach().cpu(),
                            data["target_face"][b].detach().cpu())
                        pymesh.save_mesh_raw(
                            os.path.join(
                                opt.log_dir, subdir,
                                "template-{}-Sab.ply".format(t_filename)),
                            deformed[b].detach().cpu(),
                            source_face[b].detach().cpu())
                    else:
                        save_ply(
                            source_mesh[0].detach().cpu(),
                            os.path.join(
                                opt.log_dir, subdir,
                                "template-{}-Sa.ply".format(t_filename)))
                        save_ply(
                            target_shape[b].detach().cpu(),
                            os.path.join(
                                opt.log_dir, subdir,
                                "template-{}-Sb.ply".format(t_filename)),
                            normals=data["target_normals"][b].detach().cpu())
                        save_ply(
                            deformed[b].detach().cpu(),
                            os.path.join(
                                opt.log_dir, subdir,
                                "template-{}-Sab.ply".format(t_filename)),
                            normals=data["target_normals"][b].detach().cpu())

                    pymesh.save_mesh_raw(
                        os.path.join(
                            opt.log_dir, subdir,
                            "template-{}-cage1.ply".format(t_filename)),
                        outputs["cage"][b].detach().cpu(),
                        outputs["cage_face"][b].detach().cpu())
                    pymesh.save_mesh_raw(
                        os.path.join(
                            opt.log_dir, subdir,
                            "template-{}-cage2.ply".format(t_filename)),
                        outputs["new_cage"][b].detach().cpu(),
                        outputs["cage_face"][b].detach().cpu())

                    log_str = "{}/{} {}".format(i, len(dataloader), t_filename)
                    print(log_str)
                    f.write(log_str + "\n")

    dataset.render_result(test_output_dir)
Exemplo n.º 12
0
def test(net=None, save_subdir="test"):
    opt.phase = "test"
    dataset = build_dataset(opt)

    if opt.dim == 3:
        init_cage_V, init_cage_Fs = loadInitCage([opt.template])
        cage_V_t = init_cage_V.transpose(1, 2).detach().cuda()
    else:
        init_cage_V = generatePolygon(0, 0, 1.5, 0, 0, 0, opt.cage_deg)
        init_cage_V = torch.tensor([(x, y) for x, y in init_cage_V],
                                   dtype=torch.float).unsqueeze(0)
        cage_V_t = init_cage_V.transpose(1, 2).detach().cuda()
        init_cage_Fs = [
            torch.arange(opt.cage_deg, dtype=torch.int64).view(1, 1,
                                                               -1).cuda()
        ]

    if net is None:
        # network
        net = networks.NetworkFull(
            opt,
            dim=opt.dim,
            bottleneck_size=opt.bottleneck_size,
            template_vertices=cage_V_t,
            template_faces=init_cage_Fs[-1],
        ).cuda()
        net.eval()
        load_network(net, opt.ckpt)
    else:
        net.eval()

    print(net)

    dataloader = torch.utils.data.DataLoader(
        dataset,
        batch_size=1,
        shuffle=False,
        drop_last=False,
        collate_fn=tolerating_collate,
        num_workers=0,
        worker_init_fn=lambda id: np.random.seed(np.random.get_state()[1][0] +
                                                 id))

    test_output_dir = os.path.join(opt.log_dir, save_subdir)
    os.makedirs(test_output_dir, exist_ok=True)
    with open(os.path.join(test_output_dir, "eval.txt"), "w") as f:
        with torch.no_grad():
            for i, data in enumerate(dataloader):
                data = dataset.uncollate(data)

                ############# blending ############
                # sample 4 different alpha
                if opt.blend_style:
                    num_alpha = 4
                    blend_alpha = torch.linspace(
                        0, 1, steps=num_alpha,
                        dtype=torch.float32).cuda().reshape(num_alpha, 1)
                    data["source_shape"] = data["source_shape"].expand(
                        num_alpha, -1, -1).contiguous()
                    data["target_shape"] = data["target_shape"].expand(
                        num_alpha, -1, -1).contiguous()
                else:
                    blend_alpha = 1.0

                data["alpha"] = blend_alpha

                ###################################
                source_shape_t = data["source_shape"].transpose(
                    1, 2).contiguous().detach()
                target_shape_t = data["target_shape"].transpose(
                    1, 2).contiguous().detach()

                outputs = net(source_shape_t, target_shape_t, blend_alpha)
                deformed = outputs["deformed"]

                ####################### evaluation ########################
                s_filename = os.path.splitext(data["source_file"][0])[0]
                t_filename = os.path.splitext(data["target_file"][0])[0]

                log_str = "{}/{} {}-{} ".format(i, len(dataloader), s_filename,
                                                t_filename)
                print(log_str)
                f.write(log_str + "\n")

                ###################### outputs ############################
                for b in range(deformed.shape[0]):
                    if "source_mesh" in data and data[
                            "source_mesh"] is not None:
                        if isinstance(data["source_mesh"][0], str):
                            source_mesh = om.read_polymesh(
                                data["source_mesh"][0]).points().copy()
                            source_mesh = dataset.normalize(
                                source_mesh, opt.isV2)
                            source_mesh = torch.from_numpy(
                                source_mesh.astype(
                                    np.float32)).unsqueeze(0).cuda()
                            deformed = deform_with_MVC(
                                outputs["cage"][b:b + 1],
                                outputs["new_cage"][b:b + 1],
                                outputs["cage_face"], source_mesh)
                        else:
                            deformed = deform_with_MVC(
                                outputs["cage"][b:b + 1],
                                outputs["new_cage"][b:b + 1],
                                outputs["cage_face"], data["source_mesh"])

                    deformed[b] = center_bounding_box(deformed[b])[0]
                    if data["source_face"] is not None and data[
                            "source_mesh"] is not None:
                        source_mesh = data["source_mesh"][0].detach().cpu()
                        source_mesh = center_bounding_box(source_mesh)[0]
                        source_face = data["source_face"][0].detach().cpu()
                        tosave = pymesh.form_mesh(vertices=source_mesh,
                                                  faces=source_face)
                        pymesh.save_mesh(os.path.join(
                            opt.log_dir, save_subdir,
                            "{}-{}-Sa.obj".format(s_filename, t_filename)),
                                         tosave,
                                         use_float=True)
                        tosave = pymesh.form_mesh(
                            vertices=deformed[0].detach().cpu(),
                            faces=source_face)
                        pymesh.save_mesh(
                            os.path.join(
                                opt.log_dir, save_subdir,
                                "{}-{}-Sab-{}.obj".format(
                                    s_filename, t_filename, b)),
                            tosave,
                            use_float=True,
                        )
                    elif data["source_face"] is None and isinstance(
                            data["source_mesh"][0], str):
                        orig_file_path = data["source_mesh"][0]
                        mesh = om.read_polymesh(orig_file_path)
                        points_arr = mesh.points()
                        points_arr[:] = source_mesh[0].detach().cpu().numpy()
                        om.write_mesh(
                            os.path.join(
                                opt.log_dir, save_subdir,
                                "{}-{}-Sa.obj".format(s_filename, t_filename)),
                            mesh)
                        points_arr[:] = deformed[0].detach().cpu().numpy()
                        om.write_mesh(
                            os.path.join(
                                opt.log_dir, save_subdir,
                                "{}-{}-Sab-{}.obj".format(
                                    s_filename, t_filename, b)), mesh)
                    else:
                        # save to "pts" for rendering
                        save_pts(
                            os.path.join(
                                opt.log_dir, save_subdir,
                                "{}-{}-Sa.pts".format(s_filename, t_filename)),
                            data["source_shape"][b].detach().cpu())
                        save_pts(
                            os.path.join(
                                opt.log_dir, save_subdir,
                                "{}-{}-Sab-{}.pts".format(
                                    s_filename, t_filename, b)),
                            deformed[0].detach().cpu())

                    if data["target_face"] is not None and data[
                            "target_mesh"] is not None:
                        data["target_mesh"][0] = center_bounding_box(
                            data["target_mesh"][0])[0]
                        tosave = pymesh.form_mesh(
                            vertices=data["target_mesh"][0].detach().cpu(),
                            faces=data["target_face"][0].detach().cpu())
                        pymesh.save_mesh(
                            os.path.join(
                                opt.log_dir, save_subdir,
                                "{}-{}-Sb.obj".format(s_filename, t_filename)),
                            tosave,
                            use_float=True,
                        )
                    elif data["target_face"] is None and isinstance(
                            data["target_mesh"][0], str):
                        orig_file_path = data["target_mesh"][0]
                        mesh = om.read_polymesh(orig_file_path)
                        points_arr = mesh.points()
                        points_arr[:] = dataset.normalize(
                            points_arr.copy(), opt.isV2)
                        om.write_mesh(
                            os.path.join(
                                opt.log_dir, save_subdir,
                                "{}-{}-Sb.obj".format(s_filename, t_filename)),
                            mesh)
                    else:
                        save_pts(
                            os.path.join(
                                opt.log_dir, save_subdir,
                                "{}-{}-Sb.pts".format(s_filename, t_filename)),
                            data["target_shape"][0].detach().cpu())

                    outputs["cage"][b] = center_bounding_box(
                        outputs["cage"][b])[0]
                    outputs["new_cage"][b] = center_bounding_box(
                        outputs["new_cage"][b])[0]
                    pymesh.save_mesh_raw(
                        os.path.join(
                            opt.log_dir, save_subdir,
                            "{}-{}-cage1-{}.ply".format(
                                s_filename, t_filename, b)),
                        outputs["cage"][b].detach().cpu(),
                        outputs["cage_face"][0].detach().cpu(),
                        binary=True)
                    pymesh.save_mesh_raw(
                        os.path.join(
                            opt.log_dir, save_subdir,
                            "{}-{}-cage2-{}.ply".format(
                                s_filename, t_filename, b)),
                        outputs["new_cage"][b].detach().cpu(),
                        outputs["cage_face"][0].detach().cpu(),
                        binary=True)

    dataset.render_result(test_output_dir)
Exemplo n.º 13
0
def forward(opt):
    """
    Takes an input and a target mesh. Deform input in output and propagate a
    manually defined high frequency from the oinput to the output
    :return:
    """
    my_utils.plant_seeds(randomized_seed=opt.randomize)
    os.makedirs(opt.output_dir, exist_ok=True)

    trainer = t.Trainer(opt)
    trainer.build_dataset_train_for_matching()
    trainer.build_dataset_test_for_matching()
    trainer.build_network()
    trainer.build_losses()
    trainer.network.eval()

    if opt.eval_list and os.path.isfile(opt.eval_list):
        source_target_files = np.loadtxt(opt.eval_list, dtype=str)
        source_target_files = source_target_files.tolist()
        for i, st in enumerate(source_target_files):
            source, target = st
            cat1, fname1 = source.split('/')
            fname1 = os.path.splitext(fname1)[0]
            cat2, fname2 = target.split('/')
            fname2 = os.path.splitext(fname2)[0]
            if len(opt.shapenetv1_path) > 0:
                source_target_files[i] = (os.path.join(opt.shapenetv1_path,
                                                       cat1, fname1,
                                                       "model.obj"),
                                          os.path.join(opt.shapenetv1_path,
                                                       cat2, fname2,
                                                       "model.obj"))
            elif len(opt.shapenetv2_path) > 0:
                source_target_files[i] = (os.path.join(opt.shapenetv2_path,
                                                       cat1, fname1, "models",
                                                       "model_normalized.obj"),
                                          os.path.join(opt.shapenetv2_path,
                                                       cat2, fname2, "models",
                                                       "model_normalized.obj"))
    elif (opt.eval_source != "" and opt.eval_source[-4:] == ".txt") and (
            opt.eval_target != "" and opt.eval_target[-4:] == ".txt"):
        source_target_files = [
            (figure_2_3.convert_path(opt.shapenetv1_path, opt.eval_source),
             figure_2_3.convert_path(opt.shapenetv1_path, opt.eval_target))
        ]

    rot_mat = get_3D_rot_matrix(1, np.pi / 2)
    rot_mat_rev = get_3D_rot_matrix(1, -np.pi / 2)
    isV2 = len(opt.shapenetv2_path) > 0
    for i, source_target in enumerate(source_target_files):
        basename = get_model_id(source_target[0], isV2) + "-" + get_model_id(
            source_target[1], isV2)
        path_deformed = os.path.join(opt.output_dir, basename + "-Sab.ply")
        path_source = os.path.join(opt.output_dir, basename + "-Sa.ply")
        path_target = os.path.join(opt.output_dir, basename + "-Sb.ply")

        mesh_path = source_target[0]
        print(mesh_path)
        source_mesh_edge = get_shapenet_model.link(mesh_path)

        mesh_path = source_target[1]
        target_mesh_edge = get_shapenet_model.link(mesh_path)

        print("Deforming source in target")

        source = source_mesh_edge.vertices
        target = target_mesh_edge.vertices

        pymesh.save_mesh_raw(path_source,
                             source,
                             source_mesh_edge.faces,
                             ascii=True)
        pymesh.save_mesh_raw(path_target,
                             target,
                             target_mesh_edge.faces,
                             ascii=True)

        if len(opt.shapenetv2_path) > 0:
            source = source.dot(rot_mat)
            target = target.dot(rot_mat)

        source = torch.from_numpy(source).cuda().float().unsqueeze(0)
        target = torch.from_numpy(target).cuda().float().unsqueeze(0)

        with torch.no_grad():
            source, _, _, _, _ = loss.forward_chamfer(
                trainer.network,
                source,
                target,
                local_fix=None,
                distChamfer=trainer.distChamfer)

        try:
            source = source.squeeze().cpu().detach().numpy()
            if len(opt.shapenetv2_path) > 0:
                source = source.dot(rot_mat_rev)
            P2_P1_mesh = pymesh.form_mesh(vertices=source,
                                          faces=source_mesh_edge.faces)
            pymesh.save_mesh(path_deformed, P2_P1_mesh, ascii=True)

            # print("computing signal tranfer form source to target")
            # high_frequencies.high_frequency_propagation(path_source, path_deformed, path_target)
        except Exception as e:
            print(e)
            import pdb
            pdb.set_trace()
            path_deformed = path_deformed[:-4] + ".pts"
            save_pts(path_deformed, source.squeeze().cpu().detach().numpy())
Exemplo n.º 14
0
def test_orientation():
    m = pymesh.load_mesh(os.path.join(os.path.dirname(__file__), 'source_models/bunny.obj'))
    new_mesh = orientation.orient_printed_mesh(m)
    pymesh.save_mesh_raw(os.path.join(os.path.dirname(__file__), 'watermarked_models/out_orientation.obj'), new_mesh.vertices, new_mesh.faces)
Exemplo n.º 15
0
import pymesh

file_path = "/Users/luchenliu/Desktop/Intern/1_projection/glasses.obj"
mesh = pymesh.load_mesh(file_path)
pymesh.save_mesh_raw(file_path.replace(".obj", ".ply"), mesh.vertices,
                     mesh.faces, mesh.voxels)
Exemplo n.º 16
0
def get_normalize_mesh(model_file, norm_mesh_sub_dir, pnt_dir, ref_sub_dir):
    total = 16384 * 50
    print("trimesh_load:", model_file)
    ref_file = os.path.join(ref_sub_dir, "isosurf.obj")
    mesh_list = trimesh.load_mesh(model_file, process=False)
    if not isinstance(mesh_list, list):
        mesh_list = [mesh_list]
    area_sum = 0
    area_lst = []
    for idx, mesh in enumerate(mesh_list):
        area = np.sum(mesh.area_faces)
        area_lst.append(area)
        area_sum += area
    area_lst = np.asarray(area_lst)
    amount_lst = (area_lst * total / area_sum).astype(np.int32)
    points_all = np.zeros((0, 3), dtype=np.float32)
    all_face_normals = np.zeros((0, 3), dtype=np.float32)
    all_vert_normals = np.zeros((0, 3, 3), dtype=np.float32)
    all_tries = np.zeros((0, 3, 3), dtype=np.float32)
    sample_indices = np.zeros((0), dtype=np.int)
    for i in range(amount_lst.shape[0]):
        mesh = mesh_list[i]
        # print("start sample surface of ", mesh.faces.shape[0])
        points, index = trimesh.sample.sample_surface(mesh, amount_lst[i])
        if not os.path.exists(ref_file):
            sample_indices = np.concatenate(
                [sample_indices, sample_indices.shape[0] + index], axis=0)
            vert_ind = mesh.faces.reshape(-1)
            all_tries = np.concatenate(
                [all_tries, mesh.vertices[vert_ind].reshape([-1, 3, 3])],
                axis=0)
            all_face_normals = np.concatenate(
                [all_face_normals, mesh.face_normals], axis=0)
            all_vert_normals = np.concatenate([
                all_vert_normals, mesh.vertex_normals[vert_ind].reshape(
                    [-1, 3, 3])
            ],
                                              axis=0)
        # print("end sample surface")
        points_all = np.concatenate([points_all, points], axis=0)
    centroid = np.mean(points_all, axis=0)
    points_all = points_all - centroid
    m = np.max(np.sqrt(np.sum(points_all**2, axis=1)))
    obj_file = os.path.join(norm_mesh_sub_dir, "pc_norm.obj")
    param_file = os.path.join(norm_mesh_sub_dir, "pc_norm.txt")
    params = np.concatenate([centroid, np.expand_dims(m, axis=0)])
    np.savetxt(param_file, params)
    print("export_mesh", obj_file)
    from_marchingcube = False
    if not os.path.exists(ref_file):
        ori_mesh = pymesh.load_mesh(model_file)
        print("centroid, m", centroid, m)
    else:
        from_marchingcube = True
        mesh_list = trimesh.load_mesh(ref_file, process=False)
        print("trimesh_load ref_file:", ref_file)
        if not isinstance(mesh_list, list):
            mesh_list = [mesh_list]
        area_sum = 0
        area_lst = []
        for idx, mesh in enumerate(mesh_list):
            area = np.sum(mesh.area_faces)
            area_lst.append(area)
            area_sum += area
        area_lst = np.asarray(area_lst)
        amount_lst = (area_lst * total / area_sum).astype(np.int32)
        points_all = np.zeros((0, 3), dtype=np.float32)
        for i in range(amount_lst.shape[0]):
            mesh = mesh_list[i]
            # print("start sample surface of ", mesh.faces.shape[0])
            points, index = trimesh.sample.sample_surface(mesh, amount_lst[i])
            sample_indices = np.concatenate(
                [sample_indices, sample_indices.shape[0] + index], axis=0)
            vert_ind = mesh.faces.reshape(-1)
            all_tries = np.concatenate(
                [all_tries, mesh.vertices[vert_ind].reshape([-1, 3, 3])],
                axis=0)
            all_face_normals = np.concatenate(
                [all_face_normals, mesh.face_normals], axis=0)
            all_vert_normals = np.concatenate([
                all_vert_normals, mesh.vertex_normals[vert_ind].reshape(
                    [-1, 3, 3])
            ],
                                              axis=0)
            # print("end sample surface")
            points_all = np.concatenate([points_all, points], axis=0)
        centroid = np.mean(points_all, axis=0)
        points_all = points_all - centroid
        m = np.max(np.sqrt(np.sum(points_all**2, axis=1)))
        ori_mesh = pymesh.load_mesh(ref_file)
    surfpoints = points_all / float(m)
    all_tries = (all_tries - centroid[np.newaxis, np.newaxis, :]) / float(m)
    print("centroid, m", centroid, m)
    verts = (ori_mesh.vertices - centroid) / float(m)
    pymesh.save_mesh_raw(obj_file, verts, ori_mesh.faces)
    face_norm_surfpnt = save_surface(sample_indices, surfpoints, all_tries,
                                     all_face_normals, all_vert_normals,
                                     pnt_dir)
    return all_tries, all_face_normals, all_vert_normals, params, surfpoints, face_norm_surfpnt, from_marchingcube
Exemplo n.º 17
0
        ])
    new_face = np.array(new_f)
    return new_face


random_sample = np.random.choice(6890, size=6890, replace=False)
random_sample2 = np.random.choice(6890, size=6890, replace=False)

id_mesh = pymesh.load_mesh('./demo_data/13_643.obj')
pose_mesh = pymesh.load_mesh('./demo_data/14_664.obj')

with torch.no_grad():
    id_mesh_points = id_mesh.vertices[random_sample]
    id_mesh_points = id_mesh_points - (id_mesh.bbox[0] + id_mesh.bbox[1]) / 2
    id_mesh_points = torch.from_numpy(id_mesh_points.astype(np.float32)).cuda()

    pose_mesh_points = pose_mesh.vertices  #[random_sample2]
    pose_mesh_points = pose_mesh_points - (pose_mesh.bbox[0] +
                                           pose_mesh.bbox[1]) / 2
    pose_mesh_points = torch.from_numpy(pose_mesh_points.astype(
        np.float32)).cuda()

    pointsReconstructed = net_G(
        pose_mesh_points.transpose(0, 1).unsqueeze(0),
        id_mesh_points.transpose(0, 1).unsqueeze(0))  # forward pass

new_face = face_reverse(id_mesh.faces)

pymesh.save_mesh_raw('./demo_data/13_664.obj',
                     pointsReconstructed.cpu().numpy().squeeze(), new_face)
Exemplo n.º 18
0
        scheduler.step(loss.item())

    return deformed_shape


if __name__ == "__main__":
    parser = MyOptions()
    opt = parser.parse()

    opt.log_dir = os.path.dirname(opt.ckpt)

    os.makedirs(os.path.join(opt.log_dir, opt.subdir), exist_ok=True)
    if opt.use_cage is None:
        # optimize initial cage for the new target
        cage_v, cage_f = optimize(opt)
        pymesh.save_mesh_raw(os.path.join(opt.log_dir, opt.subdir, "optimized_template_cage.ply"),
                             cage_v[0].detach().cpu(), cage_f[0].detach().cpu())
    else:
        cage_v, cage_f = read_trimesh(opt.use_cage)
        cage_v = torch.from_numpy(cage_v[:, :3].astype(np.float32)).cuda()
        cage_f = torch.from_numpy(cage_f[:, :3].astype(np.int64)).cuda()
        cage_v.unsqueeze_(0)
        cage_f.unsqueeze_(0)

    # # test using the new source and initial cage
    # target_shape_pose, target_face_pose, _ = read_trimesh("/home/mnt/points/data/MPI-FAUST/training/registrations/tr_reg_002.ply")
    # target_shape_pose = torch.from_numpy(target_shape_pose[:,:3].astype(np.float32)).cuda()
    # target_face_pose = torch.from_numpy(target_face_pose[:,:3].astype(np.int64)).cuda()
    # target_shape_pose, _, _ = center_bounding_box(target_shape_pose)
    # target_shape_pose.unsqueeze_(0)
    # target_face_pose.unsqueeze_(0)
    # test_one(opt, cage_v, target_shape, target_face, target_shape_pose, target_face_pose)
    def __call__(self, outputMesh):

        generate_x = np.array([])
        generate_y = np.array([])
        generate_z = np.array([])

        source_control_x = self.source_vertices_x[0:self.control_num]
        source_control_y = self.source_vertices_y[0:self.control_num]
        source_control_z = self.source_vertices_z[0:self.control_num]
        target_control_x = self.target_vertices_x[0:self.control_num]
        target_control_y = self.target_vertices_y[0:self.control_num]
        target_control_z = self.target_vertices_z[0:self.control_num]

        result_x = source_control_x
        result_y = source_control_y
        result_z = source_control_z

        vertex_num = self.source_vertices_x.size
        for i in range(self.control_num, vertex_num):
            source_di_x = np.array([])
            source_di_y = np.array([])
            source_di_z = np.array([])
            for j in range(0, self.control_num):
                di_x = self.source_vertices_x.item(
                    i) - self.source_vertices_x.item(j)
                di_y = self.source_vertices_y.item(
                    i) - self.source_vertices_y.item(j)
                di_z = self.source_vertices_z.item(
                    i) - self.source_vertices_z.item(j)
                source_di_x = np.append(source_di_x, di_x)
                source_di_y = np.append(source_di_y, di_y)
                source_di_z = np.append(source_di_z, di_z)
                #print(source_di_x.shape)
                #print(source_di_y.shape)
                #print(source_di_z.shape)
                #print(source_control_x.shape)
            fitting_x = RBF(source_control_x, source_control_y,
                            source_control_z, source_di_x)
            fitting_y = RBF(source_control_x, source_control_y,
                            source_control_z, source_di_y)
            fitting_z = RBF(source_control_x, source_control_y,
                            source_control_z, source_di_z)
            generate_x = np.add(
                fitting_x(target_control_x, target_control_y,
                          target_control_z), target_control_x)
            generate_y = np.add(
                fitting_y(target_control_x, target_control_y,
                          target_control_z), target_control_y)
            generate_z = np.add(
                fitting_z(target_control_x, target_control_y,
                          target_control_z), target_control_z)
            result_x = np.append(result_x, np.mean(generate_x))
            result_y = np.append(result_y, np.mean(generate_y))
            result_z = np.append(result_z, np.mean(generate_z))

        result_vertices = np.vstack([result_x, result_y, result_z]).T
        pm.save_mesh_raw(outputMesh + ".obj",
                         result_vertices,
                         self.target_face,
                         voxels=None)
        print("Deformation finished")

        check_a = result_vertices.flatten()
        check_b = self.source_vertices.flatten()

        percentage = 0
        for i in range(0, check_a.size):
            percentage = percentage + (abs(check_a.item(i) - check_b.item(i)) /
                                       check_b.item(i))
        #print(percentage)
        percentage = percentage / check_a.size
        print("Average error (in percentage):", percentage * 100)
Exemplo n.º 20
0
            files = glob.glob(os.path.join(phrase_path, '*.off'))
            for file in files:
                _, filename = os.path.split(file)
                new_filename = new_root + '/' + type + '/' + phrase + '/' + filename[:
                                                                                     -4]

                # load mesh
                mesh = pymesh.load_mesh(file)

                ### off2ply
                vertices = mesh.vertices
                faces = mesh.faces
                voxels = mesh.voxels
                # For surface mesh
                pymesh.save_mesh_raw(new_filename + ".ply", vertices, faces)
                # For volume mesh
                # pymesh.save_mesh_raw(new_filename + ".ply", vertices, faces, voxels)
                # In ascii and using float
                # pymesh.save_mesh_raw(new_filename + ".ply", vertices, faces, voxels, ascii=True, use_float=True)

                ### off2npz
                # clean up
                mesh, _ = pymesh.remove_isolated_vertices(mesh)
                mesh, _ = pymesh.remove_duplicated_vertices(mesh)

                # get elements
                vertices = mesh.vertices.copy()
                faces = mesh.faces.copy()

                # move to center
Exemplo n.º 21
0
 def write(self, mesh_file, vertices, faces):
     import pymesh
     pymesh.save_mesh_raw(mesh_file, vertices, faces)
Exemplo n.º 22
0
def test_all(opt, new_cage_shape):
    opt.phase = "test"
    opt.target_model = None
    print(opt.model)

    if opt.is_poly:
        source_mesh = om.read_polymesh(opt.model)
    else:
        source_mesh = om.read_trimesh(opt.model)

    dataset = build_dataset(opt)
    dataloader = torch.utils.data.DataLoader(dataset, batch_size=1, shuffle=False, drop_last=False,
                                             collate_fn=tolerating_collate,
                                             num_workers=0, worker_init_fn=lambda id: np.random.seed(np.random.get_state()[1][0] + id))

    states = torch.load(opt.ckpt)
    if "states" in states:
        states = states["states"]
    # states["template_vertices"] = new_cage_shape.transpose(1, 2)
    # states["source_vertices"] = new_source.transpose(1,2)
    # states["source_faces"] = new_source_face
    # new_source_face = states["source_faces"]

    om.write_mesh(os.path.join(opt.log_dir, opt.subdir,
                               "template-Sa.ply"), source_mesh)

    net = networks.FixedSourceDeformer(opt, 3, opt.num_point, bottleneck_size=opt.bottleneck_size,
                                       template_vertices=states["template_vertices"], template_faces=states["template_faces"].cuda(),
                                       source_vertices=states["source_vertices"], source_faces=states["source_faces"]).cuda()
    load_network(net, states)

    source_points = torch.from_numpy(
        source_mesh.points().copy()).float().cuda().unsqueeze(0)
    with torch.no_grad():
        # source_face = net.source_faces.detach()
        for i, data in enumerate(dataloader):
            data = dataset.uncollate(data)

            target_shape, target_filename = data["target_shape"], data["target_file"]
            logger.info("", data["target_file"][0])

            sample_idx = None
            if "sample_idx" in data:
                sample_idx = data["sample_idx"]

            outputs = net(target_shape.transpose(1, 2), cage_only=True)
            if opt.d_residual:
                cage_offset = outputs["new_cage"]-outputs["cage"]
                outputs["cage"] = new_cage_shape
                outputs["new_cage"] = new_cage_shape+cage_offset

            deformed = deform_with_MVC(outputs["cage"], outputs["new_cage"], outputs["cage_face"].expand(
                outputs["cage"].shape[0], -1, -1), source_points)

            for b in range(deformed.shape[0]):
                t_filename = os.path.splitext(target_filename[b])[0]
                source_mesh_arr = source_mesh.points()
                source_mesh_arr[:] = deformed[0].cpu().detach().numpy()
                om.write_mesh(os.path.join(
                    opt.log_dir, opt.subdir, "template-{}-Sab.obj".format(t_filename)), source_mesh)
                # if data["target_face"] is not None and data["target_mesh"] is not None:
                # pymesh.save_mesh_raw(os.path.join(opt.log_dir, opt.subdir, "template-{}-Sa.ply".format(t_filename)),
                #             source_mesh[0].detach().cpu(), source_face[b].detach().cpu())
                pymesh.save_mesh_raw(os.path.join(opt.log_dir, opt.subdir, "template-{}-Sb.ply".format(t_filename)),
                                     data["target_mesh"][b].detach().cpu(), data["target_face"][b].detach().cpu())
                # pymesh.save_mesh_raw(os.path.join(opt.log_dir, opt.subdir, "template-{}-Sab.ply".format(t_filename)),
                #             deformed[b].detach().cpu(), source_face[b].detach().cpu())

                # else:
                #     save_ply(source_mesh[0].detach().cpu(), os.path.join(opt.log_dir, opt.subdir,"template-{}-Sa.ply".format(t_filename)))
                #     save_ply(target_shape[b].detach().cpu(), os.path.join(opt.log_dir, opt.subdir,"template-{}-Sb.ply".format(t_filename)),
                #                 normals=data["target_normals"][b].detach().cpu())
                #     save_ply(deformed[b].detach().cpu(), os.path.join(opt.log_dir, opt.subdir,"template-{}-Sab.ply".format(t_filename)),
                #                 normals=data["target_normals"][b].detach().cpu())

                pymesh.save_mesh_raw(
                    os.path.join(opt.log_dir, opt.subdir, "template-{}-cage1.ply".format(t_filename)),
                    outputs["cage"][b].detach().cpu(), outputs["cage_face"][b].detach().cpu(),
                                   )
                pymesh.save_mesh_raw(
                    os.path.join(opt.log_dir, opt.subdir, "template-{}-cage2.ply".format(t_filename)),
                    outputs["new_cage"][b].detach().cpu(), outputs["cage_face"][b].detach().cpu(),
                                   )

            # if opt.opt_lap and deformed.shape[1] == source_mesh.shape[1]:
            #     deformed = optimize_lap(opt, source_mesh, deformed, source_face)
            #     for b in range(deformed.shape[0]):
            #         pymesh.save_mesh_raw(os.path.join(opt.log_dir, opt.subdir, "template-{}-Sab-optlap.ply".format(t_filename)),
            #                                 deformed[b].detach().cpu(), source_face[b].detach().cpu())

            if i % 20 == 0:
                logger.success("[{}/{}] Done".format(i, len(dataloader)))

    dataset.render_result(os.path.join(opt.log_dir, opt.subdir))
Exemplo n.º 23
0
source_control_z = source_vertices_z[0:control_num]
target_control_x = target_vertices_x[0:control_num]
target_control_y = target_vertices_y[0:control_num]
target_control_z = target_vertices_z[0:control_num]

result_x = target_control_x
result_y = target_control_y
result_z = target_control_z

vertex_num = source_vertices_x.size
for i in range(control_num, vertex_num):
    for j in range(0, control_num):
        distance_x = source_vertices_x.item(i) - source_vertices_x.item(j)
        distance_y = source_vertices_y.item(i) - source_vertices_y.item(j)
        distance_z = source_vertices_z.item(i) - source_vertices_z.item(j)
        source_distance_x = np.append(source_distance_x, distance_x)
        source_distance_y = np.append(source_distance_y, distance_y)
        source_distance_z = np.append(source_distance_z, distance_z)
    fitting_func_x = Rbf(source_control_x, source_distance_x)
    fitting_func_y = Rbf(source_control_y, source_distance_y)
    fitting_func_z = Rbf(source_control_z, source_distance_z)
    generate_x = np.add(Rbf(source_control_x) + target_control_x)
    generate_y = np.add(Rbf(source_control_y) + target_control_y)
    generate_z = np.add(Rbf(source_control_z) + target_control_z)
    result_x = np.append(result_x, np.mean(generate_x))
    result_y = np.append(result_y, np.mean(generate_y))
    result_z = np.append(result_z, np.mean(generate_z))

result_vertices = np.vstack([result_x, result_y, result_z]).T
pm.save_mesh_raw("output.obj", result_vertices, target_faces, voxels=None)
Exemplo n.º 24
0
def optimize(opt):
    """
    weights are the same with the original source mesh
    target=net(old_source)
    """
    # load new target
    if opt.is_poly:
        target_mesh = om.read_polymesh(opt.model)
    else:
        target_mesh = om.read_trimesh(opt.model)
    target_shape_arr = target_mesh.points()
    target_shape = target_shape_arr.copy()
    target_shape = torch.from_numpy(
        target_shape[:, :3].astype(np.float32)).cuda()
    target_shape.unsqueeze_(0)

    states = torch.load(opt.ckpt)
    if "states" in states:
        states = states["states"]
    cage_v = states["template_vertices"].transpose(1, 2).cuda()
    cage_f = states["template_faces"].cuda()
    shape_v = states["source_vertices"].transpose(1, 2).cuda()
    shape_f = states["source_faces"].cuda()

    if os.path.isfile(opt.model.replace(os.path.splitext(opt.model)[1], ".picked")) and os.path.isfile(opt.source_model.replace(os.path.splitext(opt.source_model)[1], ".picked")):
        new_label_path = opt.model.replace(os.path.splitext(opt.model)[1], ".picked")
        orig_label_path = opt.source_model.replace(os.path.splitext(opt.source_model)[1], ".picked")
        logger.info("Loading picked labels {} and {}".format(orig_label_path, new_label_path))
        import pandas as pd
        new_label = pd.read_csv(new_label_path, delimiter=" ",skiprows=1, header=None)
        orig_label = pd.read_csv(orig_label_path, delimiter=" ",skiprows=1, header=None)
        orig_label_name = orig_label.iloc[:,5]
        new_label_name = new_label.iloc[:,5].tolist()
        new_to_orig_idx = []
        for i, name in enumerate(new_label_name):
            matched_idx = orig_label_name[orig_label_name==name].index
            if matched_idx.size == 1:
                new_to_orig_idx.append((i, matched_idx[0]))
        new_to_orig_idx = np.array(new_to_orig_idx)
        if new_label.shape[1] == 10:
            new_vidx = new_label.iloc[:,9].to_numpy()[new_to_orig_idx[:,0]]
            target_points = target_shape[:, new_vidx, :]
        else:
            new_label_points = torch.from_numpy(new_label.iloc[:,6:9].to_numpy().astype(np.float32))
            target_points = new_label_points.unsqueeze(0).cuda()
            target_points, new_vidx, _ = faiss_knn(1, target_points, target_shape, NCHW=False)
            target_points = target_points.squeeze(2) # B,N,3
            new_label[9] = new_vidx.squeeze(0).squeeze(-1).cpu().numpy()
            new_label.to_csv(new_label_path, sep=" ", header=[str(new_label.shape[0])]+[""]*(new_label.shape[1]-1), index=False)
            target_points = target_points[:, new_to_orig_idx[:,0], :]

        target_points = target_points.cuda()
        source_shape, _ = read_trimesh(opt.source_model)
        source_shape = torch.from_numpy(source_shape[None, :,:3]).float()
        if orig_label.shape[1] == 10:
            orig_vidx = orig_label.iloc[:,9].to_numpy()[new_to_orig_idx[:,1]]
            source_points = source_shape[:, orig_vidx, :]
        else:
            orig_label_points = torch.from_numpy(orig_label.iloc[:,6:9].to_numpy().astype(np.float32))
            source_points = orig_label_points.unsqueeze(0)
            # find the closest point on the original meshes
            source_points, new_vidx, _ = faiss_knn(1, source_points, source_shape, NCHW=False)
            source_points = source_points.squeeze(2) # B,N,3
            orig_label[9] = new_vidx.squeeze(0).squeeze(-1).cpu().numpy()
            orig_label.to_csv(orig_label_path, sep=" ", header=[str(orig_label.shape[0])]+[""]*(orig_label.shape[1]-1), index=False)
            source_points = source_points[:,new_to_orig_idx[:,1],:]

        _, source_center, _ = center_bounding_box(source_shape[0])
        source_points -= source_center
        source_points = source_points.cuda()
        # # shift target so that the belly match
        # try:
        #     orig_bellyUp_idx = orig_label_name[orig_label_name=="bellUp"].index[0]
        #     orig_bellyUp = orig_label_points[orig_bellyUp_idx, :]
        #     new_bellyUp_idx = [i for i, i2 in new_to_orig_idx if i2==orig_bellyUp_idx][0]
        #     new_bellyUp = new_label_points[new_bellyUp_idx,:]
        #     target_points += (orig_bellyUp - new_bellyUp)
        # except Exception as e:
        #     logger.warn("Couldn\'t match belly to belly")
        #     traceback.print_exc(file=sys.stdout)

        # source_points[0] = center_bounding_box(source_points[0])[0]
    elif not os.path.isfile(opt.model.replace(os.path.splitext(opt.model)[1], ".picked")) and os.path.isfile(opt.source_model.replace(os.path.splitext(opt.source_model)[1], ".picked")):
        logger.info("Assuming Faust model")
        orig_label_path = opt.source_model.replace(os.path.splitext(opt.source_model)[1], ".picked")
        logger.info("Loading picked labels {}".format(orig_label_path))
        import pandas as pd
        orig_label = pd.read_csv(orig_label_path, delimiter=" ",skiprows=1, header=None)
        orig_label_name = orig_label.iloc[:,5]
        source_shape, _ = read_trimesh(opt.source_model)
        source_shape = torch.from_numpy(source_shape[None, :,:3]).cuda().float()
        if orig_label.shape[1] == 10:
            idx = torch.from_numpy(orig_label.iloc[:,9].to_numpy()).long()
            source_points = source_shape[:,idx,:]
            target_points = target_shape[:,idx,:]
        else:
            source_points = torch.from_numpy(orig_label.iloc[:,6:9].to_numpy().astype(np.float32))
            source_points = source_points.unsqueeze(0).cuda()
            # find the closest point on the original meshes
            source_points, idx, _ = faiss_knn(1, source_points, source_shape, NCHW=False)
            source_points = source_points.squeeze(2) # B,N,3
            idx = idx.squeeze(-1)
            target_points = target_shape[:,idx,:]

        _, source_center, _ = center_bounding_box(source_shape[0])
        source_points -= source_center
    elif opt.corres_idx is None and target_shape.shape[1] == shape_v.shape[1]:
        logger.info("No correspondence provided, assuming registered Faust models")
        # corresp_idx = torch.randint(0, shape_f.shape[1], (100,)).cuda()
        corresp_v = torch.unique(torch.randint(0, shape_v.shape[1], (4800,))).cuda()
        target_points = torch.index_select(target_shape, 1, corresp_v)
        source_points = torch.index_select(shape_v, 1, corresp_v)

    target_shape[0], target_center, target_scale = center_bounding_box(target_shape[0])
    _, _, source_scale = center_bounding_box(shape_v[0])
    target_scale_factor = (source_scale/target_scale)[1]
    target_shape *= target_scale_factor
    target_points -= target_center
    target_points = (target_points*target_scale_factor).detach()
    # make sure test use the normalized
    target_shape_arr[:] = target_shape[0].cpu().numpy()
    om.write_mesh(os.path.join(opt.log_dir, opt.subdir, os.path.splitext(
        os.path.basename(opt.model))[0]+"_normalized.obj"), target_mesh)
    opt.model = os.path.join(opt.log_dir, opt.subdir, os.path.splitext(
        os.path.basename(opt.model))[0]+"_normalized.obj")
    pymesh.save_mesh_raw(os.path.join(opt.log_dir, opt.subdir, "template-initial.obj"),
                         shape_v[0].cpu().numpy(), shape_f[0].cpu().numpy())
    pymesh.save_mesh_raw(os.path.join(opt.log_dir, opt.subdir, "cage-initial.obj"),
                         cage_v[0].cpu().numpy(), cage_f[0].cpu().numpy())
    save_ply(target_points[0].cpu().numpy(), os.path.join(
        opt.log_dir, opt.subdir, "target_points.ply"))
    save_ply(source_points[0].cpu().numpy(), os.path.join(
        opt.log_dir, opt.subdir, "source_points.ply"))
    logger.info("Optimizing for {} corresponding vertices".format(
        target_points.shape[1]))

    cage_init = cage_v.clone().detach()
    lap_loss = MeshLaplacianLoss(torch.nn.MSELoss(reduction="none"), use_cot=True,
                                 use_norm=True, consistent_topology=True, precompute_L=True)
    mvc_reg_loss = MVCRegularizer(threshold=50, beta=1.0, alpha=0.0)
    cage_v.requires_grad_(True)
    optimizer = torch.optim.Adam([cage_v], lr=opt.lr, betas=(0.5, 0.9))
    scheduler = torch.optim.lr_scheduler.StepLR(optimizer, int(opt.nepochs*0.4), gamma=0.5, last_epoch=-1)

    if opt.dim == 3:
        weights_ref = mean_value_coordinates_3D(
            source_points, cage_init, cage_f, verbose=False)
    else:
        raise NotImplementedError

    for t in range(opt.nepochs):
        optimizer.zero_grad()
        weights = mean_value_coordinates_3D(
            target_points, cage_v, cage_f, verbose=False)
        loss_mvc = torch.mean((weights-weights_ref)**2)
        # reg = torch.sum((cage_init-cage_v)**2, dim=-1)*1e-4
        reg = 0
        if opt.clap_weight > 0:
            reg = lap_loss(cage_init, cage_v, face=cage_f)*opt.clap_weight
            reg = reg.mean()
        if opt.mvc_weight > 0:
            reg += mvc_reg_loss(weights)*opt.mvc_weight

        # weight regularizer with the shape difference
        # dist = torch.sum((source_points - target_points)**2, dim=-1)
        # weights = torch.exp(-dist)
        # reg = reg*weights*0.1

        loss = loss_mvc + reg
        if (t+1) % 50 == 0:
            print("t {}/{} mvc_loss: {} reg: {}".format(t,
                                                        opt.nepochs, loss_mvc.item(), reg.item()))

        if loss_mvc.item() < 5e-6:
            break
        loss.backward()
        optimizer.step()
        scheduler.step()

    return cage_v, cage_f
def save_as_ply(filename, new_filename):
    mesh = pymesh.load_mesh(filename)
    vertices = mesh.vertices
    faces = mesh.faces
    pymesh.save_mesh_raw(new_filename, vertices, faces)
Exemplo n.º 26
0
from common import read_trimesh

work_dir = sys.argv[1]
output_dir = sys.argv[2]
sources = glob(os.path.join(work_dir, "*Sa.*"))
logger.info("Found {} source files".format(len(sources)))

os.makedirs(output_dir, exist_ok=True)

for source in sources:
    target = source.replace("Sa", "Sb")
    fn = os.path.basename(target)
    fn = fn.replace("Sb", "Sab")
    V_t, F_t = read_trimesh(target, clean=True)
    V_t = V_t[:,:3]
    V_s, F_s = read_trimesh(source, clean=True)
    V_s = V_s[:,:3]

    bb_max = np.max(V_t, axis=0)
    bb_min = np.min(V_t, axis=0)
    size_t = (bb_max - bb_min)

    bb_max = np.max(V_s, axis=0)
    bb_min = np.min(V_s, axis=0)
    size_s = (bb_max - bb_min)

    V_st = (V_s * size_t/size_s)
    pymesh.save_mesh(os.path.join(output_dir, fn.replace("Sab", "Sa")), pymesh.form_mesh(V_s, F_s))
    pymesh.save_mesh(os.path.join(output_dir, fn.replace("Sab", "Sb")), pymesh.form_mesh(V_t, F_t))
    pymesh.save_mesh_raw(os.path.join(output_dir, fn), V_st, F_s)