Beispiel #1
0
def my_mesh_thicken(mesh, thickness=1.0, cls=None):
    """Thicken a mesh.

    Parameters
    ----------
    mesh : Mesh
        A mesh to thicken.
    thickness : real
        The mesh thickness

    Returns
    -------
    thickened_mesh : Mesh
        The thickened mesh.

    """
    if cls is None:
        cls = type(mesh)

    # offset in both directions
    mesh_top, mesh_bottom = map(lambda eps: my_mesh_offset(mesh, eps * thickness / 2., cls), [+1, -1])

    # flip bottom part
    mesh_flip_cycles(mesh_bottom)

    # join parts
    thickened_mesh = meshes_join([mesh_top, mesh_bottom], cls)

    # close boundaries
    n = thickened_mesh.number_of_vertices() / 2

    edges_on_boundary = []
    for boundary in list(my_edges_on_boundaries(thickened_mesh)):
        edges_on_boundary.extend(boundary)

    for u, v in edges_on_boundary:
        if u < n and v < n:
            thickened_mesh.add_face([u, v, v + n, u + n])

    return thickened_mesh
Beispiel #2
0
def _dae_mesh_importer(filename):
    """This is a very simple implementation of a DAE/Collada parser.
    It merges all solids of the DAE file into one mesh, because
    several other parts of the framework don't support multi-meshes per file."""
    dae = XML.from_file(filename)
    meshes = []

    for mesh_xml in dae.root.findall('.//mesh'):
        for triangle_set in mesh_xml.findall('triangles'):
            triangle_set_data = triangle_set.find('p').text.split()

            # Parse vertices
            vertices_input = triangle_set.find('input[@semantic="VERTEX"]')
            vertices_link = mesh_xml.find('vertices[@id="{}"]/input'.format(vertices_input.attrib['source'][1:]))
            positions = mesh_xml.find('source[@id="{}"]/float_array'.format(vertices_link.attrib['source'][1:]))
            positions = positions.text.split()

            vertices = list(map(float, positions[i:i + 3]) for i in range(0, len(positions), 3))

            # Parse faces
            faces = list(map(int, triangle_set_data[::2]))  # Ignore normals (ever second item is normal index)
            faces = list(faces[i:i + 3] for i in range(0, len(faces), 3))

            mesh = Mesh.from_vertices_and_faces(vertices, faces)

            meshes.append(mesh)

    combined_mesh = meshes_join(meshes)

    # from compas.datastructures import mesh_transform
    # from compas.geometry import Frame
    # from compas.geometry import Transformation

    # former DAE files have yaxis and zaxis swapped
    # frame = Frame([0, 0, 0], [1, 0, 0], [0, 0, 1])
    # T = Transformation.from_frame(frame)
    # mesh_transform(combined_mesh, T)
    return combined_mesh
# ==============================================================================
# Main
# ==============================================================================

if __name__ == "__main__":

    import doctest

    import compas
    from compas.datastructures import Mesh
    from compas.datastructures import meshes_join
    from compas.geometry import translate_points_xy

    m1 = Mesh.from_obj(compas.get('faces.obj'))
    m2 = m1.copy()

    points = m2.vertices_attributes('xyz')
    x, y, z = zip(*points)
    xmin = min(x)
    xmax = max(x)
    points = translate_points_xy(points, [1.5 * (xmax - xmin), 0, 0])
    for key, attr in m2.vertices(True):
        attr['x'] = points[key][0]
        attr['y'] = points[key][1]
        attr['z'] = points[key][2]

    m3 = meshes_join([m1, m2])

    doctest.testmod()
def create_sk3_quad(lines, joint_width=1, leaf_width=1, joint_length=0.4):
    def get_convex_hull_mesh(points):
        faces = convex_hull(points)
        vertices = list(set(flatten(faces)))

        i_index = {i: index for index, i in enumerate(vertices)}
        vertices = [points[index] for index in vertices]
        faces = [[i_index[i] for i in face] for face in faces]
        faces = unify_cycles(vertices, faces)

        mesh = Mesh.from_vertices_and_faces(vertices, faces)

        return mesh

    def create_networks():
        networks = {}
        descendent_tree = {}
        for u in joints:
            global_local = {}
            lines = []
            nbrs = network_global.neighbors(u)
            start_pt = network_global.node_coordinates(u)

            for v in nbrs:
                end_pt = network_global.edge_point(u, v, t=joint_length)
                lines.append([start_pt, end_pt])

            network_local = Network.from_lines(lines)
            key_local = list(
                set(list(network_local.nodes())) -
                set(network_local.leaves()))[0]
            global_local.update({u: key_local})

            gkeys_global_network = [geometric_key(line[1]) for line in lines]
            gkeys_local_network = [
                geometric_key(network_local.node_coordinates(key))
                for key in network_local.leaves()
            ]

            for i, key_global in enumerate(nbrs):
                gkey_global = gkeys_global_network[i]
                index_local = gkeys_local_network.index(gkey_global)
                key_local = network_local.leaves()[index_local]
                global_local.update({key_global: key_local})

            descendent_tree.update({u: global_local})
            networks.update({u: network_local})

        return networks, descendent_tree

    def create_sk3_branch(u, v):
        def find_vertices(u, v):
            sk3_joint_u = sk3_joints[u]

            # inside of network_u, find vertices on the verge
            leaf_u = descendent_tree[u][
                v]  # this is network local key, not convexhull mesh
            leaf_u = sk3_joint_u.network_convexhull[leaf_u]
            nbrs = sk3_joint_u.convexhull_mesh.vertex_neighbors(leaf_u,
                                                                ordered=True)
            keys = [
                sk3_joint_u.descendent_tree[leaf_u][nbr]['lp'] for nbr in nbrs
            ]
            points = [sk3_joint_u.vertex_coordinates(key) for key in keys]

            return points

        if u in joints and v in joints:
            # its an internal edge
            points_u = find_vertices(u, v)
            points_v = find_vertices(v, u)

            if len(points_u) != len(points_v):
                mesh = get_convex_hull_mesh(points_u + points_v)
            else:
                points_v = points_v[::-1]
                index = closest_point_in_cloud(points_u[0], points_v)[2]
                points_v = points_v[index:] + points_v[:index]

                vertices = points_u + points_v
                faces = []
                n = len(points_u)
                for i in range(n):
                    faces.append([i, (i + 1) % n, (i + 1) % n + n, i + n])

                mesh = Mesh.from_vertices_and_faces(vertices, faces)

        else:
            if u in leafs:
                leaf, joint = u, v
            elif v in leafs:
                leaf, joint = v, u

            points_joint = find_vertices(joint, leaf)
            network = networks[joint]

            u_local = descendent_tree[joint][joint]
            v_local = descendent_tree[joint][leaf]

            vec = [
                i * (1 - joint_length)
                for i in network_global.edge_vector(joint, leaf)
            ]
            points_leaf = [add_vectors(pt, vec) for pt in points_joint]

            vertices = points_joint + points_leaf
            faces = []
            n = len(points_joint)
            for i in range(n):
                faces.append([i, (i + 1) % n, (i + 1) % n + n, i + n])

            mesh = Mesh.from_vertices_and_faces(vertices, faces)

        return mesh

    def create_sk3_branches():

        return [create_sk3_branch(u, v) for u, v in network_global.edges()]

    def create_sk3_joints(networks):
        sk3_joints = {}
        for u in networks:
            network = networks[u]
            sk3_joint = Skeleton3D_Node.from_network(network)
            sk3_joint.joint_width = joint_width
            sk3_joint.leaf_width = leaf_width
            sk3_joint.update_vertices_location()
            sk3_joints.update({u: sk3_joint})

        return sk3_joints

    def draw_mesh_faces(mesh):
        fkeys_nodraw = [
            fkey for fkey in mesh.faces() if mesh.face_area(fkey) <= 0
        ]
        fkeys = list(set(list(mesh.faces())) - set(fkeys_nodraw))

        artist = MeshArtist(mesh)
        artist.layer = '3GS::Skeleton'
        artist.draw_faces(faces=fkeys, join_faces=True)

    network_global = Network.from_lines(lines)

    joints = []
    leafs = []
    for key in network_global.node:
        if network_global.is_leaf(key):
            leafs.append(key)
        else:
            joints.append(key)

    networks, descendent_tree = create_networks()
    sk3_joints = create_sk3_joints(networks)
    sk3_branches = create_sk3_branches()

    mesh = meshes_join(sk3_joints.values() + sk3_branches)
    draw_mesh_faces(mesh)

    return mesh
Beispiel #5
0
        [-30, 0, 0],
        [-30, -30, 0],
        [0, -30, 0],
        [30, -30, 0],
    ]

    for vector, mesh2 in zip(vectors, meshes):
        mesh2.collect_strips()
        fix_boundaries(mesh2)
        define_density(mesh2, 300)
        fix_boundaries(mesh2.get_quad_mesh())
        find_form(mesh2.get_quad_mesh(), 100.0)
        mesh_move_by(mesh2.get_quad_mesh(), vector)
        rotate_mesh(mesh2.get_quad_mesh())

    # for mesh2 in meshes:
    # 	if mesh2.get_quad_mesh() is None:
    # 		print('!')

    # for mesh in meshes:
    # 	plotter = MeshPlotter(mesh, figsize=(5.0, 5.0))
    # 	plotter.draw_edges()
    # 	plotter.draw_faces()
    # 	plotter.show()

    all_meshes = meshes_join([mesh2.get_quad_mesh() for mesh2 in meshes])
    plotter = MeshPlotter(all_meshes, figsize=(5.0, 5.0))
    plotter.draw_edges()
    plotter.draw_faces()
    plotter.show()
Beispiel #6
0
r_axis = 3.0
r_pipe = 1.5
torus = Torus(plane, r_axis, r_pipe)

vs, fs = torus.to_vertices_and_faces(u=11, v=11)
torus_mesh = Mesh.from_vertices_and_faces(vs, fs)

vertex_spheres = []
for v in torus_mesh.vertices():
    v_coords = torus_mesh.vertex_coordinates(v)
    sphere = Sphere(v_coords, 0.2)
    vs, fs = sphere.to_vertices_and_faces(u=12, v=12)
    sphere_mesh = Mesh.from_vertices_and_faces(vs, fs)
    vertex_spheres.append(sphere_mesh)

spheres_mesh = meshes_join(vertex_spheres)
torus_and_spheres = meshes_join([spheres_mesh, torus_mesh])

edge_cylinders = []

for e in torus_mesh.edges():

    e_mid = torus_mesh.edge_midpoint(e[0], e[1])
    e_dir = torus_mesh.edge_direction(e[0], e[1])
    e_len = torus_mesh.edge_length(e[0], e[1])
    circle = Circle((e_mid, e_dir), 0.1)
    cylinder = Cylinder(circle, e_len)
    vs, fs = cylinder.to_vertices_and_faces(u=16)
    cyl_mesh = Mesh.from_vertices_and_faces(vs, fs)
    edge_cylinders.append(cyl_mesh)
Beispiel #7
0
    def to_compas_quadmesh(self,
                           nu,
                           nv=None,
                           weld=False,
                           facefilter=None,
                           cls=None):
        """Convert the surface to a COMPAS mesh.

        Parameters
        ----------
        nu: int
            The number of faces in the u direction.
        nv: int, optional
            The number of faces in the v direction.
            Default is the same as the u direction.
        weld: bool, optional
            Weld the vertices of the mesh.
            Default is ``False``.
        facefilter: callable, optional
            A filter for selection which Brep faces to include.
            If provided, the filter should return ``True`` or ``False`` per face.
            A very simple filter that includes all faces is ``def facefilter(face): return True``.
            Default parameter value is ``None`` in which case all faces are included.
        cls: :class:`compas.geometry.Mesh`, optional
            The type of COMPAS mesh.

        Returns
        -------
        :class:`compas.geometry.Mesh`
        """
        nv = nv or nu
        cls = cls or Mesh

        if not self.geometry.HasBrepForm:
            return

        brep = Rhino.Geometry.Brep.TryConvertBrep(self.geometry)

        if facefilter and callable(facefilter):
            faces = [face for face in brep.Faces if facefilter(face)]
        else:
            faces = brep.Faces

        meshes = []
        for face in faces:
            domain_u = face.Domain(0)
            domain_v = face.Domain(1)
            du = (domain_u[1] - domain_u[0]) / (nu)
            dv = (domain_v[1] - domain_v[0]) / (nv)

            @memoize
            def point_at(i, j):
                return point_to_compas(face.PointAt(i, j))

            quads = []
            for i in range(nu):
                for j in range(nv):
                    a = point_at(domain_u[0] + (i + 0) * du,
                                 domain_v[0] + (j + 0) * dv)
                    b = point_at(domain_u[0] + (i + 1) * du,
                                 domain_v[0] + (j + 0) * dv)
                    c = point_at(domain_u[0] + (i + 1) * du,
                                 domain_v[0] + (j + 1) * dv)
                    d = point_at(domain_u[0] + (i + 0) * du,
                                 domain_v[0] + (j + 1) * dv)
                    quads.append([a, b, c, d])

            meshes.append(cls.from_polygons(quads))

        return meshes_join(meshes, cls=cls)