def update_scene_transforms_and_positions(self, scene):
        """Walks through the scene tree and updates transforms and positions.  To be used when
        nodes have been added or the nodes' matrices or TRS attributes have been set or updated.

        Parameters
        ----------
        scene : :class:`compas.files.GLTFScene`

        Returns
        -------

        """
        origin = [0, 0, 0]
        for node_key in scene.children:
            node = self.nodes[node_key]
            node.transform = node.matrix or node.get_matrix_from_trs()
            node.position = transform_points([origin], node.transform)[0]
            queue = [node_key]
            while queue:
                cur_key = queue.pop(0)
                cur = self.nodes[cur_key]
                for child_key in cur.children:
                    child = self.nodes[child_key]
                    child.transform = multiply_matrices(
                        cur.transform,
                        child.matrix or child.get_matrix_from_trs()
                    )
                    child.position = transform_points([origin], child.transform)[0]
                    queue.append(child_key)
Exemple #2
0
    def get_forward_transformations(self, configuration):
        """Calculate the transformations according to the configuration.

        Args:
            configuration (:class:`Configuration`): The robot's configuration.

        Returns:
            transformations (:obj:`list` of :class:`Transformation`): The
                transformations for each link.
        """
        q0, q1, q2, q3, q4, q5 = configuration.joint_values
        j0, j1, j2, j3, j4, j5 = self.j0, self.j1, self.j2, self.j3, self.j4, self.j5

        T0 = Rotation.from_axis_and_angle(subtract_vectors(j0[1], j0[0]), q0, j0[1])
        j1 = transform_points(j1, T0)
        T1 = Rotation.from_axis_and_angle(subtract_vectors(j1[1], j1[0]), q1, j1[1]) * T0
        j2 = transform_points(j2, T1)
        T2 = Rotation.from_axis_and_angle(subtract_vectors(j2[1], j2[0]), q2, j2[1]) * T1
        j3 = transform_points(j3, T2)
        T3 = Rotation.from_axis_and_angle(subtract_vectors(j3[1], j3[0]), q3, j3[1]) * T2
        j4 = transform_points(j4, T3)
        T4 = Rotation.from_axis_and_angle(subtract_vectors(j4[1], j4[0]), q4, j4[1]) * T3
        j5 = transform_points(j5, T4)
        T5 = Rotation.from_axis_and_angle(subtract_vectors(j5[1], j5[0]), q5, j5[1]) * T4

        # now apply the transformation to the base
        T0 = self.transformation_RCS_WCS * T0
        T1 = self.transformation_RCS_WCS * T1
        T2 = self.transformation_RCS_WCS * T2
        T3 = self.transformation_RCS_WCS * T3
        T4 = self.transformation_RCS_WCS * T4
        T5 = self.transformation_RCS_WCS * T5

        return T0, T1, T2, T3, T4, T5
def offset_polygon_xy(points, dist, planarize=False):
    if len(points) < 3:
        return None
    frame = Frame.from_plane(
        Plane.from_three_points(points[0], points[1], points[2]))
    xform = Transformation.from_frame_to_frame(frame, Frame.worldXY())
    if planarize:
        points = [point_on_plane(point, frame) for point in points]
    points = transform_points(points, xform)
    points = offset_polygon(points, dist)
    points = transform_points(points, xform.inverse())
    return points
Exemple #4
0
def mesh_transform(mesh, transformation):
    """Transform a mesh.

    Parameters
    ----------
    mesh : Mesh
        The mesh.
    transformation : Transformation
        The transformation.

    Notes
    -----
    The mesh is modified in-place.

    Examples
    --------
    >>> mesh = Mesh.from_obj(compas.get('cube.obj'))
    >>> T = matrix_from_axis_and_angle([0, 0, 1], pi / 4)
    >>> tmesh = mesh.copy()
    >>> mesh_transform(tmesh, T)
    >>> viewer.mesh = tmesh  # this should be a list of meshes
    >>> viewer.show()

    """
    vertices = [mesh.vertex_coordinates(key) for key in mesh.vertices()]
    xyz = transform_points(vertices, transformation)
    for index, (key, attr) in enumerate(mesh.vertices(True)):
        attr['x'] = xyz[index][0]
        attr['y'] = xyz[index][1]
        attr['z'] = xyz[index][2]
Exemple #5
0
    def transform(self, T):
        """Transform this polygon.

        Parameters
        ----------
        T : :class:`compas.geometry.Transformation` | list[list[float]]
            The transformation.

        Returns
        -------
        None

        Examples
        --------
        >>> from math import radians
        >>> from compas.geometry import Rotation
        >>> polygon = Polygon.from_sides_and_radius_xy(4, 1.0)
        >>> R = Rotation.from_axis_and_angle([0.0, 0.0, 1.0], radians(45))
        >>> polygon.transform(R)
        >>> polygon.points[0]
        Point(-0.707, 0.707, 0.000)

        """
        for index, point in enumerate(transform_points(self.points, T)):
            self.points[index].x = point[0]
            self.points[index].y = point[1]
            self.points[index].z = point[2]
Exemple #6
0
    def transform_collection(collection, X):
        """Transform a collection of points.

        Parameters
        ----------
        collection : list of :class:`compas.geometry.Point`
            The collection of points.

        Returns
        -------
        None
            The points are modified in-place.

        Examples
        --------
        >>> T = Translation([1.0, 2.0, 3.0])
        >>> a = Point(0.0, 0.0, 0.0)
        >>> points = [a]
        >>> Point.transform_collection(points, T)
        >>> b = points[0]
        >>> b
        Point(1.000, 2.000, 3.000)
        >>> a is b
        True
        """
        data = transform_points(collection, X)
        for point, xyz in zip(collection, data):
            point.x = xyz[0]
            point.y = xyz[1]
            point.z = xyz[2]
Exemple #7
0
def volmesh_transform(volmesh, transformation):
    """Transform a mesh.

    Parameters
    ----------
    volmesh : :class:`compas.datastructures.VolMesh`
        The volmesh.
    transformation : :class:`compas.geometry.Transformation`
        The transformation.

    Returns
    -------
    None

    Notes
    -----
    The volmesh is modified in-place.

    Examples
    --------
    >>> from compas.datastructures import VolMesh
    >>> from compas.geometry import Rotation
    >>> volmesh = VolMesh.from_obj(compas.get('boxes.obj'))
    >>> T = Rotation.from_axis_and_angle([0, 0, 1], math.pi / 4)
    >>> volmesh_transform(volmesh, T)

    """
    vertices = list(volmesh.vertices())
    xyz = [volmesh.vertex_coordinates(vertex) for vertex in vertices]
    xyz[:] = transform_points(xyz, transformation)
    for index, vertex in enumerate(vertices):
        volmesh.vertex_attributes(vertex, 'xyz', xyz[index])
Exemple #8
0
    def to_vertices_and_faces(self, **kwargs):
        """Returns a list of vertices and faces"""

        u = kwargs.get('u') or 10
        if u < 3:
            raise ValueError('The value for u should be u > 3.')

        vertices = []
        a = 2 * pi / u
        for i in range(u):
            x = self.circle.radius * cos(i * a)
            y = self.circle.radius * sin(i * a)
            z = self.height / 2
            vertices.append([x, y, z])
            vertices.append([x, y, -z])

        # transform vertices to cylinder's plane
        frame = Frame.from_plane(self.circle.plane)
        M = matrix_from_frame(frame)
        vertices = transform_points(vertices, M)

        faces = []
        for i in range(0, u * 2, 2):
            faces.append([i, i + 1, (i + 3) % (u * 2), (i + 2) % (u * 2)])

        faces.append([i for i in range(0, u * 2, 2)])
        faces.append([i for i in range(1, u * 2, 2)])
        faces[-1].reverse()

        return vertices, faces
Exemple #9
0
def mesh_transform(mesh, transformation):
    """Transform a mesh.

    Parameters
    ----------
    mesh : :class:`compas.datastructures.Mesh`
        The mesh.
    transformation : :class:`compas.geometry.Transformation`
        The transformation.

    Returns
    -------
    None
        The mesh is modified in-place.

    Examples
    --------
    >>> from compas.datastructures import Mesh
    >>> from compas.geometry import matrix_from_axis_and_angle
    >>> mesh = Mesh.from_polyhedron(6)
    >>> T = matrix_from_axis_and_angle([0, 0, 1], math.pi / 4)
    >>> tmesh = mesh.copy()
    >>> mesh_transform(tmesh, T)

    """
    vertices = list(mesh.vertices())
    xyz = [mesh.vertex_coordinates(vertex) for vertex in vertices]
    xyz[:] = transform_points(xyz, transformation)
    for index, vertex in enumerate(vertices):
        mesh.vertex_attributes(vertex, 'xyz', xyz[index])
Exemple #10
0
def network_transform(network, transformation):
    """Transform a network.

    Parameters
    ----------
    network : :class:`compas.datastructures.Network`
        The network.
    transformation : :class:`compas.geometry.Transformation`
        The transformation.

    Returns
    -------
    None

    Notes
    -----
    The network is modified in-place.

    """
    vertices = [network.node_coordinates(key) for key in network.nodes()]
    xyz = transform_points(vertices, transformation)
    for index, (key, attr) in enumerate(network.nodes(True)):
        attr['x'] = xyz[index][0]
        attr['y'] = xyz[index][1]
        attr['z'] = xyz[index][2]
Exemple #11
0
def network_transform(network, transformation):
    """Transform a network.

    Parameters
    ----------
    network : network
        The network.
    transformation : Transformation
        The transformation.

    Notes
    -----
    The network is modified in-place.

    Examples
    --------
    >>> network = network.from_obj(compas.get('cube.obj'))
    >>> T = matrix_from_axis_and_angle([0, 0, 1], pi / 4)
    >>> tnetwork = network.copy()
    >>> network_transform(tnetwork, T)
    >>> viewer.network = tnetwork  # this should be a list of networkes
    >>> viewer.show()

    """
    vertices = [network.vertex_coordinates(key) for key in network.vertices()]
    xyz = transform_points(vertices, transformation)
    for index, (key, attr) in enumerate(network.vertices(True)):
        attr['x'] = xyz[index][0]
        attr['y'] = xyz[index][1]
        attr['z'] = xyz[index][2]
Exemple #12
0
    def to_vertices_and_faces(self, **kwargs):
        """Returns a list of vertices and faces, called by `Mesh.from_shape()`."""
        if 'u' in kwargs:
            u = kwargs['u']
        else:
            u = 10

        vertices = []
        a = 2 * pi / u
        for i in range(u):
            x = self.circle.radius * cos(i * a)
            y = self.circle.radius * sin(i * a)
            vertices.append([x, y, 0])
        vertices.append([0, 0, self.height])

        # transform vertices to cylinder's plane
        frame = Frame.from_plane(self.circle.plane)
        M = matrix_from_frame(frame)
        vertices = transform_points(vertices, M)

        faces = []
        last = len(vertices) - 1
        for i in range(u):
            faces.append([i, (i + 1) % u, last])
        faces.append([i for i in range(u)])
        faces[-1].reverse()

        return vertices, faces
Exemple #13
0
def mesh_transform(mesh, transformation):
    """Transform a mesh.

    Parameters
    ----------
    mesh : compas.datastructures.Mesh
        The mesh.
    transformation : compas.geometry.Transformation
        The transformation.

    Notes
    -----
    The mesh is modified in-place.

    Examples
    --------
    >>> mesh = Mesh.from_obj(compas.get('cube.obj'))
    >>> T = matrix_from_axis_and_angle([0, 0, 1], pi / 4)
    >>> tmesh = mesh.copy()
    >>> mesh_transform(tmesh, T)

    """
    vertices = [mesh.vertex_coordinates(key) for key in mesh.vertices()]
    xyz = transform_points(vertices, transformation)
    for index, (_, attr) in enumerate(mesh.vertices(True)):
        attr['x'] = xyz[index][0]
        attr['y'] = xyz[index][1]
        attr['z'] = xyz[index][2]
Exemple #14
0
    def get_transformed_model(self, transformation, xtransform_function=None):
        """Get the transformed meshes of the tool model.

        Args:
            transformation (:class:`Transformation`): The transformation to
                reach tool0_frame.
            xform_function (function name, optional): the name of the function
                used to transform the model. Defaults to None.

        Returns:
            model (:obj:`list` of :class:`Mesh`): The list of meshes in the
                respective class of the CAD environment
        """
        tmodel = []
        if xtransform_function:
            for m in self.model:
                tmodel.append(xtransform_function(m, transformation,
                                                  copy=True))
        else:
            for m in self.model:
                xyz = [(a['x'], a['y'], a['z']) for k, a in m.vertices(True)]
                mtxyz = transform_points(xyz, transformation)
                #mtxyz = transform_points(m.xyz, transformation)
                faces = [m.face_vertices(fkey) for fkey in m.faces()]
                tmodel.append(Mesh.from_vertices_and_faces(mtxyz, faces))
        return tmodel
def volmesh_transform(volmesh, transformation):
    """Transform a mesh.

    Parameters
    ----------
    volmesh : compas.datastructures.VolMesh
        The volmesh.
    transformation : compas.geometry.Transformation
        The transformation.

    Notes
    -----
    The volmesh is modified in-place.

    Examples
    --------
    >>> volmesh = VolMesh.from_obj(compas.get('cube.obj'))
    >>> T = matrix_from_axis_and_angle([0, 0, 1], pi / 4)
    >>> volmesh_transform(volmesh, T)

    """
    vertices = list(volmesh.vertices())
    xyz = [volmesh.vertex_coordinates(vertex) for vertex in vertices]
    xyz[:] = transform_points(xyz, transformation)
    for index, vertex in enumerate(vertices):
        volmesh.vertex_attributes(vertex, 'xyz', xyz[index])
Exemple #16
0
    def to_vertices_and_faces(self, **kwargs):
        if 'u' in kwargs:
            u = kwargs['u']
        else:
            u = 10

        vertices = []
        a = 2 * pi / u
        for i in range(u):
            x = self.circle.radius * cos(i * a)
            y = self.circle.radius * sin(i * a)
            z = self.height / 2
            vertices.append([x, y, z])
            vertices.append([x, y, -z])

        # transform vertices to cylinder's plane
        frame = Frame.from_plane(self.circle.plane)
        M = matrix_from_frame(frame)
        vertices = transform_points(vertices, M)


        faces = []
        for i in range(0, u*2, 2):
            faces.append([i, i+1, (i+3)%(u*2), (i+2)%(u*2)])
        
        faces.append([i for i in range(0, u*2, 2)])
        faces.append([i for i in range(1, u*2, 2)])
        faces[-1].reverse()

        return vertices, faces
Exemple #17
0
    def blocks(self):
        """Compute the blocks.

        Returns
        -------
        list
            A list of blocks defined as simple meshes.

        Notes
        -----
        This method is used by the ``from_geometry`` constructor of the assembly data structure
        to create an assembly "from geometry".

        """
        if self.rise > self.span / 2:
            raise Exception("Not a semicircular arch.")

        radius = self.rise / 2 + self.span**2 / (8 * self.rise)
        # base = [0.0, 0.0, 0.0]
        top = [0.0, 0.0, self.rise]
        left = [-self.span / 2, 0.0, 0.0]
        center = [0.0, 0.0, self.rise - radius]
        vector = subtract_vectors(left, center)
        springing = angle_vectors(vector, [-1.0, 0.0, 0.0])
        sector = radians(180) - 2 * springing
        angle = sector / self.n

        a = top
        b = add_vectors(top, [0, self.depth, 0])
        c = add_vectors(top, [0, self.depth, self.thickness])
        d = add_vectors(top, [0, 0, self.thickness])

        R = Rotation.from_axis_and_angle([0, 1.0, 0], 0.5 * sector, center)
        bottom = transform_points([a, b, c, d], R)

        blocks = []
        for i in range(self.n):
            R = Rotation.from_axis_and_angle([0, 1.0, 0], -angle, center)
            top = transform_points(bottom, R)
            vertices = bottom + top
            faces = [[0, 1, 2, 3], [7, 6, 5, 4], [3, 7, 4, 0], [6, 2, 1, 5],
                     [7, 3, 2, 6], [5, 1, 0, 4]]
            mesh = Mesh.from_vertices_and_faces(vertices, faces)
            blocks.append(mesh)
            bottom = top

        return blocks
Exemple #18
0
def offset_bbox_xy(pts, dist):
    bbox = pca_numpy(pts)
    frame1 = Frame(bbox[0], bbox[1][0], bbox[1][1])
    xform = Transformation.from_frame_to_frame(frame1, Frame.worldXY())
    pts = transform_points(pts, xform)
    bbox = bounding_box_xy(pts)
    bbox = offset_polygon(bbox, dist)
    return bbox, xform
Exemple #19
0
    def to_vertices_and_faces(self, u=16, triangulated=False):
        """Returns a list of vertices and faces.

        Parameters
        ----------
        u : int, optional
            Number of faces in the "u" direction.
        triangulated: bool, optional
            Flag indicating that the faces have to be triangulated.

        Returns
        -------
        (vertices, faces)
            A list of vertex locations and a list of faces,
            with each face defined as a list of indices into the list of vertices.
        """
        if u < 3:
            raise ValueError('The value for u should be u > 3.')

        vertices = []
        a = 2 * pi / u
        z = self.height / 2
        for i in range(u):
            x = self.circle.radius * cos(i * a)
            y = self.circle.radius * sin(i * a)
            vertices.append([x, y, z])
            vertices.append([x, y, -z])
        # add v in bottom and top's circle center
        vertices.append([0, 0, z])
        vertices.append([0, 0, -z])

        # transform vertices to cylinder's plane
        frame = Frame.from_plane(self.circle.plane)
        M = matrix_from_frame(frame)
        vertices = transform_points(vertices, M)

        faces = []
        # side faces
        for i in range(0, u * 2, 2):
            faces.append([i, i + 1, (i + 3) % (u * 2), (i + 2) % (u * 2)])
        # top and bottom circle faces
        for i in range(0, u * 2, 2):
            top = [i, (i + 2) % (u * 2), len(vertices) - 2]
            bottom = [i + 1, (i + 3) % (u * 2), len(vertices) - 1]
            faces.append(top)
            faces.append(bottom[::-1])

        if triangulated:
            triangles = []
            for face in faces:
                if len(face) == 4:
                    triangles.append(face[0:3])
                    triangles.append([face[0], face[2], face[3]])
                else:
                    triangles.append(face)
            faces = triangles

        return vertices, faces
Exemple #20
0
    def transform_network(self, transformation):
        nodes = [self.node_coordinates(key) for key in self.nodes()]
        xyz = transform_points(nodes, transformation)
        for index, (key, attr) in enumerate(self.nodes(True)):
            attr["x"] = xyz[index][0]
            attr["y"] = xyz[index][1]
            attr["z"] = xyz[index][2]

        self.build_dist_dict()
Exemple #21
0
    def transform(self, transformation):
        """Transform the polyhedron.

        Parameters
        ----------
        transformation : :class:`Transformation`

        """
        self.vertices = transform_points(self.vertices, transformation)
Exemple #22
0
 def apply_xform(self, M):
     key_index = self.key_index()
     points = self.get_vertices_attributes('xyz')
     points = transform_points(points, M)
     for key, attr in self.vertices(True):
         index = key_index[key]
         x, y, z = points[index]
         attr['x'] = x
         attr['y'] = y
         attr['z'] = z
Exemple #23
0
    def to_vertices_and_faces(self, u=16, triangulated=False):
        """Returns a list of vertices and faces.

        Parameters
        ----------
        u : int, optional
            Number of faces in the "u" direction.
        triangulated: bool, optional
            If True, triangulate the faces.

        Returns
        -------
        list[list[float]]
            A list of vertex locations.
        list[list[int]]
            And a list of faces,
            with each face defined as a list of indices into the list of vertices.

        """
        if u < 3:
            raise ValueError('The value for u should be u > 3.')

        vertices = [[0, 0, 0]]
        a = 2 * pi / u
        radius = self.circle.radius
        for i in range(u):
            x = radius * cos(i * a)
            y = radius * sin(i * a)
            vertices.append([x, y, 0])
        vertices.append([0, 0, self.height])

        frame = Frame.from_plane(self.circle.plane)
        M = matrix_from_frame(frame)
        vertices = transform_points(vertices, M)

        faces = []
        first = 0
        last = len(vertices) - 1
        for i, j in pairwise(range(1, last)):
            faces.append([i, j, last])
            faces.append([j, i, first])
        faces.append([last - 1, 1, last])
        faces.append([1, last - 1, first])

        if triangulated:
            triangles = []
            for face in faces:
                if len(face) == 4:
                    triangles.append(face[0:3])
                    triangles.append([face[0], face[2], face[3]])
                else:
                    triangles.append(face)
            faces = triangles

        return vertices, faces
    def draw_blocks(self, keys=None, show_faces=False, show_vertices=False, show_edges=True):
        """Draw the blocks of the assembly.

        Parameters
        ----------
        show_faces : bool, optional
            Draw the faces of the blocks.
            Default is ``False``.
        show_vertices : bool, optional
            Draw the vertices of the blocks.
            Default is ``False``.
        show_edges : bool, optional
            Draw the edges of the blocks.
            Default is ``True``.

        Notes
        -----
        * By default, blocks are drawn as wireframes.
        * By default, blocks are drawn on a sublayer of the base layer, if a base layer was specified.
        * Block names have the following pattern: ``"{assembly_name}.block.{block_id}"``
        * Faces and vertices can be drawn using the corresponding flags.
        * Block components have the following pattern:

          * face: ``"{assembly_name}.block.{block_id}.face.{face_id}"``
          * edge: ``"{assembly_name}.block.{block_id}.edge.{edge_id}"``
          * vertex: ``"{assembly_name}.block.{block_id}.vertex.{vertex_id}"``

        Examples
        --------
        >>>
        """
        blocks = []
        # compas_blender.clear_collection()
        for key in self.assembly.nodes():
            block = self.assembly.blocks[key]
            centroid = block.centroid()
            T = Translation(subtract_vectors([0, 0, 0], centroid))
            name = "Assembly.block.{}".format(key)
            vertices = transform_points(block.vertices_attributes('xyz'), T)
            edges = list(block.edges())
            faces = [block.face_vertices(fkey) for fkey in block.faces()]
            mesh = compas_blender.bpy.data.meshes.new(name)
            mesh.from_pydata(vertices, edges, faces)
            obj = compas_blender.bpy.data.objects.new(name, mesh)
            obj.show_wire = True
            obj.location = centroid
            if self.assembly.node_attribute(key, 'is_support'):
                compas_blender.drawing.set_object_color(obj, [1.0, 0.0, 0.0])
            else:
                compas_blender.drawing.set_object_color(obj, [1.0, 1.0, 1.0])
            blocks.append(obj)
        for obj in blocks:
            for col in obj.users_collection:
                col.objects.unlink(obj)
            self.block_collection.objects.link(obj)
Exemple #25
0
    def transform(self, transformation):
        """Transform the polyhedron.

        Parameters
        ----------
        transformation : :class:`compas.geometry.Transformation`

        Returns
        -------
        None

        """
        self.vertices = transform_points(self.vertices, transformation)
Exemple #26
0
    def transform(self, matrix):
        """Transform this ``Polygon`` using a given transformation matrix.

        Parameters
        ----------
        matrix : list of list
            The transformation matrix.

        """
        for index, point in enumerate(transform_points(self.points, matrix)):
            self.points[index].x = point[0]
            self.points[index].y = point[1]
            self.points[index].z = point[2]
Exemple #27
0
    def to_vertices_and_faces(self, u=10, v=10):
        """Returns a list of vertices and faces

        Parameters
        ----------
        u : int, optional
            Number of faces in the "u" direction.
            Default is ``10``.
        v : int, optional
            Number of faces in the "v" direction.
            Default is ``10``.

        Returns
        -------
        (vertices, faces)
            A list of vertex locations and a list of faces,
            with each face defined as a list of indices into the list of vertices.
        """
        if u < 3:
            raise ValueError('The value for u should be u > 3.')
        if v < 3:
            raise ValueError('The value for v should be v > 3.')

        theta = pi * 2 / u
        phi = pi * 2 / v
        vertices = []
        for i in range(u):
            for j in range(v):
                x = cos(i * theta) * (self.radius_axis +
                                      self.radius_pipe * cos(j * phi))
                y = sin(i * theta) * (self.radius_axis +
                                      self.radius_pipe * cos(j * phi))
                z = self.radius_pipe * sin(j * phi)
                vertices.append([x, y, z])

        # transform vertices to torus' plane
        frame = Frame.from_plane(self.plane)
        M = matrix_from_frame(frame)
        vertices = transform_points(vertices, M)

        faces = []
        for i in range(u):
            ii = (i + 1) % u
            for j in range(v):
                jj = (j + 1) % v
                a = i * v + j
                b = ii * v + j
                c = ii * v + jj
                d = i * v + jj
                faces.append([a, b, c, d])
        return vertices, faces
Exemple #28
0
    def to_vertices_and_faces(self, u=10):
        """Returns a list of vertices and faces.

        Parameters
        ----------
        u : int, optional
            Number of faces in the "u" direction.
            Default is ``10``.

        Returns
        -------
        (vertices, faces)
            A list of vertex locations and a list of faces,
            with each face defined as a list of indices into the list of vertices.
        """
        if u < 3:
            raise ValueError('The value for u should be u > 3.')

        vertices = []
        a = 2 * pi / u
        z = self.height / 2
        for i in range(u):
            x = self.circle.radius * cos(i * a)
            y = self.circle.radius * sin(i * a)
            vertices.append([x, y, z])
            vertices.append([x, y, -z])
        # add v in bottom and top's circle center
        vertices.append([0, 0, z])
        vertices.append([0, 0, -z])

        # transform vertices to cylinder's plane
        frame = Frame.from_plane(self.circle.plane)
        M = matrix_from_frame(frame)
        vertices = transform_points(vertices, M)

        faces = []
        # side faces
        for i in range(0, u * 2, 2):
            faces.append([i, i + 1, (i + 3) % (u * 2), (i + 2) % (u * 2)])
        # top and bottom circle faces
        for i in range(0, u * 2, 2):
            top = [i, (i + 2) % (u * 2), len(vertices) - 2]
            bottom = [i + 1, (i + 3) % (u * 2), len(vertices) - 1]
            faces.append(top)
            faces.append(bottom[::-1])

        return vertices, faces
Exemple #29
0
    def transform(self, T):
        """Apply a transformation to the pointcloud.

        Parameters
        ----------
        T : :class:`compas.geometry.Transformation`
            The transformation.

        Returns
        -------
        None
            The cloud is modified in place.
        """
        for index, point in enumerate(transform_points(self.points, T)):
            self.points[index].x = point[0]
            self.points[index].y = point[1]
            self.points[index].z = point[2]
    def draw_interfaces(self, keys=None, color=None):
        """Draw the interfaces between the blocks.

        Parameters
        ----------
        keys : list
            A list of interface identifiers (i.e. assembly edge (u, v) tuples).
            Default is ``None``, in which case all interfaces are drawn.
        color : str, tuple, dict
            The color specififcation for the interfaces.
            Colors should be specified in the form of a string (hex colors) or
            as a tuple of RGB components.
            To apply the same color to all interfaces, provide a single color
            specification. Individual colors can be assigned using a dictionary
            of key-color pairs. Missing keys will be assigned the default interface
            color (``self.settings['color.interface']``).
            The default is ``None``, in which case all interfaces are assigned the
            default interface color.

        Notes
        -----
        * Interfaces are drawn as mesh faces.
        * Interfaces are drawn on a sub-layer *Interfaces* of the base layer, if a base layer was provided.
        * Interface names have the following pattern: ``"{assembly_name}.interface.{from block_id}-{to block_id}"``
        * Interfaces have a direction, as suggested by the naming convention.
        """
        interfaces = []
        for key, attr in self.assembly.edges(True):
            u, v = key
            name = "Assembly.interface.{}-{}".format(u, v)
            points = attr['interface_points']
            base = attr['interface_origin']
            T = Translation(subtract_vectors([0, 0, 0], base))
            vertices = transform_points(points, T)
            faces = [list(range(len(vertices)))]
            edges = list(pairwise(faces[0] + [0]))
            mesh = compas_blender.bpy.data.meshes.new(name)
            mesh.from_pydata(vertices, edges, faces)
            obj = compas_blender.bpy.data.objects.new(name, mesh)
            obj.location = base
            compas_blender.drawing.set_object_color(obj, [0, 0, 1.0])
            interfaces.append(obj)
        for obj in interfaces:
            for col in obj.users_collection:
                col.objects.unlink(obj)
            self.interface_collection.objects.link(obj)