Пример #1
0
def clean_up_mesh(mesh, tol):
    new_mesh, _ = pymesh.remove_isolated_vertices(mesh)
    new_mesh, _ = pymesh.remove_duplicated_vertices(new_mesh)
    new_mesh, _ = pymesh.remove_duplicated_faces(new_mesh)
    new_mesh, _ = pymesh.remove_degenerated_triangles(new_mesh)
    new_mesh, _ = pymesh.collapse_short_edges(new_mesh, rel_threshold=0.2)
    return new_mesh
Пример #2
0
def map_boundary_to_sphere(mesh, basename):
    bd_mesh = pymesh.form_mesh(mesh.vertices, mesh.faces)
    bd_mesh, info = pymesh.remove_isolated_vertices(bd_mesh)
    bd_vertices = np.copy(bd_mesh.vertices)

    assembler = pymesh.Assembler(bd_mesh)
    L = assembler.assemble("graph_laplacian")

    # First, Laplacian smoothing to improve triangle quality.
    for i in range(100):
        c = np.mean(bd_vertices, axis=0)
        bd_vertices = bd_vertices - c
        r = np.amax(norm(bd_vertices, axis=1))
        bd_vertices /= r

        bd_vertices += L * bd_vertices

        if i % 10 == 0:
            sphere_mesh = pymesh.form_mesh(bd_vertices, bd_mesh.faces)
            pymesh.save_mesh("{}_flow_{:03}.msh".format(basename, i),
                             sphere_mesh)

    # Then, run mean curvature flow.
    sphere_mesh = pymesh.form_mesh(bd_vertices, bd_mesh.faces)
    sphere_mesh = mean_curvature_flow(sphere_mesh,
                                      100,
                                      use_graph_laplacian=True)
    pymesh.save_mesh("{}_flow_final.msh".format(basename), sphere_mesh)
    bd_vertices = sphere_mesh.vertices

    # Lastly, project vertices onto unit sphere.
    bd_vertex_indices = info["ori_vertex_index"]
    bd_vertex_positions = np.divide(bd_vertices,
                                    norm(bd_vertices, axis=1).reshape((-1, 1)))
    return bd_vertex_indices, bd_vertex_positions
Пример #3
0
def fix_mesh(mesh, resolution):
    bbox_min, bbox_max = mesh.bbox
    diag_len = norm(bbox_max - bbox_min)

    target_len = diag_len * resolution

    rospy.loginfo("\tTarget resolution: {} mm".format(target_len))

    count = 0
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 100)
    mesh, __ = pymesh.split_long_edges(mesh, target_len)
    num_vertices = mesh.num_vertices
    while True:
        mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6)
        mesh, __ = pymesh.collapse_short_edges(mesh,
                                               target_len,
                                               preserve_feature=True)
        mesh, __ = pymesh.remove_obtuse_triangles(mesh, 150.0, 100)
        if mesh.num_vertices == num_vertices:
            break

        num_vertices = mesh.num_vertices
        rospy.loginfo("\t#vertices: {}".format(num_vertices))
        count += 1
        if count > 2: break

    mesh = pymesh.resolve_self_intersection(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh = pymesh.compute_outer_hull(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5)
    mesh, __ = pymesh.remove_isolated_vertices(mesh)

    return mesh
Пример #4
0
        def finalMesh(z):
            poolWarning = None

            # Check if pools will overflow mesh
            if z > zMax:
                z = zMax
                poolWarning = 'The pool have a greater volume than the mesh can contain. Pool set to fill entire mesh.'

            # Create Bbox
            bMesh = createBbox(z)

            # Make intersection
            newMesh, bottomFaces, boolWarning = intersectAndBottomFaces(bMesh, z)

            # Create volume mesh
            volMesh = getVolMesh(newMesh, bottomFaces, z)

            volMesh.add_attribute('voxel_volume')
            volVol = volMesh.get_attribute('voxel_volume')
            volVol = sum(list(map(abs, volVol)))

            # Clean up mesh
            volMesh, info = pm.remove_isolated_vertices(volMesh)
            #print('num vertex removed', info["num_vertex_removed"])
            volMesh, info = pm.remove_duplicated_faces(volMesh)

            return volMesh, volVol, poolWarning, poolWarning
Пример #5
0
def map_boundary_to_sphere(mesh, basename):
    bd_mesh = pymesh.form_mesh(mesh.vertices, mesh.faces);
    bd_mesh, info = pymesh.remove_isolated_vertices(bd_mesh);
    bd_vertices = np.copy(bd_mesh.vertices);

    assembler = pymesh.Assembler(bd_mesh);
    L = assembler.assemble("graph_laplacian");

    # First, Laplacian smoothing to improve triangle quality.
    for i in range(100):
        c = np.mean(bd_vertices, axis=0);
        bd_vertices = bd_vertices - c;
        r = np.amax(norm(bd_vertices, axis=1));
        bd_vertices /= r;

        bd_vertices += L * bd_vertices;

        if i%10 == 0:
            sphere_mesh = pymesh.form_mesh(bd_vertices, bd_mesh.faces);
            pymesh.save_mesh("{}_flow_{:03}.msh".format(basename, i), sphere_mesh);

    # Then, run mean curvature flow.
    sphere_mesh = pymesh.form_mesh(bd_vertices, bd_mesh.faces);
    sphere_mesh = mean_curvature_flow(sphere_mesh, 100, use_graph_laplacian=True);
    pymesh.save_mesh("{}_flow_final.msh".format(basename), sphere_mesh);
    bd_vertices = sphere_mesh.vertices;

    # Lastly, project vertices onto unit sphere.
    bd_vertex_indices = info["ori_vertex_index"];
    bd_vertex_positions = np.divide(bd_vertices, norm(bd_vertices,
        axis=1).reshape((-1,1)));
    return bd_vertex_indices, bd_vertex_positions;
Пример #6
0
def clean_mesh(mesh, connected=True, fill_internals=False):
    print('\t - Cleaning mesh (this may take a moment)')
    vert_list = []
    mesh, info = pymesh.remove_isolated_vertices(mesh)
    mesh, info = pymesh.remove_duplicated_vertices(mesh)
    mesh, info = pymesh.remove_degenerated_triangles(mesh)
    mesh, info = pymesh.remove_duplicated_faces(mesh)

    if connected or fill_internals:
        mesh_list = pymesh.separate_mesh(mesh, 'auto')
        max_verts = 0
        print(' - Total number of meshes (ideally 1): %d' % len(mesh_list))
        for mesh_obj in mesh_list:
            nverts = mesh_obj.num_vertices
            if nverts > max_verts:
                max_verts = nverts
                mesh = mesh_obj

        if fill_internals:
            for mesh_obj in mesh_list:
                if mesh_obj.num_vertices != max_verts:
                    vert_list.append(mesh_obj.vertices)

            return mesh, vert_list

    return mesh, vert_list
Пример #7
0
def fix_mesh(mesh, detail=5e-3):
    # "normal": 5e-3
    # "high":   2.5e-3
    # "low":    2e-2
    # "vlow":   2.5e-2
    bbox_min, bbox_max = mesh.bbox
    diag_len = np.linalg.norm(bbox_max - bbox_min)
    if detail is None:
        detail = 5e-3
    target_len = diag_len * detail
    print("Target resolution: {} mm".format(target_len))

    count = 0
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 100)
    mesh, __ = pymesh.split_long_edges(mesh, target_len)
    num_vertices = mesh.num_vertices
    while True:
        mesh, __ = pymesh.collapse_short_edges(mesh, 1e-4)
        mesh, __ = pymesh.collapse_short_edges(mesh,
                                               target_len,
                                               preserve_feature=True)

        mesh, __ = pymesh.remove_isolated_vertices(mesh)
        mesh, __ = pymesh.remove_duplicated_vertices(mesh, tol=1e-4)
        mesh, __ = pymesh.remove_duplicated_faces(mesh)
        mesh, __ = pymesh.remove_degenerated_triangles(mesh)
        mesh, __ = pymesh.remove_isolated_vertices(mesh)

        mesh, __ = pymesh.remove_obtuse_triangles(mesh, 150.0, 100)
        if mesh.num_vertices == num_vertices:
            break

        num_vertices = mesh.num_vertices
        print("fix #v: {}".format(num_vertices))
        count += 1
        if count > 10:
            break

    mesh = pymesh.resolve_self_intersection(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh = pymesh.compute_outer_hull(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5)
    mesh, __ = pymesh.remove_isolated_vertices(mesh)

    return mesh
def inc_remesh(mesh, detail="normal"):
    bbox_min, bbox_max = mesh.bbox
    diag_len = norm(bbox_max - bbox_min)
    if detail == "normal":
        target_len = diag_len * 5e-3
    elif detail == "high":
        target_len = diag_len * 2.5e-3
    elif detail == "low":
        target_len = diag_len * 2.5e-2
    print("Target resolution: {} mm".format(target_len))

    count = 1

    #
    # mesh = pymesh.resolve_self_intersection(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    # mesh = pymesh.compute_outer_hull(mesh)
    # mesh, __ = pymesh.remove_duplicated_faces(mesh)

    mesh, __ = pymesh.remove_isolated_vertices(mesh)

    num_vertices = mesh.num_vertices

    low = 4 / 5 * target_len
    high = 4 / 3 * target_len

    while True:
        print()
        print("[iteration " + str(count) + "]")
        # mesh, __ = pymesh.split_long_edges(mesh, high)
        # print("<split_long_edges> :      DONE")
        # mesh, __ = pymesh.collapse_short_edges(mesh, low, preserve_feature=True)
        # print("<collapse_short_edges> :  DONE")
        check_mesh(mesh)
        mesh = equalize_valences(mesh)
        print("<equalize_valences> :     DONE")
        # mesh = tangential_relaxation(mesh)
        # print("<tangential_relaxation> : DONE")

        if mesh.num_vertices == num_vertices: break

        num_vertices = mesh.num_vertices
        print("#v: {}".format(num_vertices))
        count += 1
        if count > 10: break

    # mesh = pymesh.resolve_self_intersection(mesh)
    # mesh, __ = pymesh.remove_duplicated_faces(mesh)
    # mesh = pymesh.compute_outer_hull(mesh)
    # mesh, __ = pymesh.remove_duplicated_faces(mesh)
    # mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5)
    # mesh, __ = pymesh.remove_isolated_vertices(mesh)

    check_mesh(mesh)

    return mesh
Пример #9
0
def fix_meshes(mesh, detail="normal"):
    meshCopy = mesh

    # copy/pasta of pymesh script fix_mesh from qnzhou, see pymesh on GitHub
    bbox_min, bbox_max = mesh.bbox
    diag_len = np.linalg.norm(bbox_max - bbox_min)
    if detail == "normal":
        target_len = diag_len * 5e-3
    elif detail == "high":
        target_len = diag_len * 2.5e-3
    elif detail == "low":
        target_len = diag_len * 1e-2

    count = 0
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 100)
    mesh, __ = pymesh.split_long_edges(mesh, target_len)
    num_vertices = mesh.num_vertices
    while True:
        mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6)
        mesh, __ = pymesh.collapse_short_edges(mesh,
                                               target_len,
                                               preserve_feature=True)
        mesh, __ = pymesh.remove_obtuse_triangles(mesh, 150.0, 100)
        if mesh.num_vertices == num_vertices:
            break

        num_vertices = mesh.num_vertices
        count += 1
        if count > 10:
            break

    mesh = pymesh.resolve_self_intersection(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh = pymesh.compute_outer_hull(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5)
    mesh, __ = pymesh.remove_isolated_vertices(mesh)

    if is_mesh_broken(mesh, meshCopy) is True:
        if detail == "high":
            print(
                f'The function fix_meshes broke mesh, trying with lower details settings'
            )
            fix_meshes(mesh, detail="normal")
        if detail == "normal":
            print(
                f'The function fix_meshes broke mesh, trying with lower details settings'
            )
            fix_meshes(mesh, detail="low")
        if detail == "low":
            print(
                f'The function fix_meshes broke mesh, no lower settings can be applied, no fix was done'
            )
            return meshCopy
    else:
        return mesh
Пример #10
0
def convert_obj2ply(obj_filename,
                    ply_filename,
                    recenter=False,
                    center_mode='pt_center'):
    mesh = pymesh.load_mesh(obj_filename)
    pymesh.remove_isolated_vertices(mesh)

    if recenter:
        if center_mode == 'pt_center':
            center = np.mean(mesh.vertices, axis=0)
        elif center_mode == 'box_center':
            min_p = np.amin(mesh.vertices, axis=0)
            max_p = np.amax(mesh.vertices, axis=0)
            center = (min_p + max_p) / 2.0

        new_vertices = mesh.vertices - center
        mesh = pymesh.form_mesh(new_vertices, mesh.faces)

    pymesh.save_mesh(ply_filename, mesh)
Пример #11
0
 def _load_mesh(desc):
     path = desc['objs_dir']
     objs = desc['objs']
     mesh_list = []
     for obj in eval(objs):
         obj_path = os.path.join(path, obj + '.obj')
         mesh_tmp = load_pc(obj_path)
         mesh_tmp, info = pymesh.remove_isolated_vertices(mesh_tmp)
         mesh_list.append(mesh_tmp)
     mesh = pymesh.merge_meshes(mesh_list)
     return mesh
Пример #12
0
def clean(vertices, faces, duplicate_tol=1e-12):
    mesh = pymesh.meshio.form_mesh(vertices, faces)
    mesh = pymesh.remove_isolated_vertices(mesh)[0]
    mesh = pymesh.remove_duplicated_vertices(mesh, tol=duplicate_tol)[0]
    mesh = remove_duplicated_faces(mesh)[0]
    # mesh = pymesh.remove_duplicated_faces(mesh, fins_only=True)[0]
    mesh = pymesh.remove_degenerated_triangles(mesh)[0]
    mesh = pymesh.resolve_self_intersection(mesh)
    # meshes = pymesh.separate_mesh(mesh)
    # for i, mesh in enumerate(meshes):
    #     meshes[i] = make_face_normals_consistent(mesh)
    # mesh = pymesh.merge_meshes(meshes)
    return mesh.vertices, mesh.faces
def extract_intersecting_faces(mesh, selection):
    face_pairs = pymesh.detect_self_intersection(mesh);
    selected_faces = np.zeros(mesh.num_faces, dtype=bool);

    if selection is not None:
        selected_pairs = np.any(face_pairs == selection, axis=1);
        face_pairs = face_pairs[selected_pairs];

    selected_faces[face_pairs[:,0]] = True;
    selected_faces[face_pairs[:,1]] = True;
    faces = mesh.faces[selected_faces];
    intersecting_mesh = pymesh.form_mesh(mesh.vertices, faces);
    intersecting_mesh, __ = pymesh.remove_isolated_vertices(intersecting_mesh);
    return intersecting_mesh;
def extract_intersecting_faces(mesh, selection):
    face_pairs = pymesh.detect_self_intersection(mesh)
    selected_faces = np.zeros(mesh.num_faces, dtype=bool)

    if selection is not None:
        selected_pairs = np.any(face_pairs == selection, axis=1)
        face_pairs = face_pairs[selected_pairs]

    selected_faces[face_pairs[:, 0]] = True
    selected_faces[face_pairs[:, 1]] = True
    faces = mesh.faces[selected_faces]
    intersecting_mesh = pymesh.form_mesh(mesh.vertices, faces)
    intersecting_mesh, __ = pymesh.remove_isolated_vertices(intersecting_mesh)
    return intersecting_mesh
Пример #15
0
def remesh(path1):
    """
    This function takes a path to the orginal shapenet model and subsample it nicely
    """
    obj1 = pymesh.load_mesh(path1)
    obj1, info = pymesh.remove_isolated_vertices(obj1)
    print("Removed {} isolated vertices".format(info["num_vertex_removed"]))
    obj1, info = pymesh.remove_duplicated_vertices(obj1)
    print("Merged {} duplicated vertices".format(info["num_vertex_merged"]))
    obj1, _ = pymesh.remove_degenerated_triangles(obj1)
    if len(obj1.vertices) < 5000:
        while len(obj1.vertices) < 5000:
            obj1 = pymesh.subdivide(obj1)
    obj1 = pymesh.form_mesh(obj1.vertices, obj1.faces)
    return obj1
def link(path1):
    """
	This function takes a path to the orginal shapenet model and subsample it nicely
	"""
    obj1 = pymesh.load_mesh(path1)
    # obj1, info = pymesh.remove_isolated_vertices(mesh)
    obj1, info = pymesh.remove_isolated_vertices(obj1)
    print("Removed {} isolated vertices".format(info["num_vertex_removed"]))
    obj1, info = pymesh.remove_duplicated_vertices(obj1)
    print("Merged {} duplicated vertices".format(info["num_vertex_merged"]))
    obj1, info = pymesh.remove_degenerated_triangles(obj1)
    new_mesh = pymesh.form_mesh(
        normalize_points.BoundingBox(torch.from_numpy(obj1.vertices)).numpy(),
        obj1.faces)
    return new_mesh
Пример #17
0
def read_trimesh(path, normal=False, clean=True):
    mesh = pymesh.load_mesh(path)
    if clean:
        mesh, info = pymesh.remove_isolated_vertices(mesh)
        print("Removed {} isolated vertices".format(info["num_vertex_removed"]))
        mesh, info = pymesh.remove_duplicated_vertices(mesh)
        print("Merged {} duplicated vertices".format(info["num_vertex_merged"]))
        mesh, info = pymesh.remove_degenerated_triangles(mesh)
        mesh = pymesh.form_mesh(mesh.vertices, mesh.faces)

    vertices = mesh.vertices
    if normal:
        mesh.add_attribute("vertex_normal")
        vertex_normals = mesh.get_attribute("vertex_normal").reshape(-1, 3)
        vertices = np.concatenate([vertices, vertex_normals], axis=-1)
    return vertices, mesh.faces
Пример #18
0
def fix_mesh(mesh):
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 100)
    log_mesh(mesh, "Remove degenerate faces")
    mesh, __ = pymesh.collapse_short_edges(mesh, MIN_RES, preserve_feature=True)
    log_mesh(mesh, "Collapse short edges")
    mesh = pymesh.resolve_self_intersection(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    log_mesh(mesh, "Remove self intersections")
    mesh = pymesh.compute_outer_hull(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    log_mesh(mesh, "New hull, remove duplicates")
    mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.5, 5)
    log_mesh(mesh, "Remote obtuse faces")
    mesh, __ = pymesh.remove_isolated_vertices(mesh)
    log_mesh(mesh, "Remove isolated vertices")
    return mesh
    def execute(self, context):
        scene = context.scene
        pymesh_props = scene.pymesh

        obj_a = context.active_object
        mesh_a = import_object(context, obj_a)
        pymesh_r, info = pymesh.remove_degenerated_triangles(mesh_a)
        pymesh_r, info = pymesh.remove_obtuse_triangles(pymesh_r)
        pymesh_r, info = pymesh.remove_duplicated_faces(pymesh_r)
        pymesh_r, info = pymesh.collapse_short_edges(pymesh_r)
        pymesh_r, info = pymesh.remove_duplicated_vertices(pymesh_r)
        pymesh_r, info = pymesh.remove_isolated_vertices(pymesh_r)
        off_name = "Py.Clean." + obj_a.name
        mesh_r = export_mesh(context, pymesh_r, off_name)
        add_to_scene(context, mesh_r)

        return {'FINISHED'}
Пример #20
0
def fix_mesh(mesh, detail="normal"):

    bbox_min, bbox_max = mesh.bbox
    diag_len = norm(bbox_max - bbox_min)

    if detail == "normal":
        target_len = diag_len * 1e-2

    elif detail == "high":
        target_len = diag_len * 5e-3

    elif detail == "low":
        target_len = diag_len * 0.03

    print("Target resolution: {} mm".format(target_len))

    count = 0
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 100)
    mesh, __ = pymesh.split_long_edges(mesh, target_len)
    num_vertices = mesh.num_vertices

    while True:
        mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6)
        mesh, __ = pymesh.collapse_short_edges(mesh,
                                               target_len,
                                               preserve_feature=True)
        mesh, __ = pymesh.remove_obtuse_triangles(mesh, 150.0, 100)

        if mesh.num_vertices == num_vertices:
            break

        num_vertices = mesh.num_vertices
        print("#v: {}".format(num_vertices))
        count += 1
        if count > 10:
            break

    mesh = pymesh.resolve_self_intersection(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh = pymesh.compute_outer_hull(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5)
    mesh, __ = pymesh.remove_isolated_vertices(mesh)

    return mesh
Пример #21
0
def main():
    args = parse_args()
    mesh = pymesh.load_mesh(args.input_mesh)
    if args.initial_block is not None:
        block = pymesh.load_mesh(args.initial_block)
    else:
        bbox_min, bbox_max = mesh.bbox
        block = pymesh.generate_box_mesh(bbox_min,
                                         bbox_max,
                                         2,
                                         keep_symmetry=True)
        block = pymesh.form_mesh(block.vertices, block.faces)
        block, __ = pymesh.remove_isolated_vertices(block)

    carved = carve_mesh(mesh, block, args.N, args.batch_size, args.output_mesh,
                        args.initial_N, args.save_intermediate, args.debug)

    pymesh.save_mesh(args.output_mesh, carved)
def fix_mesh(mesh, detail="normal"):
    bbox_min, bbox_max = mesh.bbox;
    diag_len = norm(bbox_max - bbox_min);
    if detail == "normal":
        target_len = diag_len * 1e-2;
        #target_len = diag_len * 5e-3;
    elif detail == "enormal":
        target_len = diag_len * 5e-3
    elif detail == "high":
        target_len = diag_len * 3e-3
        #target_len = diag_len * 2.5e-3;
    elif detail == "low":
        target_len = diag_len * 1e-2;
    elif detail == "ehigh":
        target_len = diag_len * 1e-3;
    print("Target resolution: {} mm".format(target_len));

    count = 0;
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 100);
    mesh, __ = pymesh.split_long_edges(mesh, target_len);
    num_vertices = mesh.num_vertices;
    while True:
        #mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6);
        if detail == "low":
            mesh, __ = pymesh.collapse_short_edges(mesh, target_len, preserve_feature=False);
        else:
            mesh, __ = pymesh.collapse_short_edges(mesh, target_len, preserve_feature=True);
        mesh, __ = pymesh.remove_obtuse_triangles(mesh, 150.0, 100);
        if mesh.num_vertices == num_vertices:
            break;

        num_vertices = mesh.num_vertices;
        print("#v: {}".format(num_vertices));
        count += 1;
        if count > 10: break;

    mesh = pymesh.resolve_self_intersection(mesh);
    mesh, __ = pymesh.remove_duplicated_faces(mesh);
    mesh = pymesh.compute_outer_hull(mesh);
    mesh, __ = pymesh.remove_duplicated_faces(mesh);
    mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5);
    mesh, __ = pymesh.remove_isolated_vertices(mesh);

    return mesh;
Пример #23
0
def main():
    args = parse_args();
    mesh = pymesh.load_mesh(args.input_mesh);
    if args.initial_block is not None:
        block = pymesh.load_mesh(args.initial_block);
    else:
        bbox_min, bbox_max = mesh.bbox;
        block = pymesh.generate_box_mesh(bbox_min, bbox_max, 2, keep_symmetry=True);
        block = pymesh.form_mesh(block.vertices, block.faces);
        block, __ = pymesh.remove_isolated_vertices(block);

    carved = carve_mesh(mesh, block, args.N,
            args.batch_size,
            args.output_mesh,
            args.initial_N,
            args.save_intermediate,
            args.debug);

    pymesh.save_mesh(args.output_mesh, carved);
Пример #24
0
def fix_mesh(mesh, target_len):
    bbox_min, bbox_max = mesh.bbox
    diag_len = np.linalg.norm(bbox_max - bbox_min)

    count = 0
    print("  remove degenerated triangles")
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 100)
    print("  split long edges")
    mesh, __ = pymesh.split_long_edges(mesh, target_len)
    num_vertices = mesh.num_vertices
    while True:
        print("  pass %d" % count)
        print("    collapse short edges #1")
        mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6)
        print("    collapse short edges #2")
        mesh, __ = pymesh.collapse_short_edges(mesh,
                                               target_len,
                                               preserve_feature=True)
        print("    remove obtuse triangles")
        mesh, __ = pymesh.remove_obtuse_triangles(mesh, 150.0, 100)
        print("    %d of %s vertices." % (num_vertices, mesh.num_vertices))

        if mesh.num_vertices == num_vertices:
            break

        num_vertices = mesh.num_vertices
        count += 1
        if count > 10: break

    print("  resolve self intersection")
    mesh = pymesh.resolve_self_intersection(mesh)
    print("  remove duplicated faces")
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    print("  computer outer hull")
    mesh = pymesh.compute_outer_hull(mesh)
    print("  remove duplicated faces")
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    print("  remove obtuse triangles")
    mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5)
    print("  remove isolated vertices")
    mesh, __ = pymesh.remove_isolated_vertices(mesh)

    return mesh
def range_slider_reconstruction(imagestack):
    imageStack = imagestack
    zSpacing = 0.35 / 1.518

    for levelThreshold in range(0, 20, 2):

        vertices, faces, normals, values = measure.marching_cubes_lewiner(
            imageStack,
            level=float(levelThreshold),
            spacing=(zSpacing, 0.05, 0.05),
            allow_degenerate=False)
        mesh2 = form_mesh(vertices, faces)

        # clean mesh
        mesh3, dictMesh = remove_isolated_vertices(mesh2)
        # print('Vertices removed : {0}'.format(dictMesh[0]))
        # meshName = '{0}_{1}_{2}.ply'.format(filename, str(levelThreshold), zSpacing)
        # save_mesh(meshName, mesh3)
        return mesh2
Пример #26
0
def extract_vertices_and_faces(fn):
    print(f"Processing {fn}")
    mesh = pymesh.load_mesh(str(fn))

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

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

    # move to center
    center = np.mean(vertices, axis=0)
    vertices -= center

    # normalize
    max_len = np.max(np.sum(vertices**2, axis=1))
    vertices /= np.sqrt(max_len)

    return vertices, faces
Пример #27
0
    def __fix_mesh(self, mesh, improvement_thres=0.8):
        mesh, __ = pymesh.split_long_edges(mesh, self.mesh_target_len)
        num_vertices = len(mesh.vertices)

        for __ in range(10):
            mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6)
            mesh, __ = pymesh.collapse_short_edges(
                mesh, self.mesh_target_len, preserve_feature=True
            )
            mesh, __ = pymesh.remove_obtuse_triangles(mesh, 150.0, 100)

            if len(mesh.vertices) < num_vertices * improvement_thres:
                break

        mesh = pymesh.resolve_self_intersection(mesh)
        mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6)
        mesh, __ = pymesh.remove_duplicated_faces(mesh)
        mesh, __ = pymesh.remove_duplicated_faces(mesh)
        mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5)
        mesh, __ = pymesh.remove_isolated_vertices(mesh)

        return mesh
    def _getitem_leaf(self, index):
        if index in self.cache:
            mesh = self.cache[index]
        else:
            path = self.leafs_in_action.iloc[index]['objs_dir']
            objs = self.leafs_in_action.iloc[index]['objs']
            mesh_list = []
            for obj in eval(objs):
                obj_path = os.path.join(path, obj + '.obj')
                mesh_tmp = load_pc(obj_path)
                mesh_tmp, info = pymesh.remove_isolated_vertices(mesh_tmp)
                mesh_list.append(mesh_tmp)
            mesh = pymesh.merge_meshes(mesh_list)
            if len(self.cache) == self.cache_maxsize:
                pop_key = random.choice(list(self.cache.keys()))
                self.cache.pop(pop_key)
            self.cache[index] = mesh

        if self.return_mode == "vertex":
            res = get_pc(mesh)
        else:
            res = mesh
        return res
Пример #29
0
def old_fix_mesh(vertices, faces, detail="normal"):
    bbox_min = np.amin(vertices, axis=0)
    bbox_max = np.amax(vertices, axis=0)
    diag_len = norm(bbox_max - bbox_min)
    if detail == "normal":
        target_len = diag_len * 5e-3
    elif detail == "high":
        target_len = diag_len * 2.5e-3
    elif detail == "low":
        target_len = diag_len * 1e-2
    print("Target resolution: {} mm".format(target_len))

    count = 0
    vertices, faces = pymesh.split_long_edges(vertices, faces, target_len)
    num_vertices = len(vertices)
    while True:
        vertices, faces = pymesh.collapse_short_edges(vertices, faces, 1e-6)
        vertices, faces = pymesh.collapse_short_edges(vertices,
                                                      faces,
                                                      target_len,
                                                      preserve_feature=True)
        vertices, faces = pymesh.remove_obtuse_triangles(
            vertices, faces, 150.0, 100)
        if num_vertices == len(vertices):
            break
        num_vertices = len(vertices)
        print("#v: {}".format(num_vertices))
        count += 1
        if count > 10: break

    vertices, faces = pymesh.resolve_self_intersection(vertices, faces)
    vertices, faces = pymesh.remove_duplicated_faces(vertices, faces)
    vertices, faces, _ = pymesh.compute_outer_hull(vertices, faces, False)
    vertices, faces = pymesh.remove_duplicated_faces(vertices, faces)
    vertices, faces = pymesh.remove_obtuse_triangles(vertices, faces, 179.0, 5)
    vertices, faces, voxels = pymesh.remove_isolated_vertices(vertices, faces)
    return vertices, faces
Пример #30
0
def fix_mesh(mesh, detail="normal"):
    bbox_min, bbox_max = mesh.bbox;
    diag_len = norm(bbox_max - bbox_min);
    if detail == "normal":
        target_len = diag_len * 5e-3;
    elif detail == "high":
        target_len = diag_len * 2.5e-3;
    elif detail == "low":
        target_len = diag_len * 1e-2;
    print("Target resolution: {} mm".format(target_len));

    count = 0;
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 100);
    mesh, __ = pymesh.split_long_edges(mesh, target_len);
    num_vertices = mesh.num_vertices;
    while True:
        mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6);
        mesh, __ = pymesh.collapse_short_edges(mesh, target_len,
                preserve_feature=True);
        mesh, __ = pymesh.remove_obtuse_triangles(mesh, 150.0, 100);
        if mesh.num_vertices == num_vertices:
            break;

        num_vertices = mesh.num_vertices;
        print("#v: {}".format(num_vertices));
        count += 1;
        if count > 10: break;

    mesh = pymesh.resolve_self_intersection(mesh);
    mesh, __ = pymesh.remove_duplicated_faces(mesh);
    mesh = pymesh.compute_outer_hull(mesh);
    mesh, __ = pymesh.remove_duplicated_faces(mesh);
    mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5);
    mesh, __ = pymesh.remove_isolated_vertices(mesh);

    return mesh;
Пример #31
0
def main():
    args = parse_args();
    mesh = pymesh.load_mesh(args.input_mesh);
    mesh = pymesh.form_mesh(mesh.vertices, mesh.faces);
    mesh, __ = pymesh.remove_isolated_vertices(mesh);
    pymesh.save_mesh(args.output_mesh, mesh);
Пример #32
0
def main():
    args = parse_args()
    mesh = pymesh.load_mesh(args.input_mesh)
    mesh = pymesh.form_mesh(mesh.vertices, mesh.faces)
    mesh, __ = pymesh.remove_isolated_vertices(mesh)
    pymesh.save_mesh(args.output_mesh, mesh)
Пример #33
0
def fix_meshes(mesh, detail="normal"):
    """
    A pipeline to optimise and fix mesh based on pymesh Mesh object.

    1. A box is created around the mesh.
    2. A target length is found based on diagonal of the mesh box.
    3. You can choose between 3 level of details, normal details settings seems to be a good compromise between
    final mesh size and sufficient number of vertices. It highly depends on your final goal.
    4. Remove degenerated triangles aka collinear triangles composed of 3 aligned points. The number of iterations is 5
    and should remove all degenerated triangles
    5. Remove isolated vertices, not connected to any faces or edges
    6. Remove self intersection edges and faces which is not realistic
    7. Remove duplicated faces
    8. The removing of duplicated faces can leave some vertices alone, we will removed them
    9. The calculation of outer hull volume is useful to be sure that the mesh is still ok
    10. Remove obtuse triangles > 179 who is not realistic and increase computation time
    11. We will remove potential duplicated faces again
    12. And duplicated vertices again
    13. Finally we will look if the mesh is broken or not. If yes we will try lower settings, if the lowest settings
    broke the mesh we will return the initial mesh. If not, we will return the optimised mesh.

    :param mesh: Pymesh Mesh object to optimise
    :param detail: string 'high', 'normal' or 'low' ('normal' as default), or float/int
    Settings to choose the targeting minimum length of edges
    :return: Pymesh Mesh object
    An optimised mesh or not depending on detail settings and mesh quality
    """
    meshCopy = mesh

    # copy/pasta of pymesh script fix_mesh from qnzhou, see pymesh on GitHub
    bbox_min, bbox_max = mesh.bbox
    diag_len = np.linalg.norm(bbox_max - bbox_min)
    if detail == "normal":
        target_len = diag_len * 5e-3
    elif detail == "high":
        target_len = diag_len * 2.5e-3
    elif detail == "low":
        target_len = diag_len * 1e-2
    elif detail is float or detail is int and detail > 0:
        target_len = diag_len * detail
    else:
        print(
            'Details settings is invalid, must be "low", "normal", "high" or positive int or float'
        )
        quit()

    count = 0
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 5)
    mesh, __ = pymesh.split_long_edges(mesh, target_len)
    num_vertices = mesh.num_vertices
    while True:
        mesh, __ = pymesh.collapse_short_edges(mesh,
                                               target_len,
                                               preserve_feature=True)
        mesh, info = pymesh.remove_obtuse_triangles(mesh, 179.0, 5)
        if mesh.num_vertices == num_vertices:
            break

        num_vertices = mesh.num_vertices
        count += 1
        if count > 10:
            break

    mesh, __ = pymesh.remove_duplicated_vertices(mesh)
    mesh, __ = pymesh.remove_isolated_vertices(mesh)
    mesh = pymesh.resolve_self_intersection(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh, __ = pymesh.remove_duplicated_vertices(mesh)
    mesh = pymesh.compute_outer_hull(mesh)
    mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh, __ = pymesh.remove_isolated_vertices(mesh)

    if is_mesh_broken(mesh, meshCopy) is True:
        if detail == "high":
            print(
                f'The function fix_meshes broke mesh, trying with lower details settings'
            )
            fix_meshes(meshCopy, detail="normal")
            return mesh
        if detail == "normal":
            print(
                f'The function fix_meshes broke mesh, trying with lower details settings'
            )
            mesh = fix_meshes(meshCopy, detail="low")
            return mesh
        if detail == "low":
            print(
                f'The function fix_meshes broke mesh, no lower settings can be applied, no fix was done'
            )
            return meshCopy
    else:
        return mesh
Пример #34
0
def preprocess_mesh(input_mesh, prevent_nonmanifold_edges=True):
    r"""Removes duplicated vertices, duplicated faces, zero-area faces, and
    optionally faces the insertion of which would cause an edge of the mesh to
    become non-manifold. In particular, an iteration is performed over all faces
    in the mesh, keeping track of the half-edges in each face, and if a face
    contains a half-edge already found in one of the faces previously processed,
    it gets removed from the mesh.

    Args:
        input_mesh (pymesh.Mesh.Mesh): Mesh to preprocess.
        prevent_nonmanifold_edges (bool, optional): If True, faces that would
            cause an edge to become non-manifold are removed from the mesh (cf.
            above). (default: :obj:`True`)

    Returns:
        output_mesh (pymesh.Mesh.Mesh): Mesh after preprocessing.
    """
    halfedges_found = set()
    new_faces = np.empty([input_mesh.num_faces, 3])
    # Remove duplicated vertices.
    input_mesh = pymesh.remove_duplicated_vertices(input_mesh)[0]
    # Remove duplicated faces.
    input_mesh = pymesh.remove_duplicated_faces(input_mesh)[0]
    num_valid_faces = 0
    # Compute face areas so that zero-are faces can be removed.
    input_mesh.add_attribute("face_area")
    face_areas = input_mesh.get_face_attribute("face_area")
    assert (len(face_areas) == len(input_mesh.faces))
    for face, face_area in zip(input_mesh.faces, face_areas):
        # Do not include the face if it does not have three different
        # vertices.
        if (face[0] == face[1] or face[0] == face[2] or face[1] == face[2]):
            continue
        # Do not include zero-area faces.
        if (face_area == 0):
            continue
        # Optionally prevent non-manifold edges.
        if (prevent_nonmanifold_edges):
            new_halfedges_in_face = set()
            for idx in range(3):
                halfedge = (face[idx], face[(idx + 1) % 3])
                if (halfedge[0] != halfedge[1]):  # Exclude self-loops.
                    if (halfedge not in halfedges_found):
                        # Half-edge not found previously. -> The edge is
                        # manifold so far.
                        new_halfedges_in_face.add(halfedge)
            if (len(new_halfedges_in_face) == 3):
                # Face does not introduce non-manifold edges.
                halfedges_found.update(new_halfedges_in_face)
                new_faces[num_valid_faces] = face
                num_valid_faces += 1
                # Here one can compute the face features already.
        else:
            new_faces[num_valid_faces] = face
            num_valid_faces += 1

    new_faces = new_faces[:num_valid_faces]
    output_mesh = pymesh.form_mesh(input_mesh.vertices, new_faces)
    # Not including faces might have caused vertices to become isolated.
    output_mesh = pymesh.remove_isolated_vertices(output_mesh)[0]

    return output_mesh
Пример #35
0
    for type in os.listdir(root):
        for phrase in ['train', 'test']:
            type_path = os.path.join(root, type)
            phrase_path = os.path.join(type_path, phrase)
            if not os.path.exists(type_path):
                os.mkdir(os.path.join(new_root, type))
            if not os.path.exists(phrase_path):
                os.mkdir(phrase)

            files = glob.glob(os.path.join(phrase_path, '*.off'))
            for file in files:
                # load mesh
                mesh = pymesh.load_mesh(file)

                # 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
                center = (np.max(vertices, 0) + np.min(vertices, 0)) / 2
                vertices -= center

                # normalize
                max_len = np.max(vertices[:, 0]**2 + vertices[:, 1]**2 +
                                 vertices[:, 2]**2)
                vertices /= np.sqrt(max_len)