Ejemplo n.º 1
0
def mesh_unweld_edges(mesh, edges):
    """Unwelds a mesh along edges.

    Parameters
    ----------
    mesh : Mesh
        A mesh.
    edges: list
        List of edges as tuples of vertex keys.

    """

    # set of vertices in edges to unweld
    vertices = set([i for edge in edges for i in edge])

    # to store changes to do all at once
    vertex_changes = {}

    for vkey in vertices:

        # maps between old mesh face index and new network vertex index
        old_to_new = {nbr: i for i, nbr in enumerate(mesh.vertex_faces(vkey))}
        new_to_old = {i: nbr for i, nbr in enumerate(mesh.vertex_faces(vkey))}

        # get adjacency network of faces around the vertex excluding adjacency
        # through the edges to unweld
        network_vertices = [
            mesh.face_centroid(fkey) for fkey in mesh.vertex_faces(vkey)
        ]
        network_edges = []
        for nbr in mesh.vertex_neighbors(vkey):
            if not mesh.is_edge_on_boundary(vkey, nbr) and (
                    vkey, nbr) not in edges and (nbr, vkey) not in edges:
                network_edges.append((old_to_new[mesh.halfedge[vkey][nbr]],
                                      old_to_new[mesh.halfedge[nbr][vkey]]))

        adjacency = adjacency_from_edges(network_edges)
        for key, values in adjacency.items():
            adjacency[key] = {value: None for value in values}
        # include non connected vertices
        edge_vertices = list(set([i for edge in network_edges for i in edge]))
        for i in range(len(mesh.vertex_faces(vkey))):
            if i not in edge_vertices:
                adjacency[i] = {}

        # collect the disconnected parts around the vertex due to unwelding
        vertex_changes[vkey] = [[new_to_old[key] for key in part]
                                for part in connected_components(adjacency)]

    for vkey, changes in vertex_changes.items():
        # for each disconnected part replace the vertex by a new vertex in the
        # faces of the part
        for change in changes:
            mesh_substitute_vertex_in_faces(
                mesh, vkey, mesh.add_vertex(attr_dict=mesh.vertex[vkey]),
                change)

        # delete old vertices
        mesh.delete_vertex(vkey)
Ejemplo n.º 2
0
def mesh_disconnected_vertices(mesh):
    """Get the disconnected vertex groups in a mesh.

    Parameters
    ----------
    mesh : Mesh
        A mesh.

    Returns
    -------
    parts : list
        The list of disconnected vertex groups.
    """
    return connected_components(mesh.adjacency)
Ejemplo n.º 3
0
def network_disconnected_nodes(network):
    """Get the disconnected node groups in a network.

    Parameters
    ----------
    network : Network
        A network.

    Returns
    -------
    list
        The list of disconnected node groups.
    """
    return connected_components(network.adjacency)
Ejemplo n.º 4
0
def mesh_disconnected_vertices(mesh):
    """Get the disconnected vertex groups in a mesh.

    Parameters
    ----------
    mesh : :class:`compas.datastructures.Mesh`
        A mesh.

    Returns
    -------
    list[list[int]]
        The disconnected parts of the mesh as a list of lists of vertex identifiers.

    """
    return connected_components(mesh.adjacency)
Ejemplo n.º 5
0
def network_disconnected_nodes(network):
    """Get the disconnected node groups in a network.

    Parameters
    ----------
    network : :class:`compas.datastructures.Network`
        A network.

    Returns
    -------
    list[list[hashable]]
        The list of disconnected node groups.

    """
    return connected_components(network.adjacency)
Ejemplo n.º 6
0
def mesh_connected_components(mesh):
    """Find the connected components of the mesh.

    Parameters
    ----------
    mesh : :class:`compas.datastructures.Mesh`
        A mesh data structure.

    Returns
    -------
    list[list[int]]
        Groups of connected vertices.

    """
    return connected_components(mesh.adjacency)
Ejemplo n.º 7
0
def mesh_connected_components(mesh):
    return connected_components(mesh.adjacency)
Ejemplo n.º 8
0
    from compas.datastructures import Mesh
    from compas.viewers import MeshViewer
    from compas.utilities import download_file_from_remote
    from compas.topology import connected_components


    source = 'https://raw.githubusercontent.com/ros-industrial/abb/kinetic-devel/abb_irb6600_support/meshes/irb6640/visual/link_1.stl'
    filepath = os.path.join(compas.APPDATA, 'data', 'meshes', 'ros', 'link_1.stl')

    download_file_from_remote(source, filepath, overwrite=False)

    stl = STL(filepath, precision='6f')

    mesh = Mesh.from_vertices_and_faces(stl.parser.vertices, stl.parser.faces)

    vertexgroups = connected_components(mesh.halfedge)
    facegroups = [[] for _ in range(len(vertexgroups))]

    vertexsets = list(map(set, vertexgroups))

    for fkey in mesh.faces():
        vertices = set(mesh.face_vertices(fkey))

        for i, vertexset in enumerate(vertexsets):
            if vertices.issubset(vertexset):
                facegroups[i].append(fkey)
                break

    meshes = []

    for vertexgroup, facegroup in zip(vertexgroups, facegroups):
Ejemplo n.º 9
0
    def from_quad_mesh(cls,
                       quad_mesh,
                       collect_strips=True,
                       collect_polyedges=True,
                       attribute_density=True):
        """Build coarse quad mesh from quad mesh with density and child-parent element data.

		Parameters
		----------
		quad_mesh : QuadMesh
			A quad mesh.
		attribute_density : bool, optional
			Keep density data of dense quad mesh and inherit it as aatribute.

		Returns
		----------
		coarse_quad_mesh : CoarseQuadMesh
			A coarse quad mesh with density data.
		"""

        polyedges = quad_mesh.singularity_polyedge_decomposition()

        # vertex data
        vertices = {
            vkey: quad_mesh.vertex_coordinates(vkey)
            for vkey in quad_mesh.vertices()
        }
        coarse_vertices_children = {
            vkey: vkey
            for polyedge in polyedges for vkey in [polyedge[0], polyedge[-1]]
        }
        coarse_vertices = {
            vkey: quad_mesh.vertex_coordinates(vkey)
            for vkey in coarse_vertices_children
        }

        # edge data
        coarse_edges_children = {(polyedge[0], polyedge[-1]): polyedge
                                 for polyedge in polyedges}
        singularity_edges = [(x, y) for polyedge in polyedges
                             for u, v in pairwise(polyedge)
                             for x, y in [(u, v), (v, u)]]

        # face data
        faces = {
            fkey: quad_mesh.face_vertices(fkey)
            for fkey in quad_mesh.faces()
        }
        adj_edges = {(f1, f2)
                     for f1 in quad_mesh.faces()
                     for f2 in quad_mesh.face_neighbors(f1)
                     if f1 < f2 and quad_mesh.face_adjacency_halfedge(f1, f2)
                     not in singularity_edges}
        coarse_faces_children = {}
        for i, connected_faces in enumerate(
                connected_components(adjacency_from_edges(adj_edges))):
            mesh = Mesh.from_vertices_and_faces(
                vertices, [faces[face] for face in connected_faces])
            coarse_faces_children[i] = [
                vkey for vkey in reversed(mesh.boundaries()[0])
                if mesh.vertex_degree(vkey) == 2
            ]

        coarse_quad_mesh = cls.from_vertices_and_faces(coarse_vertices,
                                                       coarse_faces_children)

        # attribute relation child-parent element between coarse and dense quad meshes
        coarse_quad_mesh.data['attributes'][
            'vertex_coarse_to_dense'] = coarse_vertices_children
        coarse_quad_mesh.data['attributes']['edge_coarse_to_dense'] = {
            u: {}
            for u in coarse_quad_mesh.vertices()
        }
        for (u, v), polyedge in coarse_edges_children.items():
            coarse_quad_mesh.data['attributes']['edge_coarse_to_dense'][u][
                v] = polyedge
            coarse_quad_mesh.data['attributes']['edge_coarse_to_dense'][v][
                u] = list(reversed(polyedge))

        # collect strip and polyedge attributes
        if collect_strips:
            coarse_quad_mesh.collect_strips()
        if collect_polyedges:
            coarse_quad_mesh.collect_polyedges()

        # store density attribute from input dense quad mesh
        if attribute_density:
            coarse_quad_mesh.set_strips_density(1)
            for skey in coarse_quad_mesh.strips():
                u, v = coarse_quad_mesh.strip_edges(skey)[0]
                d = len(
                    coarse_edges_children.get((u, v),
                                              coarse_edges_children.get((v, u),
                                                                        [])))
                coarse_quad_mesh.set_strip_density(skey, d)

        # store quad mesh and use as polygonal mesh
        coarse_quad_mesh.set_quad_mesh(quad_mesh)
        coarse_quad_mesh.set_polygonal_mesh(quad_mesh.copy())

        return coarse_quad_mesh