Example #1
0
    def create_from_setting(cls, setting):
        """ Syntax:
        {
            "type": "boundary",
            "mesh": mesh_file,
            "color": color_name,
            "radius": radius
        }
        """
        mesh = pymesh.load_mesh(setting["mesh"])
        vertices = mesh.vertices
        bd_edges = mesh.boundary_edges
        vertices, bd_edges, __ = pymesh.remove_isolated_vertices_raw(
            vertices, bd_edges)
        wires = pymesh.wires.WireNetwork()
        if len(bd_edges) > 0:
            wires.load(vertices, bd_edges)
        else:
            logger = logging.getLogger(__name__)
            logger.warning("Mesh ({}) contains no boundary.".format(
                setting["mesh"]))

        tmp_dir = tempfile.gettempdir()
        stamp = datetime.datetime.now().isoformat()
        wire_file = os.path.join(tmp_dir, "{}.wire".format(stamp))
        wires.write_to_file(wire_file)

        wire_setting = {
            "type": "wire_network",
            "wire_network": wire_file,
            "color": setting.get("color", None),
            "radius": setting.get("radius", 0.1),
            "bbox": mesh.bbox,
        }
        return WireView.create_from_setting(wire_setting)
Example #2
0
def slice_mesh(mesh, N):
    bbox_min, bbox_max = mesh.bbox;
    min_corner = [bbox_min[0] -1.0, bbox_min[1] - 1.0, bbox_min[2] - 1.0];
    output_wires = [];
    for i in range(N):
        ratio = float(i) / float(N);
        slice_val = bbox_min[0] * ratio + bbox_max[0] * (1-ratio);
        max_corner = [slice_val, bbox_max[1] + 1.0, bbox_max[2] + 1.0];
        box = pymesh.generate_box_mesh(min_corner, max_corner);
        diff = pymesh.boolean(box, mesh, "difference");
        #pymesh.save_mesh("tmp_{}.msh".format(i), diff);
        vertices = diff.vertices;
        y_out_range = np.logical_or(
                    vertices[:,1] < bbox_min[1],
                    vertices[:,1] > bbox_max[1]);
        z_out_range = np.logical_or(
                    vertices[:,2] < bbox_min[2],
                    vertices[:,2] > bbox_max[2]);
        on_outside = np.logical_or(y_out_range, z_out_range);

        if not np.any(on_outside): continue;

        edges = [];
        for f in diff.faces:
            if np.sum(on_outside[f]) == 1:
                if on_outside[f[0]]:
                    edges.append([f[1], f[2]]);
                if on_outside[f[1]]:
                    edges.append([f[2], f[0]]);
                if on_outside[f[2]]:
                    edges.append([f[0], f[1]]);

        if len(edges) == 0: continue;
        edges = np.array(edges, dtype=int);

        below_ground = vertices[:,1] < 0.5*(bbox_min[1]+bbox_max[1]);
        edges_below_ground = np.any(below_ground[edges], axis=1);
        edges = edges[np.logical_not(edges_below_ground)];

        vertices, edges, __ = \
                pymesh.remove_isolated_vertices_raw(vertices, edges);
        wires = pymesh.wires.WireNetwork.create_from_data(vertices, edges);
        output_wires.append(wires);
        print('.',end="",flush=True)
    print("done");

    return output_wires;
Example #3
0
def extract_submesh(mesh, face_indices, n_ring):
    vertices = mesh.vertices

    selected_faces = np.zeros(mesh.num_faces, dtype=bool)
    selected_faces[face_indices] = True
    ring_index = np.zeros(mesh.num_faces, dtype=int)
    ring_index[selected_faces] += 1
    for i in range(n_ring):
        selected_faces = expand_by_one_ring(mesh, selected_faces)
        ring_index[selected_faces] += 1
    selected_face_indices = np.arange(mesh.num_faces)[selected_faces]
    faces = mesh.faces[selected_faces]
    ring_index = (ring_index[selected_faces] - n_ring - 1) * (-1)

    vertices, faces, __ = pymesh.remove_isolated_vertices_raw(vertices, faces)
    mesh = pymesh.form_mesh(vertices, faces)
    mesh.add_attribute("ori_face_index")
    mesh.set_attribute("ori_face_index", selected_face_indices)
    mesh.add_attribute("ring")
    mesh.set_attribute("ring", ring_index)
    return mesh
Example #4
0
def extract_submesh(mesh, face_indices, n_ring):
    vertices = mesh.vertices;

    selected_faces = np.zeros(mesh.num_faces, dtype=bool);
    selected_faces[face_indices] = True;
    ring_index = np.zeros(mesh.num_faces, dtype=int);
    ring_index[selected_faces] += 1;
    for i in range(n_ring):
        selected_faces = expand_by_one_ring(mesh, selected_faces);
        ring_index[selected_faces] += 1;
    selected_face_indices = np.arange(mesh.num_faces)[selected_faces];
    faces = mesh.faces[selected_faces];
    ring_index = (ring_index[selected_faces] - n_ring - 1) * (-1);

    vertices, faces, __ = pymesh.remove_isolated_vertices_raw(vertices, faces);
    mesh = pymesh.form_mesh(vertices, faces);
    mesh.add_attribute("ori_face_index");
    mesh.set_attribute("ori_face_index", selected_face_indices);
    mesh.add_attribute("ring");
    mesh.set_attribute("ring", ring_index);
    return mesh;
Example #5
0
 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)
Example #6
0
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
Example #7
0
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;