예제 #1
0
파일: text.py 프로젝트: kloppen/ezdxf
def _get_rotation(text: AnyText) -> Matrix44:
    if isinstance(text, Text):
        return Matrix44.axis_rotate(text.dxf.extrusion, radians(text.dxf.rotation))
    if isinstance(text, MText):
        return Matrix44.axis_rotate(text.dxf.extrusion, radians(text.get_rotation()))
    elif isinstance(text, Attrib):
        return Matrix44()
    else:
        raise TypeError(type(text))
예제 #2
0
def _get_rotation(text: AnyText) -> Matrix44:
    if isinstance(text, Text):  # Attrib and AttDef are sub-classes of Text
        if text.get_align() in ("FIT", "ALIGNED"):
            rotation = _calc_aligned_rotation(text)
        else:
            rotation = radians(text.dxf.rotation)
        return Matrix44.axis_rotate(text.dxf.extrusion, rotation)
    elif isinstance(text, MText):
        return Matrix44.axis_rotate(Vec3(0, 0, 1), radians(text.get_rotation()))
    else:
        raise TypeError(type(text))
예제 #3
0
    def matrix44(self) -> Matrix44:
        """Returns a transformation matrix of type :class:`Matrix44` to
        transform the block entities into :ref:`WCS`.

        """
        dxf = self.dxf
        sx = dxf.xscale
        sy = dxf.yscale
        sz = dxf.zscale

        ocs = self.ocs()
        extrusion = ocs.uz
        ux = Vec3(ocs.to_wcs(X_AXIS))
        uy = Vec3(ocs.to_wcs(Y_AXIS))
        m = Matrix44.ucs(ux=ux * sx, uy=uy * sy, uz=extrusion * sz)
        # same as Matrix44.ucs(ux, uy, extrusion) * Matrix44.scale(sx, sy, sz)

        angle = math.radians(dxf.rotation)
        if angle:
            m *= Matrix44.axis_rotate(extrusion, angle)

        insert = ocs.to_wcs(dxf.get("insert", NULLVEC))

        block_layout = self.block()
        if block_layout is not None:
            # transform block base point into WCS without translation
            insert -= m.transform_direction(
                block_layout.block.dxf.base_point)  # type: ignore

        # set translation
        m.set_row(3, insert.xyz)  # type: ignore
        return m
예제 #4
0
파일: forms.py 프로젝트: tbwhsb88/ezdxf
def rotation_form(count: int, profile: Iterable['Vertex'], angle: float = 2 * pi,
                  axis: 'Vertex' = (1, 0, 0)) -> MeshTransformer:
    """
    Create MESH entity by rotating a `profile` around an `axis`.

    Args:
        count: count of rotated profiles
        profile: profile to rotate as list of vertices
        angle: rotation angle in radians
        axis: rotation axis

    Returns: :class:`~ezdxf.render.MeshTransformer`

    """
    if count < 3:
        raise ValueError('count >= 2')
    delta = float(angle) / count
    m = Matrix44.axis_rotate(Vector(axis), delta)
    profile = [Vector(p) for p in profile]
    profiles = [profile]
    for _ in range(int(count)):
        profile = list(m.transform_vertices(profile))
        profiles.append(profile)
    mesh = from_profiles_linear(profiles, close=False, caps=False)
    return mesh
예제 #5
0
    def matrix44(self) -> Matrix44:
        """ Returns a transformation :class:`Matrix44` object to transform block
        entities into WCS.

        .. versionadded:: 0.13

        """
        dxf = self.dxf
        sx = dxf.xscale
        sy = dxf.yscale
        sz = dxf.zscale

        ocs = self.ocs()
        extrusion = ocs.uz
        ux = Vector(ocs.to_wcs(X_AXIS))
        uy = Vector(ocs.to_wcs(Y_AXIS))
        m = Matrix44.ucs(ux=ux * sx, uy=uy * sy, uz=extrusion * sz)

        angle = math.radians(dxf.rotation)
        if angle != 0.0:
            m = Matrix44.chain(m, Matrix44.axis_rotate(extrusion, angle))

        insert = ocs.to_wcs(dxf.get('insert', Vector()))

        block_layout = self.block()
        if block_layout is not None:
            # transform block base point into WCS without translation
            insert -= m.transform_direction(block_layout.block.dxf.base_point)

        # set translation
        m.set_row(3, insert.xyz)
        return m
예제 #6
0
def rotation_form(
    count: int,
    profile: Iterable['Vertex'],
    angle: float = 2 * pi,
    axis: 'Vertex' = (1, 0, 0)) -> MeshVertexMerger:
    """
    Mesh by rotating a profile around an axis.

    Args:
        count: count of rotated profiles
        profile: profile to rotate as list of vertices
        angle: rotation angle in radians
        axis: rotation axis

    Returns: MeshVertexMerger()

    """
    if count < 3:
        raise ValueError('count >= 2')
    delta = float(angle) / count
    m = Matrix44.axis_rotate(Vector(axis), delta)
    profile = [Vector(p) for p in profile]
    profiles = [profile]
    for _ in range(int(count)):
        profile = m.transform_vectors(profile)
        profiles.append(profile)
    mesh = from_profiles_linear(profiles, close=False, caps=False)
    return mesh
예제 #7
0
 def build():
     circle = Circle()
     vertices = list(circle.vertices(linspace(0, 360, vertex_count, endpoint=False)))
     m = Matrix44.chain(
         Matrix44.axis_rotate(axis=Vec3.random(), angle=random.uniform(0, math.tau)),
         Matrix44.translate(dx=random.uniform(-2, 2), dy=random.uniform(-2, 2), dz=random.uniform(-2, 2)),
     )
     return synced_transformation(circle, vertices, m)
예제 #8
0
def build(angle, dx, dy, dz, axis, start, end, count):
    ellipse = Ellipse.new(dxfattribs={
        'start_param': start,
        'end_param': end,
    })
    vertices = list(ellipse.vertices(ellipse.params(count)))
    m = Matrix44.chain(Matrix44.axis_rotate(axis=axis, angle=angle),
                       Matrix44.translate(dx=dx, dy=dy, dz=dz))
    return synced_transformation(ellipse, vertices, m)
예제 #9
0
    def rotate_local_x(self, angle: float) -> 'UCS':
        """ Returns a new rotated UCS, rotation axis is the local x-axis.

        Args:
             angle: rotation angle in radians

        """
        t = Matrix44.axis_rotate(self.ux, angle)
        uy, uz = t.transform_vertices([self.uy, self.uz])
        return UCS(origin=self.origin, ux=self.ux, uy=uy, uz=uz)
예제 #10
0
파일: ucs.py 프로젝트: Rahulghuge94/ezdxf
    def rotate_local_z(self, angle: float) -> "UCS":
        """Returns a new rotated UCS, rotation axis is the local z-axis.

        Args:
             angle: rotation angle in radians

        """
        t = Matrix44.axis_rotate(self.uz, angle)
        ux, uy = t.transform_vertices([self.ux, self.uy])
        return UCS(origin=self.origin, ux=ux, uy=uy, uz=self.uz)
예제 #11
0
    def rotate_axis(self, axis: "Vertex", angle: float) -> "DXFGraphic":
        """Rotate entity inplace about vector `axis`, returns `self`
        (floating interface).

        Args:
            axis: rotation axis as tuple or :class:`Vec3`
            angle: rotation angle in radians

        """
        return self.transform(Matrix44.axis_rotate(axis, angle))
예제 #12
0
 def build():
     arc = Arc.new(dxfattribs={
         'start_angle': random.uniform(0, 360),
         'end_angle': random.uniform(0, 360),
     })
     vertices = list(arc.vertices(arc.angles(vertex_count)))
     m = Matrix44.chain(
         Matrix44.axis_rotate(axis=Vec3.random(), angle=random.uniform(0, math.tau)),
         Matrix44.translate(dx=random.uniform(-2, 2), dy=random.uniform(-2, 2), dz=random.uniform(-2, 2)),
     )
     return synced_transformation(arc, vertices, m)
예제 #13
0
 def build():
     ellipse = Ellipse.new(dxfattribs={
         'start_param': start,
         'end_param': end,
     })
     vertices = list(ellipse.vertices(ellipse.params(vertex_count)))
     m = Matrix44.chain(
         Matrix44.axis_rotate(axis=Vec3.random(), angle=random.uniform(0, math.tau)),
         Matrix44.translate(dx=random.uniform(-2, 2), dy=random.uniform(-2, 2), dz=random.uniform(-2, 2)),
     )
     return synced_transformation(ellipse, vertices, m)
예제 #14
0
    def _rotate_local_z(self, angle: float) -> None:
        """
        Rotate axis around the local z-axis inplace.

        Args:
             angle: rotation angle in radians

        """
        t = Matrix44.axis_rotate(self._matrix.uz, angle)
        ux, uy = t.transform_vectors([self._matrix.ux, self._matrix.uy])
        self._matrix = Matrix33(ux, uy, self._matrix.uz)
예제 #15
0
파일: mesh.py 프로젝트: jrflack/ezdxf
    def rotate_axis(self, axis: 'Vertex', angle: float):
        """
        Rotate mesh around an arbitrary axis located in the origin (0, 0, 0) about `angle`.

        Args:
            axis: rotation axis as Vector
            angle: rotation angle in radians

        """
        self.vertices = Matrix44.axis_rotate(axis, angle).transform_vectors(self.vertices)
        return self
예제 #16
0
    def rotate_axis(self, axis: 'Vertex', angle: float) -> 'DXFGraphic':
        """ Rotate entity inplace about vector `axis`, returns `self` (floating interface).

        Args:
            axis: rotation axis as tuple or :class:`Vector`
            angle: rotation angle in radians

        .. versionadded:: 0.13

        """
        return self.transform(Matrix44.axis_rotate(axis, angle))
예제 #17
0
def synced_rotation(entity,
                    chk,
                    axis_vertices=None,
                    axis=Z_AXIS,
                    angle: float = 0):
    entity = entity.copy()
    entity.rotate_axis(axis, angle)
    m = Matrix44.axis_rotate(axis, angle)
    chk = list(m.transform_vertices(chk))
    if axis_vertices:
        axis_vertices = list(m.transform_vertices(axis_vertices))
        return entity, chk, axis_vertices
    return entity, chk
예제 #18
0
파일: ucs.py 프로젝트: Rahulghuge94/ezdxf
    def rotate(self, axis: "Vertex", angle: float) -> "UCS":
        """Returns a new rotated UCS, with the same origin as the source UCS.
        The rotation vector is located in the origin and has :ref:`WCS`
        coordinates e.g. (0, 0, 1) is the WCS z-axis as rotation vector.

        Args:
            axis: arbitrary rotation axis as vector in :ref:`WCS`
            angle: rotation angle in radians

        """
        t = Matrix44.axis_rotate(Vec3(axis), angle)
        ux, uy, uz = t.transform_vertices([self.ux, self.uy, self.uz])
        return UCS(origin=self.origin, ux=ux, uy=uy, uz=uz)
예제 #19
0
def test_transformation():
    axis = Vec3.random()
    angle = 1.5
    ucs = UCS(origin=(3, 4, 5))
    m = Matrix44.axis_rotate(axis, angle)
    expected_origin = m.transform(ucs.origin)
    expected_ux = m.transform(ucs.ux)
    expected_uy = m.transform(ucs.uy)
    expected_uz = m.transform(ucs.uz)
    new = ucs.transform(m)

    assert new.origin.isclose(expected_origin)
    assert new.ux.isclose(expected_ux)
    assert new.uy.isclose(expected_uy)
    assert new.uz.isclose(expected_uz)
예제 #20
0
def test_random_block_reference_transformation(sx, sy, sz, doc1: "Drawing"):
    def insert():
        return (
            Insert.new(
                dxfattribs={
                    "name": "AXIS",
                    "insert": (0, 0, 0),
                    "xscale": 1,
                    "yscale": 1,
                    "zscale": 1,
                    "rotation": 0,
                    "layer": "insert",
                },
                doc=doc1,
            ),
            [Vec3(0, 0, 0), X_AXIS, Y_AXIS, Z_AXIS],
        )

    def check(lines, chk):
        origin, x, y, z = chk
        l1, l2, l3 = lines
        assert origin.isclose(l1.dxf.start)
        assert x.isclose(l1.dxf.end)
        assert origin.isclose(l2.dxf.start)
        assert y.isclose(l2.dxf.end)
        assert origin.isclose(l3.dxf.start)
        assert z.isclose(l3.dxf.end)

    entity0, vertices0 = insert()
    entity0, vertices0 = synced_scaling(entity0, vertices0, 1, 2, 3)

    m = Matrix44.chain(
        # Transformation order is important: scale - rotate - translate
        # Because scaling after rotation leads to a non orthogonal
        # coordinate system, which can not represented by the
        # INSERT entity.
        Matrix44.scale(sx, sy, sz),
        Matrix44.axis_rotate(axis=Vec3.random(),
                             angle=random.uniform(0, math.tau)),
        Matrix44.translate(
            dx=random.uniform(-2, 2),
            dy=random.uniform(-2, 2),
            dz=random.uniform(-2, 2),
        ),
    )
    entity, vertices = synced_transformation(entity0, vertices0, m)
    lines = list(entity.virtual_entities())
    check(lines, vertices)
예제 #21
0
def synced_rotation(entity, chk, axis, angle):
    entity = entity.copy()
    entity.rotate_axis(axis, angle)
    chk = list(Matrix44.axis_rotate(axis, angle).transform_vertices(chk))
    return entity, chk
예제 #22
0
def ucs_rotation(ucs: UCS, axis: Vec3, angle: float):
    # new in ezdxf v0.11: UCS.rotate(axis, angle)
    t = Matrix44.axis_rotate(axis, math.radians(angle))
    ux, uy, uz = t.transform_vertices([ucs.ux, ucs.uy, ucs.uz])
    return UCS(origin=ucs.origin, ux=ux, uy=uy, uz=uz)
예제 #23
0
# transform insert location to OCS
insert = ucs.to_ocs((0, 0, 0))
# rotation angle about the z-axis (= WCS x-axis)
rotation = ucs.to_ocs_angle_deg(15)
msp.add_blockref('CSYS',
                 insert,
                 dxfattribs={
                     'extrusion': ucs.uz,
                     'rotation': rotation,
                 })

# To rotate a block reference around the block x-axis,
# you have to find the rotated z-axis (= extrusion vector)
# of the rotated block reference:
# t is a transformation matrix to rotate 15 degree around the x-axis
t = Matrix44.axis_rotate(axis=X_AXIS, angle=math.radians(15))
# transform block z-axis into new UCS z-axis (= extrusion vector)
uz = Vec3(t.transform(Z_AXIS))
# create new UCS at the insertion point, because we are rotating around the x-axis,
# ux is the same as the WCS x-axis and uz is the rotated z-axis.
ucs = UCS(origin=(1, 2, 0), ux=X_AXIS, uz=uz)
# transform insert location to OCS, block base_point=(0, 0, 0)
insert = ucs.to_ocs((0, 0, 0))
# for this case a rotation around the z-axis is not required
rotation = 0
blockref = msp.add_blockref('CSYS',
                            insert,
                            dxfattribs={
                                'extrusion': ucs.uz,
                                'rotation': rotation,
                            })
예제 #24
0
파일: insert.py 프로젝트: iromero91/ezdxf
def main():
    doc = ezdxf.new('R2010', setup=True)
    blk = doc.blocks.new('CSYS')
    setup_csys(blk)
    msp = doc.modelspace()

    # The DXF attribute `rotation` rotates a block reference always around the block z-axis:
    # To rotate the block reference around the WCS x-axis,
    # you have to transform the block z-axis into the WCS x-axis:
    # rotate block axis 90 deg ccw around y-axis, by using an UCS
    ucs = ucs_rotation(UCS(), axis=Y_AXIS, angle=90)
    # transform insert location, not required for (0, 0, 0)
    insert = ucs.to_ocs((0, 0, 0))
    # rotation angle about the z-axis (= WCS x-axis)
    rotation = ucs.to_ocs_angle_deg(15)
    # msp.add_blockref('CSYS', insert, dxfattribs={
    #    'extrusion': ucs.uz,
    #    'rotation': rotation,
    # })

    # To rotate a block reference around the block x-axis,
    # you have to find the rotated z-axis (= extrusion vector)
    # of the rotated block reference:
    # t is a transformation matrix to rotate 15 degree around the x-axis
    t = Matrix44.axis_rotate(axis=X_AXIS, angle=math.radians(15))
    # transform block z-axis into new UCS z-axis (= extrusion vector)
    uz = Vector(t.transform(Z_AXIS))
    # create new UCS at the insertion point, because we are rotating around the x-axis,
    # ux is the same as the WCS x-axis and uz is the rotated z-axis.
    ucs = UCS(origin=(1, 2, 0), ux=X_AXIS, uz=uz)
    # transform insert location to OCS, block base_point=(0, 0, 0)
    insert = ucs.to_ocs((0, 0, 0))
    # for this case a rotation around the z-axis is not required
    rotation = 0
    blockref = msp.add_blockref('CSYS', insert, dxfattribs={
        'extrusion': ucs.uz,
        'rotation': rotation,
    })

    # translate a block references with an established OCS
    translation = Vector(-3, -1, 1)
    # get established OCS
    ocs = blockref.ocs()
    # get insert location in WCS
    actual_wcs_location = ocs.to_wcs(blockref.dxf.insert)
    # translate location
    new_wcs_location = actual_wcs_location + translation
    # convert WCS location to OCS location
    blockref.dxf.insert = ocs.from_wcs(new_wcs_location)

    # rotate a block references with an established OCS around the block y-axis about 90 degree
    ocs = blockref.ocs()
    # convert block y-axis (= rotation axis) into WCS vector
    rotation_axis = ocs.to_wcs((0, 1, 0))
    # convert local z-axis (=extrusion vector) into WCS vector
    local_z_axis = ocs.to_wcs((0, 0, 1))
    # build transformation matrix
    t = Matrix44.axis_rotate(axis=rotation_axis, angle=math.radians(-90))
    uz = t.transform(local_z_axis)
    uy = rotation_axis
    # the block reference origin stays at the same location, no rotation needed
    wcs_insert = ocs.to_wcs(blockref.dxf.insert)
    # build new UCS to convert WCS locations and angles into OCS
    ucs = UCS(origin=wcs_insert, uy=uy, uz=uz)

    # set new OCS
    blockref.dxf.extrusion = ucs.uz
    # set new insert
    blockref.dxf.insert = ucs.to_ocs((0, 0, 0))
    # set new rotation: we do not rotate the block reference around the local z-axis,
    # but the new block x-axis (0 deg) differs from OCS x-axis and has to be adjusted
    blockref.dxf.rotation = ucs.to_ocs_angle_deg(0)

    doc.set_modelspace_vport(5)
    doc.saveas('ocs_insert.dxf')