Esempio n. 1
0
def save_to_mesh(file_path, v, f):
    """
        v : vertex data.
        f : face data.

    """
    igl.write_triangle_mesh(file_path, v, f)
    def transform(self, v: np.ndarray, f: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:

        # nv, nf, _, _, _ = igl.offset_surface(v, f, 0, 64, SIGNED_DISTANCE_TYPE_PSEUDONORMAL)

        igl.write_triangle_mesh("/home/zgong8/temp/mc_tmp_in.obj", v, f)
        subprocess.run(["/home/zgong8/libigl/tutorial/build/bin/705_MarchingCubes", "/home/zgong8/temp/mc_tmp_in.obj", "/home/zgong8/temp/mc_tmp_out_1.obj", "/home/zgong8/temp/mc_tmp_out_2.obj"])
        nv, nf = igl.read_triangle_mesh("/home/zgong8/temp/mc_tmp_out_2.obj", np.float64)
        return nv, nf
Esempio n. 3
0
def write_mesh(data_dir, vert, face, input_name):
    mesh_dir = os.path.join(data_dir, "meshes/")
    sysutil.mkdirs(mesh_dir)
    if vert.shape[0] < 10:
        vert, face = np.array([[0, 0, 0.]]), np.array([[0, 0, 0]])
    igl.write_triangle_mesh(os.path.join(mesh_dir, input_name + ".ply"),
                            vert,
                            face,
                            force_ascii=False)
Esempio n. 4
0
 def process_shape_file(self, in_file: str, out_file: str):
     assert self.is_full()
     vertices, faces = igl.read_triangle_mesh(in_file, np.float64)
     new_vertices, new_faces = self.process_shape_data(vertices, faces)
     if new_faces is not None:
         if len(new_faces) < max_output_faces:
             igl.write_triangle_mesh(out_file, new_vertices, new_faces)
             return True
         else:
             print("Too large, bad for connection, dropped in the end.")
     return False
Esempio n. 5
0
def inner_surface(in_path, out_path, depth=1, nsteps=1):
    '''compute inner surfaces from mesh at in_path, save results'''
    # load input mesh
    v, f = igl.read_triangle_mesh(in_path)

    v2array = inner_surface_mesh(v, f, depth=depth, nsteps=nsteps)

    if nsteps == 1:
        igl.write_triangle_mesh(out_path, v2array[0], f, force_ascii=False)
    else:
        split = out_path.split(".")
        for step in range(nsteps):
            step_str = "%03i" % (step + 1)
            out_path_step = ".".join([*(split[:-2]), step_str, split[-1]])
            igl.write_triangle_mesh(out_path_step,
                                    v2array[step],
                                    f,
                                    force_ascii=False)
try:
    # get binary mask
    nii = nib.load(in_file)
    binary_mask = nii.get_fdata()

    # get affine translation
    dx = nii.affine[0][3]
    dy = nii.affine[1][3]
    dz = nii.affine[2][3]
    aff = np.asarray([-dx, -dy, dz])
    # print(nii.affine)

    # create mesh
    distance = distance_transform_edt(binary_mask)
    verts, faces, _, _ = measure.marching_cubes(
        distance,
        0,
        spacing=(abs(nii.affine[0][0]), abs(nii.affine[1][1]),
                 abs(nii.affine[2][2])),
        gradient_direction="ascent",
        method='lewiner')

    # apply affine translation to vertices
    verts2 = [v + aff for v in verts]
    verts2 = np.asarray(verts2)

    # save
    igl.write_triangle_mesh(out_file, verts2, faces)
except:
    print('ERROR: cannot create ' + sys.argv[2])
Esempio n. 7
0
# make apex covariance sharper
c[0] *= 0.001
vs2, fs2 = loop_gps(v, f, c, 5)

# make apex covariance vertically anisotropic (reduce variance in x direction)
c[0] = [[0.001, 0, 0], [0, 0.01, 0], [0, 0, 0.01]]
vs3, fs3 = loop_gps(v, f, c, 5)

# make apex covariance horizontally anisotropic (reduce variance in y direction)
c[0] = [[0.01, 0, 0], [0, 0.001, 0], [0, 0, 0.01]]
vs4, fs4 = loop_gps(v, f, c, 5)

# make apex covariance horizontally anisotropic and super flat
c[0] = [[1, 0, 0], [0, 0.00001, 0], [0, 0, 1]]
vs5, fs5 = loop_gps(v, f, c, 5)

# save meshes to .off files
igl.write_triangle_mesh(os.path.join(root_folder, "data", "cone.off"), v, f)
print("Wrote control mesh to", os.path.join(root_folder, "data", "cone.off"))

igl.write_triangle_mesh(
    os.path.join(root_folder, "data", "cone-pointy-gps.off"), vs2, fs2)
igl.write_triangle_mesh(
    os.path.join(root_folder, "data", "cone-concave-gps.off"), vs3, fs3)
igl.write_triangle_mesh(
    os.path.join(root_folder, "data", "cone-plateau-gps.off"), vs4, fs4)
igl.write_triangle_mesh(
    os.path.join(root_folder, "data", "cone-cylinder-gps.off"), vs5, fs5)
print("Wrote GPS meshes to",
      os.path.join(root_folder, "data", "cone-<variant>-gps.off"))
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))
# 1. Install miniconda (python 3.7 version, windows 64 bits)
# 2. In a miniconda terminal run conda install igl
# 3. Swap to this python compiler in pycharm

import igl
import numpy as np
import os

#Change this to point to your subject folder
root_folder = '.'
subject_id_usr = os.path.join(root_folder, 'subjects folder', 'subject_01')

#Make sure you've at least simplified the mesh of the subject
vertices = np.load(os.path.join(subject_id_usr, 'vertices_simple.npy'))
faces = np.load(os.path.join(subject_id_usr, 'faces_simple.npy'))

ret = igl.write_triangle_mesh(os.path.join(subject_id_usr, "bunny_out.obj"),
                              vertices, faces)

v, f = igl.read_triangle_mesh(os.path.join(subject_id_usr, "bunny_out.obj"))
[pd1, pd2, pv1, pv2] = igl.principal_curvature(v, f, radius=5, use_k_ring=True)
#Mean curvature is (pv1+pv2)/2 and Gaussian curvature is pv1*pv2
# k = igl.gaussian_curvature(v, f)
np.save(os.path.join(subject_id_usr, 'mean_curv_simple.npy'), (pv1 + pv2) / 2)

#Deletes temporary object
os.remove(os.path.join(subject_id_usr, "bunny_out.obj"))
 def test_write_triangle_mesh(self):
     ok = igl.write_triangle_mesh("out.obj", self.v, self.f)
     self.assertEqual(ok, True)
Esempio n. 11
0
def mesh_model(model, res_path, convert=True, all_edges=True):
    fil = model.split("/")[-1][:-5]
    folder = "/".join(model.split("/")[:-1])
    with fileinput.FileInput(model, inplace=True) as fi:
        for line in fi:
            print(line.replace(
                "UNCERTAINTY_MEASURE_WITH_UNIT( LENGTH_MEASURE( 1.00000000000000E-06 )",
                "UNCERTAINTY_MEASURE_WITH_UNIT( LENGTH_MEASURE( 1.00000000000000E-17 )"
            ),
                  end='')

    occ_steps = read_step_file(model)
    bt = BRep_Tool()

    for occ_cnt in range(len(occ_steps)):
        if convert:
            try:
                nurbs_converter = BRepBuilderAPI_NurbsConvert(
                    occ_steps[occ_cnt])
                nurbs_converter.Perform(occ_steps[occ_cnt])
                nurbs = nurbs_converter.Shape()
            except:
                print("Conversion failed")
                continue
        else:
            nurbs = occ_steps[occ_cnt]

        mesh = BRepMesh_IncrementalMesh(occ_steps[occ_cnt], 0.9, False, 0.5,
                                        True)
        mesh.Perform()
        if not mesh.IsDone():
            print("Mesh is not done.")
            continue

        occ_topo = TopologyExplorer(nurbs)
        occ_top = Topo(nurbs)
        occ_topo1 = TopologyExplorer(occ_steps[occ_cnt])
        occ_top1 = Topo(occ_steps[occ_cnt])

        d1_feats = []
        d2_feats = []
        t_curves = []
        tr_curves = []
        stats = {}
        stats["model"] = model
        total_edges = 0
        total_surfs = 0
        stats["curves"] = []
        stats["surfs"] = []
        c_cnt = 0
        t_cnt = 0

        # Iterate over edges
        for edge in occ_topo.edges():
            curve = BRepAdaptor_Curve(edge)
            stats["curves"].append(edge_map[curve.GetType()])
            d1_feat = convert_curve(curve)

            if edge_map[curve.GetType()] == "Other":
                continue

            for f in occ_top.faces_from_edge(edge):
                if f == None:
                    print("Broken face")
                    continue
                su = BRepAdaptor_Surface(f)
                c = BRepAdaptor_Curve2d(edge, f)
                t_curve = {
                    "surface": f,
                    "3dcurve": edge,
                    "3dcurve_id": c_cnt,
                    "2dcurve_id": t_cnt
                }
                t_curves.append(t_curve)
                tr_curves.append(convert_2dcurve(c))
                t_cnt += 1

            d1_feats.append(d1_feat)
            c_cnt += 1
            total_edges += 1

        patches = []
        faces1 = list(occ_topo1.faces())
        # Iterate over faces
        for fci, face in enumerate(occ_topo.faces()):
            surf = BRepAdaptor_Surface(face)
            stats["surfs"].append(surf_map[surf.GetType()])
            d2_feat = convert_surface(surf)

            if surf_map[surf.GetType()] == "Other":
                continue

            for tc in t_curves:
                if tc["surface"] == face:
                    patch = {
                        "3dcurves": [],
                        "2dcurves": [],
                        "orientations": [],
                        "surf_orientation": face.Orientation(),
                        "wire_ids": [],
                        "wire_orientations": []
                    }

                    for wc, fw in enumerate(occ_top.wires_from_face(face)):
                        patch["wire_orientations"].append(fw.Orientation())
                        if all_edges:
                            edges = [
                                i for i in WireExplorer(fw).ordered_edges()
                            ]
                        else:
                            edges = list(occ_top.edges_from_wire(fw))
                        for fe in edges:
                            for ttc in t_curves:
                                if ttc["3dcurve"].IsSame(fe) and tc[
                                        "surface"] == ttc["surface"]:
                                    patch["3dcurves"].append(ttc["3dcurve_id"])
                                    patch["2dcurves"].append(ttc["2dcurve_id"])
                                    patch["wire_ids"].append(wc)
                                    orientation = fe.Orientation()
                                    patch["orientations"].append(orientation)

                    patches.append(patch)
                    break

            location = TopLoc_Location()
            facing = (bt.Triangulation(faces1[fci], location))
            if facing != None:
                tab = facing.Nodes()
                tri = facing.Triangles()
                verts = []
                for i in range(1, facing.NbNodes() + 1):
                    verts.append(list(tab.Value(i).Coord()))

                faces = []
                for i in range(1, facing.NbTriangles() + 1):
                    index1, index2, index3 = tri.Value(i).Get()
                    faces.append([index1 - 1, index2 - 1, index3 - 1])

                os.makedirs(res_path, exist_ok=True)
                igl.write_triangle_mesh(
                    "%s/%s_%03i_mesh_%04i.obj" % (res_path, fil, occ_cnt, fci),
                    np.array(verts), np.array(faces))
                d2_feat["faces"] = faces
                d2_feat["verts"] = verts
            else:
                print("Missing triangulation")
                continue

            d2_feats.append(d2_feat)
            total_surfs += 1

        bbox = get_boundingbox(occ_steps[occ_cnt], use_mesh=False)
        xmin, ymin, zmin, xmax, ymax, zmax = bbox[:6]
        bbox1 = [
            "%.2f" % xmin,
            "%.2f" % ymin,
            "%.2f" % zmin,
            "%.2f" % xmax,
            "%.2f" % ymax,
            "%.2f" % zmax,
            "%.2f" % (xmax - xmin),
            "%.2f" % (ymax - ymin),
            "%.2f" % (zmax - zmin)
        ]
        stats["#edges"] = total_edges
        stats["#surfs"] = total_surfs

        # Fix possible orientation problems
        if convert:
            for p in patches:

                # Check orientation of first curve
                if len(p["2dcurves"]) >= 2:
                    cur = tr_curves[p["2dcurves"][0]]
                    nxt = tr_curves[p["2dcurves"][1]]
                    c_ori = p["orientations"][0]
                    n_ori = p["orientations"][1]
                    if c_ori == 0:
                        pole0 = np.array(cur["poles"][0])
                        pole1 = np.array(cur["poles"][-1])
                    else:
                        pole0 = np.array(cur["poles"][-1])
                        pole1 = np.array(cur["poles"][0])

                    if n_ori == 0:
                        pole2 = np.array(nxt["poles"][0])
                        pole3 = np.array(nxt["poles"][-1])
                    else:
                        pole2 = np.array(nxt["poles"][-1])
                        pole3 = np.array(nxt["poles"][0])

                    d02 = np.abs(pole0 - pole2)
                    d12 = np.abs(pole1 - pole2)
                    d03 = np.abs(pole0 - pole3)
                    d13 = np.abs(pole1 - pole3)

                    amin = np.argmin([d02, d12, d03, d13])

                    if amin == 0 or amin == 2:  # Orientation of first curve incorrect, fix
                        p["orientations"][0] = abs(c_ori - 1)

                # Fix all orientations
                for i in range(len(p["2dcurves"]) - 1):
                    cur = tr_curves[p["2dcurves"][i]]
                    nxt = tr_curves[p["2dcurves"][i + 1]]
                    c_ori = p["orientations"][i]
                    n_ori = p["orientations"][i + 1]
                    if c_ori == 0:
                        pole1 = np.array(cur["poles"][-1])
                    else:
                        pole1 = np.array(cur["poles"][0])

                    if n_ori == 0:
                        pole2 = np.array(nxt["poles"][0])
                        pole3 = np.array(nxt["poles"][-1])
                    else:
                        pole2 = np.array(nxt["poles"][-1])
                        pole3 = np.array(nxt["poles"][0])

                    d12 = np.abs(pole1 - pole2)
                    d13 = np.abs(pole1 - pole3)

                    amin = np.min([d12, d13])

                    if amin == 1:  # Incorrect orientation, flip
                        p["orientations"][i + 1] = abs(n_ori - 1)

        features = {
            "curves": d1_feats,
            "surfaces": d2_feats,
            "trim": tr_curves,
            "topo": patches,
            "bbox": bbox1
        }

        os.makedirs(res_path, exist_ok=True)
        fip = fil + "_features2"
        with open("%s/%s_%03i.yml" % (res_path, fip, occ_cnt), "w") as fili:
            yaml.dump(features, fili, indent=2)

        fip = fil + "_features"
        with open("%s/%s_%03i.yml" % (res_path, fip, occ_cnt), "w") as fili:
            features2 = copy.deepcopy(features)
            for sf in features2["surfaces"]:
                del sf["faces"]
                del sf["verts"]
            yaml.dump(features2, fili, indent=2)


#        res_path = folder.replace("/step/", "/stat/")
#        fip = fil + "_stats"
#        with open("%s/%s_%03i.yml"%(res_path, fip, occ_cnt), "w") as fili:
#            yaml.dump(stats, fili, indent=2)

    print("Writing results for %s with %i parts." % (model, len(occ_steps)))
Esempio n. 12
0
# 3. perform Gaussian-product subdivision
#    note: igl.loop only handles 3D subdivs -> split the 9D mesh into three 3D ones
for _ in range(4):
    qq1, f = igl.loop(qq1, cm.f)
    qq2, f = igl.loop(qq2, cm.f)
    qlin, cm.f = igl.loop(qlin, cm.f)

    
# 4. transform back to 3D
cm.v = np.zeros((len(qlin),3))
for i, ql in enumerate(qlin):
    icov = [qq1[i],
            [qq1[i][1], qq2[i][0], qq2[i][1]],
            [qq1[i][2], qq2[i][1], qq2[i][2]]]
    cm.v[i] = np.linalg.inv(icov) @ ql


#------------------------------------------------------------------------------------------

# save meshes to .off file

path = os.path.join(root_folder, "data", "tweety-loop.off")
igl.write_triangle_mesh(path, lmesh.v, lmesh.f)
print("Wrote Loop mesh to", path)

path = os.path.join(root_folder, "data", "tweety-gps.off")
igl.write_triangle_mesh(path, cm.v, cm.f)
print("Wrote GPS mesh to", path)