Example #1
0
def main():
    args = parse_args()
    mesh = pymesh.load_mesh(args.mesh_file)
    if not args.dual:
        vertices, edges = pymesh.mesh_to_graph(mesh)
    else:
        vertices, edges = pymesh.mesh_to_dual_graph(mesh)
    wire_network = pymesh.wires.WireNetwork.create_from_data(vertices, edges)
    wire_network.write_to_file(args.wire_file)
Example #2
0
def main():
    args = parse_args();
    mesh = pymesh.load_mesh(args.mesh_file);
    if not args.dual:
        vertices, edges = pymesh.mesh_to_graph(mesh);
    else:
        vertices, edges = pymesh.mesh_to_dual_graph(mesh);
    wire_network = pymesh.wires.WireNetwork.create_from_data(vertices, edges);
    wire_network.write_to_file(args.wire_file);
Example #3
0
def slide_verts(input_mesh, prct, mesh_name):
    dihedral_angle_list = []
    mesh_nodes, mesh_edges = pymesh.mesh_to_graph(input_mesh)
    mesh_faces = input_mesh.faces
    input_mesh.add_attribute("face_normal")
    face_normal = input_mesh.get_attribute("face_normal").reshape((mesh_faces.shape[0], 3))
    all_edges_has_two_faces = True
    vertices = input_mesh.vertices.copy()
    for edge_idx in range(len(mesh_edges)):
        n_0 = mesh_edges[edge_idx, 0]
        n_1 = mesh_edges[edge_idx, 1]
        n_0_adjacent_face_indices = set(input_mesh.get_vertex_adjacent_faces(n_0))
        n_1_adjacent_faces_indices = set(input_mesh.get_vertex_adjacent_faces(n_1))
        edge_adjacent_faces_indices = np.sort(list(n_0_adjacent_face_indices & n_1_adjacent_faces_indices))
        if len(edge_adjacent_faces_indices) == 2:
            face_idx_0 = edge_adjacent_faces_indices[0]
            face_idx_1 = edge_adjacent_faces_indices[1]

        if len(edge_adjacent_faces_indices) != 2:
            print(
                f"message generated in slide function. mesh {mesh_name} : edge {edge_idx} has {len(edge_adjacent_faces_indices)} adjacent face.")
            all_edges_has_two_faces = False
            break

        face_0_normal = face_normal[face_idx_0]
        face_1_normal = face_normal[face_idx_1]
        cos_theta = min(np.dot(face_0_normal, face_1_normal), 1)
        cos_theta = max(-1, cos_theta)
        dihedral_angle = np.expand_dims(np.pi - np.arccos(cos_theta), axis=0)
        dihedral_angle_list.append(dihedral_angle)

    if all_edges_has_two_faces:
        dihedral_angle_array = np.array(dihedral_angle_list)

        vids = np.random.permutation(len(vertices))
        target = int(prct * len(vids))
        shifted = 0
        for vi in vids:
            if shifted < target:
                edges = np.where((mesh_edges[:, 0] == vi) | (mesh_edges[:, 1] == vi))[0]
                if min(dihedral_angle_array[edges]) > 2.65:
                    edge = mesh_edges[np.random.choice(edges)]
                    vi_t = edge[1] if vi == edge[0] else edge[0]
                    nv = vertices[vi] + np.random.uniform(0.2, 0.5) * (vertices[vi_t] - vertices[vi])
                    vertices[vi] = nv
                    shifted += 1
            else:
                break
        shifted = shifted / len(vertices)

    slided_mesh = pymesh.form_mesh(vertices, input_mesh.faces)

    return all_edges_has_two_faces, slided_mesh
Example #4
0
def extract_frontier_from_mesh(mesh_filepath):
    filename = os.path.splitext(os.path.basename(mesh_filepath))[0]
    mesh = pymesh.load_mesh(mesh_filepath)

    mesh.enable_connectivity()  # enables connectivity on mesh
    mesh.add_attribute(
        "face_centroid")  # adds the face centroids to be accessed
    mesh.add_attribute("face_normal")  # adds the face normals to be accessed
    mesh.add_attribute("vertex_valance")

    faces = mesh.faces
    centroids = mesh.get_face_attribute("face_centroid")
    normals = mesh.get_face_attribute("face_normal")
    vertex_valance = mesh.get_vertex_attribute("vertex_valance")

    #print vertex_valance
    frontiers = set()

    for face_id in range(0, mesh.num_faces):
        adj_faces = mesh.get_face_adjacent_faces(face_id)
        if len(adj_faces) <= 2:
            #print centroids[face_id]
            p = centroids[face_id]
            p = (p[0], p[1], p[2])
            frontiers.add(p)

    pts, _ = pymesh.mesh_to_graph(mesh)
    x, y, z = zip(*pts)
    x = np.array(x)
    y = np.array(y)
    z = np.array(z)
    fig = plt.figure()  # figsize=(800 / 72, 800 / 72)
    ax = plt.axes(projection='3d')
    ax.set_title(filename)
    # ax.scatter3D(x, y, z, c=z, cmap='Greens');
    ax.scatter3D(x, y, z, s=[1.0 for n in range(len(x))], c="blue")
    set_axes_equal(ax)

    # print(frontiers)

    x, y, z = zip(*frontiers)
    x = np.array(x)
    y = np.array(y)
    z = np.array(z)
    ax.scatter3D(x, y, z, s=[3.0 for n in range(len(x))], c="red")

    plt.show()
Example #5
0
 def __init__(self, input_mesh, mesh_name, data_edges, edge_area,
              edges_seg_labels, edges_soft_seg_labels, faces_seg_labels,
              nodes_seg_labels, filename_to_save, graph_label):
     self.__graph = None
     self.__input_mesh = input_mesh
     self.__mesh_name = mesh_name
     self.__input_mesh.enable_connectivity()
     self.__mesh_nodes, self.__mesh_edges = pymesh.mesh_to_graph(
         self.__input_mesh)
     self.__mesh_faces = self.__input_mesh.faces
     self.__filename_to_save = filename_to_save
     self.__graph_label = graph_label
     self.__data_edges = data_edges
     self.__edges_seg_labels = edges_seg_labels
     self.__edges_soft_seg_labels = edges_soft_seg_labels
     self.__faces_seg_labels = faces_seg_labels
     self.__nodes_seg_labels = nodes_seg_labels
     self.__edge_area = edge_area
     self.two_face_neighbor = True
Example #6
0
    def generate_primitives(self):
        if self.mesh.num_faces <= 0:
            return;

        self.primitives = [];
        d = norm(self.bmax - self.bmin) / math.sqrt(self.mesh.dim);
        radius = d * self.line_width;
        assert(radius > 0);
        vertices, edges = pymesh.mesh_to_graph(self.mesh);
        lengths = norm(vertices[edges[:,0],:] - vertices[edges[:,1],:], axis=1);
        color = color_table["dark_gray"];
        for v in vertices:
            ball = Sphere(v, radius);
            ball.color = color;
            self.primitives.append(ball);

        for e,l in zip(edges, lengths):
            if l <= 0.5 * radius : continue;
            cylinder = Cylinder(vertices[e[0]], vertices[e[1]], radius);
            cylinder.color = color;
            self.primitives.append(cylinder);
Example #7
0
    def generate_primitives(self):
        if self.mesh.num_faces <= 0:
            return

        self.primitives = []
        d = norm(self.bmax - self.bmin) / math.sqrt(self.mesh.dim)
        radius = d * self.line_width
        assert (radius > 0)
        vertices, edges = pymesh.mesh_to_graph(self.mesh)
        lengths = norm(vertices[edges[:, 0], :] - vertices[edges[:, 1], :],
                       axis=1)
        color = get_color(self.line_color)
        for v in vertices:
            ball = Sphere(v, radius)
            ball.color = color
            self.primitives.append(ball)

        for e, l in zip(edges, lengths):
            if l <= 0.5 * radius: continue
            cylinder = Cylinder(vertices[e[0]], vertices[e[1]], radius)
            cylinder.color = color
            self.primitives.append(cylinder)
Example #8
0
def get_vertices_and_edges(obj_mesh):
    vertices, edges = pymesh.mesh_to_graph(obj_mesh)
    return vertices, edges
def get_border_edge(mesh):
    vertices, edges = pymesh.mesh_to_graph(mesh)
    print(np.all(vertices == mesh.vertices))
from utils import create_weighted_graph, add_connectivity

# NB: THE FULL VERSION OF PYMESH MUST BE INSTALLED TO RUN THIS SCRIPT
# AS THE PIP INSTALLATION DOES NOT INCLUDE THE FUNCTION load_mesh()
# THE FULL VERSION OF PYMESH CAN BE INSTALLED VIA git clone ..

for i in np.arange(4, 12, 2):
    mesh_name = "poly_" + str(i) + ".off"
    mesh_boundary = "poly_boundary_" + str(i) + ".txt"
    mesh_connectivity = "poly_connectivity_" + str(i) + ".txt"
    # load and visualize mesh
    mesh = pymesh.load_mesh(mesh_name)
    #plt.triplot(mesh.vertices[:,0], mesh.vertices[:,1], mesh.faces, 'ko-', lw = 0.5, alpha=0.5, ms = 0.7)

    # convert mesh to graph
    graph = pymesh.mesh_to_graph(mesh)
    # add weights to account for irregularity of mesh
    weighted_graph = create_weighted_graph(graph)

    # add connectivity
    start_c = time.time()
    connect = np.loadtxt(mesh_connectivity)
    weighted_graph_with_connectivity = add_connectivity(
        np.copy(graph[0]), weighted_graph.copy(), connect)

    # create networkx graph
    G = nx.from_edgelist(weighted_graph)
    G_prime = nx.from_edgelist(weighted_graph_with_connectivity)

    # load boundary vertices and find their indices in the graph
    sources = np.loadtxt(mesh_boundary)
def create_graph(mesh,
                 centroids,
                 normals,
                 robot_pos,
                 traversal_tresh=35,
                 bumpiness_tresh=0.37,
                 dbscan_eps=3,
                 dbscan_min_samples=2):
    """

    :param mesh:
    :param centroids:
    :param normals:
    :param closer_centroid_idx:
    :param traversal_tresh:
    :param dbscan_eps:
    :param dbscan_min_samples:
    :return:
    """
    print("Creating Graph... num faces:", mesh.num_faces)

    frontiers = extract_frontiers(mesh)
    print("Found ", frontiers, "frontiers")

    G = nx.Graph()

    for face_idx in xrange(mesh.num_faces):
        face = mesh.faces[face_idx]

        face_inclination = graph_search.MeshGraphSearch.calculate_traversal_angle(
            normals[face_idx])
        # if 0 <= face_inclination <= traversal_tresh or 180 - traversal_tresh <= face_inclination <= 180:
        if traversal_tresh < face_inclination < 180 - traversal_tresh:
            continue

        G.add_node(face_idx)

    for face_idx in list(G.nodes()):
        face_vertexes = mesh.faces[face_idx]
        for v in face_vertexes:
            vertex_adj_faces = mesh.get_vertex_adjacent_faces(v)
            for face_adjacent in vertex_adj_faces:
                if face_adjacent != face_idx and G.has_node(face_adjacent):
                    G.add_edge(face_idx, face_adjacent, weight=1)

    #print "G edge_list:", len(list(G.edges())), sorted(list(G.edges()))

    # remove small connected components
    for component in list(nx.connected_components(G)):
        if len(component) < 3:
            for node in component:
                G.remove_node(node)

    g_centroids = [(centroids[v][0], centroids[v][1], centroids[v][2])
                   for v in sorted(G.nodes())]
    centroid_g_dict = {i: v for i, v in enumerate(sorted(G.nodes()))}

    closer_centroid_idx = mesh_planner.mesh_helper.find_closer_centroid(
        g_centroids, robot_pos, force_return_closer=True)
    conn_nodes = nx.node_connected_component(
        G, centroid_g_dict[closer_centroid_idx])
    Gconn = G.subgraph(conn_nodes).copy()

    kdtree = spatial.KDTree(g_centroids)
    pairs = kdtree.query_pairs(bumpiness_tresh)
    print "pairs:", len(pairs), pairs

    joined_by_bumpiness_nodes = set()
    for pair in pairs:
        p1_conn = centroid_g_dict[
            pair[0]]  # node inside the biggest connected component
        p2_out = centroid_g_dict[
            pair[1]]  # node outside of the biggest connected component

        # if edge is already mapped, then drop it
        if Gconn.has_edge(p1_conn, p2_out) or Gconn.has_edge(p2_out, p1_conn):
            continue

        # if edge is only connecting inside the Gconn drop it
        if Gconn.has_node(p1_conn) and Gconn.has_node(p2_out):
            continue

        # if edge is not connecting Gconn with other connected elements drop it
        if not Gconn.has_node(p1_conn) and not Gconn.has_node(p2_out):
            continue

        if p1_conn not in Gconn.nodes():
            p1_conn, p2_out = p2_out, p1_conn

        # if there is already a connection between the outside element and Gconn
        intersecting_gconn_nodes = list(
            set(G.neighbors(p2_out)).intersection(Gconn.nodes()))
        if len(intersecting_gconn_nodes) > 1:
            continue

        # this node is an another connected subgraph
        # add this node and the other ones of the subgraph
        # if not Gconn.has_node(p2_out):
        #     small_component = nx.node_connected_component(G, p2_out)
        #     for n in small_component:
        #         if not Gconn.has_node(n):
        #             Gconn.add_node(n)

        small_comp_nodes = nx.node_connected_component(G, p2_out)
        Gsmall = G.subgraph(small_comp_nodes).copy()
        GconnTemp = Gconn.copy()
        Gconn = nx.compose(Gconn, Gsmall)

        for pair2 in pairs:
            pair2_1 = centroid_g_dict[pair2[0]]
            pair2_2 = centroid_g_dict[pair2[1]]

            if (Gsmall.has_node(pair2_1) and GconnTemp.has_node(pair2_2)) or \
                (GconnTemp.has_node(pair2_1) and Gsmall.has_node(pair2_2)):

                gconn_node = pair2_1
                outside_node = pair2_2

                if not GconnTemp.has_node(gconn_node):
                    outside_node, gconn_node = gconn_node, outside_node

                # intersecting_gconn_nodes = list(set(Gconn.neighbors(gconn_node)).intersection(Gsmall.nodes()))
                # if len(intersecting_gconn_nodes) > 0:
                #     continue

                Gconn.add_edge(pair2_1, pair2_2, weight=1)
                joined_by_bumpiness_nodes.add(pair2_1)
                joined_by_bumpiness_nodes.add(pair2_2)

                # a = np.asarray(centroids[pair2_1])
                # b = np.asarray(centroids[pair2_2])
                #
                # print("dist:", np.linalg.norm(a - b))

    # add remaining edges of the new component from the original graph
    for e in G.edges():
        p1_conn = e[0]
        p2_out = e[1]

        # if edge is already mapped, then drop it
        if Gconn.has_edge(p1_conn, p2_out) or Gconn.has_edge(p2_out, p1_conn):
            continue

        # if edge is only connecting inside the Gconn drop it
        if not p1_conn in Gconn.nodes() and not p2_out in Gconn.nodes():
            continue

        Gconn.add_edge(p1_conn, p2_out, weight=1)

    print "Gconn node_list:", list(Gconn.nodes())

    # numpy array of x,y,z positions in sorted node order
    gcon_centroids = [(centroids[v][0], centroids[v][1], centroids[v][2])
                      for v in sorted(Gconn.nodes())]
    xyz = np.array(gcon_centroids)
    # scalar colors
    scalars = xyz[:, 2]  #np.array(list(Gconn.nodes())) #xyz[:, 2]  #+ 5

    mlab.figure(1, bgcolor=(0, 0, 0))
    mlab.clf()

    # centroid_gcon_dict = {v: int(i) for i, v in enumerate(gcon_centroids)}
    # print "centroid_gcon_dict:", centroid_gcon_dict.keys()
    # edge_list = []
    # for e in Gconn.edges():
    #     e1 = (centroids[e[0]][0], centroids[e[0]][1], centroids[e[0]][2])
    #     e2 = (centroids[e[1]][0], centroids[e[1]][1], centroids[e[1]][2])
    #     edge_list.append([centroid_gcon_dict[e1], centroid_gcon_dict[e2]])
    #
    # edge_list = np.array(edge_list)
    # #edge_list = np.array(list(Gconn.edges()))
    # print "edge_list:", edge_list
    # pts.mlab_source.dataset.lines = np.array(edge_list)
    # #pts.update()
    # lines = mlab.pipeline.stripper(pts)
    # mlab.pipeline.surface(lines, color=(0.2, 0.4, 0.5), line_width=1.5, opacity=.9)  #colormap='Accent',

    # tube = mlab.pipeline.tube(pts, tube_radius=0.1)
    # mlab.pipeline.surface(tube, color=(0.8, 0.8, 0.8))

    # final_mesh_pts = []
    # for e in Gconn.nodes():
    #     final_mesh_pts.append((centroids[e][0], centroids[e][1], centroids[e][2]))
    #
    # final_mesh_faces = []
    # for e in Gconn.nodes():
    #     final_mesh_faces.append(mesh.faces[e])
    #
    # x, y, z = zip(*final_mesh_pts)
    # x = np.array(x)
    # y = np.array(y)
    # z = np.array(z)
    #
    # print "mesh.faces:", mesh.faces
    #
    # mlab.triangular_mesh(x, y, z, final_mesh_faces)

    filtered_mesh = pymesh.submesh(mesh, Gconn.nodes(), 1)
    pymesh.save_mesh("/tmp/tmp.stl", filtered_mesh)

    pts, _ = pymesh.mesh_to_graph(filtered_mesh)
    x, y, z = zip(*pts)
    x = np.array(x)
    y = np.array(y)
    z = np.array(z)
    mlab.triangular_mesh(x, y, z, filtered_mesh.faces)

    mlab.show()
Example #12
0
def get_bounding_box_center(mesh):
    vertices, edges = pymesh.mesh_to_graph(mesh)
    wire_network = pymesh.WireNetwork.create_from_data(vertices=vertices, edges=edges)
    return wire_network.bbox_center