コード例 #1
0
ファイル: mesh_interfaces.py プロジェクト: rolanddenis/MeshDD
    def clean(self, vertices, faces, normals=None, tcoords=None, tol=1e-12):
        import pymesh

        # Removing duplicated vertices
        vertices, faces, info = pymesh.remove_duplicated_vertices_raw(
            vertices, faces, tol)

        if normals is not None:
            cleaned_normals = np.empty((vertices.shape[0], normals.shape[1]),
                                       dtype=normals.dtype)
            cleaned_normals[info['index_map'], :] = normals
        else:
            cleaned_normals = None

        if tcoords is not None:
            cleaned_tcoords = np.empty((vertices.shape[0], tcoords.shape[1]),
                                       dtype=tcoords.dtype)
            cleaned_tcoords[info['index_map'], :] = tcoords
        else:
            cleaned_tcoords = None

        # Removing degenerated triangles
        # FIXME: Returned vertices are modified (order probably) without a way
        #        to get the map so that to update the attributes...
        #vertices, faces, info = pymesh.remove_degenerated_triangles_raw(vertices, faces)

        # Removing degenerated triangles
        # Only the triangles with duplicated vertices
        mask = np.logical_or(
            np.logical_or(faces[:, 0] == faces[:, 1],
                          faces[:, 0] == faces[:, 2]), faces[:, 1] == faces[:,
                                                                            2])
        faces = faces[np.logical_not(mask), :]

        return vertices, faces, cleaned_normals, cleaned_tcoords
コード例 #2
0
ファイル: tet_to_hex.py プロジェクト: ezeakeal/3D-parallax
def tet_to_hex(mesh):
    in_vertices = mesh.vertices
    in_voxels = mesh.voxels
    out_vertices = []
    out_voxels = []

    hexes = np.array([[0, 6, 12, 4, 5, 11, 14,
                       13], [4, 12, 8, 1, 13, 14, 10, 7],
                      [6, 3, 8, 12, 11, 9, 10, 14],
                      [5, 2, 9, 11, 13, 7, 10, 14]])
    for i, tet in enumerate(in_voxels):
        corners = in_vertices[tet]
        e01 = (corners[0] + corners[1]) / 2.0
        e02 = (corners[0] + corners[2]) / 2.0
        e03 = (corners[0] + corners[3]) / 2.0
        e12 = (corners[1] + corners[2]) / 2.0
        e13 = (corners[3] + corners[1]) / 2.0
        e23 = (corners[2] + corners[3]) / 2.0
        f0 = (corners[1] + corners[2] + corners[3]) / 3.0
        f1 = (corners[0] + corners[2] + corners[3]) / 3.0
        f2 = (corners[0] + corners[1] + corners[3]) / 3.0
        f3 = (corners[0] + corners[1] + corners[2]) / 3.0
        center = np.mean(corners, axis=0).reshape((1, -1))
        out_vertices += [
            corners, e01, e02, e03, e12, e13, e23, f0, f1, f2, f3, center
        ]

        out_voxels.append(hexes + i * 15)

    out_vertices = np.vstack(out_vertices)
    out_voxels = np.vstack(out_voxels)
    out_vertices, out_voxels, __ = pymesh.remove_duplicated_vertices_raw(
        out_vertices, out_voxels)
    mesh = pymesh.form_mesh(out_vertices, None, out_voxels)
    return mesh
コード例 #3
0
def return_sorted_geom_connect(sx, atol):
    """sort geom array and reindex connect array to match the new geom array"""
    geom, connect = read_geom_connect(sx)
    nv = geom.shape[0]

    try:
        import pymesh

        geom, connect, inf = pymesh.remove_duplicated_vertices_raw(geom,
                                                                   connect,
                                                                   tol=atol)
        print(f"removed {inf['num_vertex_merged']} duplicates out of {nv}")
    except ModuleNotFoundError:
        print("pymesh not found, trying trimesh...")
        import trimesh

        trimesh.tol.merge = atol
        mesh = trimesh.Trimesh(geom, connect)
        mesh.merge_vertices()
        geom = mesh.vertices
        connect = mesh.faces
        print(f"removed {nv-geom.shape[0]} duplicates out of {nv}")

    ind, ind_inv = lookup_sorted_geom(geom, atol)
    geom = geom[ind, :]
    connect = np.array([ind_inv[x]
                        for x in connect.flatten()]).reshape(connect.shape)
    # sort along line (then we can use multidim_intersect)
    connect = np.sort(connect, axis=1)
    return geom, connect
コード例 #4
0
def cleanup(wires):
    vertices, edges, __ = pymesh.remove_duplicated_vertices_raw(
        wires.vertices, wires.edges, 0.0)

    # Trim zero dimension.
    if wires.dim == 3:
        assert (np.all(vertices[:, 2] == 0))
        vertices = vertices[:, [0, 1]]

    # Remove duplicated edges.
    ordered_edges = np.sort(edges, axis=1)
    __, unique_edge_ids = np.unique(ordered_edges, return_index=True, axis=0)
    edges = edges[unique_edge_ids, :]

    # Remove topologically degenerate edges.
    wires.load(vertices, edges)
    is_not_topologically_degenerate = edges[:, 0] != edges[:, 1]
    if not np.all(is_not_topologically_degenerate):
        wires.filter_edges(is_not_topologically_degenerate)

    return wires
コード例 #5
0
ファイル: repousse.py プロジェクト: ezeakeal/3D-parallax
def cleanup(wires, logger):
    if wires.num_vertices == 0:
        return wires
    start_time = time()
    tol = 1e-6
    vertices, edges, __ = pymesh.remove_duplicated_vertices_raw(
        wires.vertices, wires.edges, tol)

    # Remove duplicated edges.
    ordered_edges = np.sort(edges, axis=1)
    __, unique_edge_ids, __ = pymesh.unique_rows(ordered_edges)
    edges = edges[unique_edge_ids, :]
    wires.load(vertices, edges)

    # Remove topologically degenerate edges.
    is_not_topologically_degenerate = edges[:, 0] != edges[:, 1]
    if not np.all(is_not_topologically_degenerate):
        wires.filter_edges(is_not_topologically_degenerate)

    finish_time = time()
    t = finish_time - start_time
    logger.info("Cleanup running time: {}".format(t))

    return wires
コード例 #6
0
ファイル: repousse.py プロジェクト: qnzhou/PyMesh
def cleanup(wires, logger):
    if wires.num_vertices == 0:
        return wires;
    start_time = time();
    tol = 1e-6;
    vertices, edges, __ = pymesh.remove_duplicated_vertices_raw(
            wires.vertices, wires.edges, tol);

    # Remove duplicated edges.
    ordered_edges = np.sort(edges, axis=1);
    __, unique_edge_ids, __ = pymesh.unique_rows(ordered_edges);
    edges = edges[unique_edge_ids, :];
    wires.load(vertices, edges);

    # Remove topologically degenerate edges.
    is_not_topologically_degenerate = edges[:,0] != edges[:,1];
    if not np.all(is_not_topologically_degenerate):
        wires.filter_edges(is_not_topologically_degenerate);

    finish_time = time();
    t = finish_time - start_time;
    logger.info("Cleanup running time: {}".format(t));

    return wires;
コード例 #7
0
ファイル: tet_to_hex.py プロジェクト: mortezah/PyMesh
def tet_to_hex(mesh):
    in_vertices = mesh.vertices
    in_voxels = mesh.voxels
    out_vertices = []
    out_voxels = []

    hexes = np.array(
        [
            [0, 6, 12, 4, 5, 11, 14, 13],
            [4, 12, 8, 1, 13, 14, 10, 7],
            [6, 3, 8, 12, 11, 9, 10, 14],
            [5, 2, 9, 11, 13, 7, 10, 14],
        ]
    )
    for i, tet in enumerate(in_voxels):
        corners = in_vertices[tet]
        e01 = (corners[0] + corners[1]) / 2.0
        e02 = (corners[0] + corners[2]) / 2.0
        e03 = (corners[0] + corners[3]) / 2.0
        e12 = (corners[1] + corners[2]) / 2.0
        e13 = (corners[3] + corners[1]) / 2.0
        e23 = (corners[2] + corners[3]) / 2.0
        f0 = (corners[1] + corners[2] + corners[3]) / 3.0
        f1 = (corners[0] + corners[2] + corners[3]) / 3.0
        f2 = (corners[0] + corners[1] + corners[3]) / 3.0
        f3 = (corners[0] + corners[1] + corners[2]) / 3.0
        center = np.mean(corners, axis=0).reshape((1, -1))
        out_vertices += [corners, e01, e02, e03, e12, e13, e23, f0, f1, f2, f3, center]

        out_voxels.append(hexes + i * 15)

    out_vertices = np.vstack(out_vertices)
    out_voxels = np.vstack(out_voxels)
    out_vertices, out_voxels, __ = pymesh.remove_duplicated_vertices_raw(out_vertices, out_voxels)
    mesh = pymesh.form_mesh(out_vertices, None, out_voxels)
    return mesh
コード例 #8
0
ファイル: Tomo2Mesh.py プロジェクト: vitst/tomoPost
 def makeMesh(self, path2file, do_clean=False):
     path, file_name = os.path.split(path2file)
     fname, fext = os.path.splitext(file_name)
     
     # read image
     stack_tif = io.imread(path2file, plugin='tifffile')
     
     print('tif shape: {}'.format(stack_tif.shape), flush=True)
     
     bin_stack_tif = stack_tif.astype(bool).astype(np.int16)
     
     # clean from isolated and small pixels (optional)
     if do_clean:
         bin_stack_tif = self.erode_converge(bin_stack_tif)
         bin_stack_tif = self.clean_not_attached(bin_stack_tif)
     
         print('Saving image after cleaning', flush=True)
         io.imsave("aux.tif", (255*bin_stack_tif).astype(np.uint8), plugin='tifffile')
     
     bin_stack_tif = binary_erosion(bin_stack_tif, iterations=1)
     
     # create 1 pixel layer to make close meshes
     NZ = bin_stack_tif.shape[0]
     NY = bin_stack_tif.shape[1]
     NX = bin_stack_tif.shape[2]
     aux = np.zeros((NZ + 10, NY + 10, NX + 10))
     aux[5:NZ + 5, 5:NY + 5, 5:NX + 5] = bin_stack_tif
     
     print('Triangulation of a set of points ...', flush=True)
     
     aux = aux.astype(np.float32)
     
     aux = filters.gaussian_filter(aux, 2.0, truncate=1.0)
     
     maxA = np.max(aux)
     
     aux = aux / maxA * 4.0 - 1.0
     # aux = aux * 4.0 - 1.0
     
     minA = np.min(aux)
     maxA = np.max(aux)
     
     print('Cleaning memory', flush=True)
     del stack_tif
     del bin_stack_tif
     gc.collect()
     
     print("min aux: {}   max aux: {}".format(minA, maxA), flush=True)
     verts, faces, normals, values = measure.marching_cubes_lewiner(aux, 0)
     
     print('Cleaning memory', flush=True)
     del aux
     gc.collect()
     
     print("Mesh data 0:",flush=True)
     print("Verts: {}  Faces: {}".format(verts.shape, faces.shape))
     
     print('Remove isolated vertices', flush=True)
     verts, faces, info = pymesh.remove_isolated_vertices_raw(verts, faces)
     print(info, flush=True)
     
     print("Mesh data 1:",flush=True)
     print("Verts: {}  Faces: {}".format(verts.shape, faces.shape))
     
     print('Remove duplicated vertices', flush=True)
     verts, faces, info = pymesh.remove_duplicated_vertices_raw(verts, faces)
     print(info, flush=True)
     
     print("Mesh data 2:",flush=True)
     print("Verts: {}  Faces: {}".format(verts.shape, faces.shape))
     verts = verts - 5.0
     
     print('Set the mesh ...', flush=True)
     final_mesh = pymesh.form_mesh(verts, faces)
     
     savefilename = "{}.obj".format(fname)
     savefilepath = os.path.join('./', savefilename)
     
     print("saving file {}".format(savefilename), flush=True)
     
     pymesh.save_mesh(savefilepath, final_mesh)
     
     print('done.', flush=True)
コード例 #9
0
ファイル: repousse.py プロジェクト: ezeakeal/3D-parallax
def bevel(wires, logger, remove_holes, dist):
    bbox_min, bbox_max = wires.bbox

    #wires = uniform_sampling(wires);
    mesh = constrained_triangulate(wires, logger, remove_holes)

    cell_ids = mesh.get_attribute("cell").ravel().astype(int)
    num_cells = np.amax(cell_ids) + 1

    comps = []
    for i in range(num_cells):
        to_keep = np.arange(mesh.num_faces, dtype=int)[cell_ids == i]
        if not np.any(to_keep):
            continue

        cut_mesh = pymesh.submesh(mesh, to_keep, 0)
        bd_edges = cut_mesh.boundary_edges
        vertices, edges, __ = pymesh.remove_isolated_vertices_raw(
            cut_mesh.vertices, bd_edges)
        bd_wires = pymesh.wires.WireNetwork.create_from_data(vertices, edges)

        offset_dir = np.zeros((bd_wires.num_vertices, 2))
        for ei in edges:
            v0 = ei[0]
            v1 = ei[1]
            adj_vts = bd_wires.get_vertex_neighbors(v0)
            if len(adj_vts) == 2:
                if adj_vts[0] == v1:
                    vp = adj_vts[1]
                else:
                    vp = adj_vts[0]
                e0 = vertices[v1] - vertices[v0]
                e1 = vertices[vp] - vertices[v0]
                e0 /= norm(e0)
                e1 /= norm(e1)
                theta = math.atan2(e0[0] * e1[1] - e0[1] * e1[0], e0.dot(e1))

                if abs(theta) > 0.99 * math.pi:
                    offset = np.array([-e0[1], e0[0]])
                    scale = 1.0
                else:
                    if theta > 0:
                        offset = e0 + e1
                        scale = math.sin(theta / 2)
                    else:
                        offset = -e0 - e1
                        scale = math.cos(math.pi / 2 + theta / 2)
                    offset /= norm(offset)
                offset_dir[v0] = offset * dist / scale

        offset_vertices = vertices + offset_dir
        vertices = np.vstack((vertices, offset_vertices))
        edges = np.vstack((edges, edges + bd_wires.num_vertices))

        vertices, edges, __ = pymesh.remove_duplicated_vertices_raw(
            vertices, edges, dist / 2)

        comp_wires = pymesh.wires.WireNetwork.create_from_data(
            vertices, edges)
        comp = constrained_triangulate(comp_wires, logger, True)
        comps.append(comp)

    mesh = pymesh.merge_meshes(comps)
    bd_vertices = mesh.boundary_vertices
    is_inside = np.ones(mesh.num_vertices, dtype=bool)
    is_inside[bd_vertices] = False

    vertices = np.hstack((mesh.vertices, np.zeros((mesh.num_vertices, 1))))
    vertices[is_inside, 2] = dist
    mesh = pymesh.form_mesh(vertices, mesh.faces)
    return mesh
コード例 #10
0
ファイル: repousse.py プロジェクト: qnzhou/PyMesh
def bevel(wires, logger, remove_holes, dist):
    bbox_min, bbox_max = wires.bbox;

    #wires = uniform_sampling(wires);
    mesh = constrained_triangulate(wires, logger, remove_holes);

    cell_ids = mesh.get_attribute("cell").ravel().astype(int);
    num_cells = np.amax(cell_ids) + 1;

    comps = [];
    for i in range(num_cells):
        to_keep = np.arange(mesh.num_faces, dtype=int)[cell_ids == i];
        if not np.any(to_keep):
            continue;

        cut_mesh = pymesh.submesh(mesh, to_keep, 0);
        bd_edges = cut_mesh.boundary_edges;
        vertices, edges, __ = pymesh.remove_isolated_vertices_raw(
                cut_mesh.vertices, bd_edges);
        bd_wires = pymesh.wires.WireNetwork.create_from_data(vertices, edges);

        offset_dir = np.zeros((bd_wires.num_vertices, 2));
        for ei in edges:
            v0 = ei[0];
            v1 = ei[1];
            adj_vts = bd_wires.get_vertex_neighbors(v0);
            if len(adj_vts) == 2:
                if adj_vts[0] == v1:
                    vp = adj_vts[1];
                else:
                    vp = adj_vts[0];
                e0 = vertices[v1] - vertices[v0];
                e1 = vertices[vp] - vertices[v0];
                e0 /= norm(e0);
                e1 /= norm(e1);
                theta = math.atan2(e0[0]*e1[1] - e0[1]*e1[0], e0.dot(e1));

                if abs(theta) > 0.99 * math.pi:
                    offset = np.array([-e0[1], e0[0]]);
                    scale = 1.0;
                else:
                    if theta > 0:
                        offset = e0 + e1;
                        scale = math.sin(theta/2);
                    else:
                        offset = -e0 - e1
                        scale = math.cos(math.pi/2 + theta/2);
                    offset /= norm(offset);
                offset_dir[v0] = offset * dist / scale;

        offset_vertices = vertices + offset_dir;
        vertices = np.vstack((vertices, offset_vertices));
        edges = np.vstack((edges, edges + bd_wires.num_vertices));

        vertices, edges, __ = pymesh.remove_duplicated_vertices_raw(
                vertices, edges, dist/2);

        comp_wires = pymesh.wires.WireNetwork.create_from_data(vertices, edges);
        comp = constrained_triangulate(comp_wires, logger, True);
        comps.append(comp);

    mesh = pymesh.merge_meshes(comps);
    bd_vertices = mesh.boundary_vertices;
    is_inside = np.ones(mesh.num_vertices, dtype=bool);
    is_inside[bd_vertices] = False;

    vertices = np.hstack((mesh.vertices, np.zeros((mesh.num_vertices, 1))));
    vertices[is_inside, 2] = dist;
    mesh = pymesh.form_mesh(vertices, mesh.faces);
    return mesh;