Beispiel #1
0
 def test_transform_mtext_extrusion(self):
     """The extrusion vector is always created by the right-hand-rule from
     the transformed x- and y-axis: Z = X "cross" Y.
     """
     mtext = MTextData()
     m = Matrix44.scale(-1, 1, 1)
     mtext.transform(WCSTransform(m))
     assert mtext.text_direction.isclose(m.transform(X_AXIS))
     assert mtext.extrusion.isclose(
         -m.transform(Z_AXIS)), "expected reversed z-axis"
Beispiel #2
0
    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)
Beispiel #3
0
def _matrix_to_qtransform(matrix: Matrix44) -> qg.QTransform:
    """ Qt also uses row-vectors so the translation elements are placed in the bottom row

    This is only a simple conversion which assumes that although the transformation is 4x4,
    it does not involve the z axis.

    A more correct transformation could be implemented like so:
    https://stackoverflow.com/questions/10629737/convert-3d-4x4-rotation-matrix-into-2d
    """
    return qg.QTransform(*matrix.get_2d_transformation())
Beispiel #4
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))
 def test_to_polylines2d_with_ocs(self, path1):
     m = Matrix44.x_rotate(math.pi / 4)
     path = path1.transform(m)
     extrusion = m.transform((0, 0, 1))
     polylines = list(to_polylines2d(path, extrusion=extrusion))
     p0 = polylines[0]
     assert p0.dxf.elevation.isclose((0, 0, 1))
     assert p0.dxf.extrusion.isclose(extrusion)
     assert p0[0].dxf.location.isclose((0, 0, 1))
     assert p0[-1].dxf.location.isclose((4, 0, 1))
Beispiel #6
0
    def rotate_z(self, angle: float):
        """Rotate mesh around z-axis about `angle` inplace.

        Args:
            angle: rotation angle in radians

        """
        self.vertices = list(
            Matrix44.z_rotate(angle).transform_vertices(self.vertices))
        return self
Beispiel #7
0
    def transform(self, m: Matrix44) -> 'Point':
        """ Transform POINT entity by transformation matrix `m` inplace.

        .. versionadded:: 0.13

        """
        self.dxf.location = m.transform(self.dxf.location)
        transform_thickness_and_extrusion_without_ocs(self, m)
        # ignore dxf.angle!
        return self
Beispiel #8
0
def test_matrix44_to_wcs():
    ocs = OCS(EXTRUSION)
    matrix = Matrix44.ucs(ocs.ux, ocs.uy, ocs.uz)
    matrix.transpose()
    assert is_close_points(
        matrix.transform(
            (9.41378764657076, 13.15481838975576, 0.8689258932616031)),
        (-9.56460754, 8.44764172, 9.97894327),
        places=6,
    )
Beispiel #9
0
def test_transform():
    point = Point.new(
        dxfattribs={
            "location": (2, 3, 4),
            "extrusion": (0, 1, 0),
            "thickness": 2,
        }
    )
    # 1. rotation - 2. scaling - 3. translation
    m = Matrix44.chain(Matrix44.scale(2, 3, 1), Matrix44.translate(1, 1, 1))
    point.transform(m)
    assert point.dxf.location == (5, 10, 5)
    assert point.dxf.extrusion == (0, 1, 0)
    assert point.dxf.thickness == 6

    angle = math.pi / 4
    point.transform(Matrix44.z_rotate(math.pi / 4))
    assert point.dxf.extrusion.isclose((-math.cos(angle), math.sin(angle), 0))
    assert math.isclose(point.dxf.thickness, 6)
Beispiel #10
0
    def translate(self, dx: float, dy: float, dz: float) -> "XLine":
        """Optimized XLINE/RAY translation about `dx` in x-axis, `dy` in
        y-axis and `dz` in z-axis.

        """
        self.dxf.start = Vec3(dx, dy, dz) + self.dxf.start
        # Avoid Matrix44 instantiation if not required:
        if self.is_post_transform_required:
            self.post_transform(Matrix44.translate(dx, dy, dz))
        return self
Beispiel #11
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)
Beispiel #12
0
    def translate(self, dx: float, dy: float, dz: float) -> "Ellipse":
        """Optimized ELLIPSE translation about `dx` in x-axis, `dy` in y-axis
        and `dz` in z-axis, returns `self` (floating interface).

        """
        self.dxf.center = Vec3(dx, dy, dz) + self.dxf.center
        # Avoid Matrix44 instantiation if not required:
        if self.is_post_transform_required:
            self.post_transform(Matrix44.translate(dx, dy, dz))
        return self
 def test_draw_scaled_path(self, backend):
     p1 = Path((1, 2))
     p1.line_to((2, 3))
     backend.draw_path(p1, Properties())
     f = backend.factor
     expected_p2 = p1.transform(Matrix44.scale(f, f, f))
     p2 = backend.collector[0][1]
     for v1, v2 in zip(p2.control_vertices(),
                       expected_p2.control_vertices()):
         assert v1.isclose(v2)
Beispiel #14
0
    def transform(self, m: Matrix44) -> None:
        """ Transform vertices by transformation matrix `m`.

        .. versionadded:: 0.13

        """
        values = array('d')
        for vertex in m.transform_vertices(self):
            values.extend(vertex)
        self.values = values
Beispiel #15
0
    def rotate_z(self, angle: float) -> 'DXFGraphic':
        """ Rotate entity inplace about z-axis, returns `self` (floating interface).

        Args:
            angle: rotation angle in radians

        .. versionadded:: 0.13

        """
        return self.transform(Matrix44.z_rotate(angle))
Beispiel #16
0
    def translate(self, dx: float, dy: float, dz: float) -> 'DXFGraphic':
        """ Translate entity inplace about `dx` in x-axis, `dy` in y-axis and `dz` in z-axis,
        returns `self` (floating interface).

        Basic implementation uses the :meth:`transform` interface, subclasses may have faster implementations.

        .. versionadded:: 0.13

        """
        return self.transform(Matrix44.translate(dx, dy, dz))
Beispiel #17
0
    def rotate_y(self, angle: float):
        """
        Rotate mesh around y-axis about `angle` inplace.

        Args:
            angle: rotation angle in radians

        """
        self.vertices = Matrix44.y_rotate(angle).transform_vectors(self.vertices)
        return self
Beispiel #18
0
 def test_to_lwpolylines_with_ocs(self, path1):
     m = Matrix44.x_rotate(math.pi / 4)
     path = path1.transform(m)
     extrusion = m.transform((0, 0, 1))
     polylines = list(to_lwpolylines(path, extrusion=extrusion))
     p0 = polylines[0]
     assert p0.dxf.elevation == pytest.approx(1)
     assert p0.dxf.extrusion.isclose(extrusion)
     assert p0[0] == (0, 0, 0, 0, 0)
     assert p0[-1] == (4, 0, 0, 0, 0)
Beispiel #19
0
def test_transform(p1):
    p2 = p1.transform(Matrix44.translate(1, 1, 0))
    assert p2.start.isclose((1, 1))
    assert p2[0].end.isclose((3, 1))  # line to location
    assert p2[1].end.isclose((5, 1))  # cubic to location
    assert p2[1].ctrl1.isclose((3, 2))  # cubic ctrl1
    assert p2[1].ctrl2.isclose((5, 2))  # cubic ctrl2
    assert p2[2].end.isclose((7, 1))  # quadratic to location
    assert p2[2].ctrl.isclose((6, 0))  # quadratic ctrl
    assert p2.end.isclose((7, 1))
Beispiel #20
0
def test_transform(p1):
    p2 = p1.transform(Matrix44.translate(1, 1, 0))
    assert p2.start == (1, 1)
    assert p2[0].end == (3, 1)  # line to location
    assert p2[1].end == (5, 1)  # cubic to location
    assert p2[1].ctrl1 == (3, 2)  # cubic ctrl1
    assert p2[1].ctrl2 == (5, 2)  # cubic ctrl2
    assert p2[2].end == (7, 1)  # quadratic to location
    assert p2[2].ctrl == (6, 0)  # quadratic ctrl
    assert p2.end == (7, 1)
Beispiel #21
0
def test_insert_transform_interface():
    insert = Insert()
    insert.dxf.insert = (1, 0, 0)

    insert.transform(Matrix44.translate(1, 2, 3))
    assert insert.dxf.insert == (2, 2, 3)

    # optimized translate implementation
    insert.translate(-1, -2, -3)
    assert insert.dxf.insert == (1, 0, 0)
Beispiel #22
0
    def transform(self, m: Matrix44) -> 'Line':
        """ Transform LINE entity by transformation matrix `m` inplace.

        .. versionadded:: 0.13

        """
        start, end = m.transform_vertices([self.dxf.start, self.dxf.end])
        self.dxf.start = start
        self.dxf.end = end
        transform_thickness_and_extrusion_without_ocs(self, m)
        return self
Beispiel #23
0
    def transform(self, m: Matrix44) -> 'Face3d':
        """ Transform 3DFACE  entity by transformation matrix `m` inplace.

        .. versionadded:: 0.13

        """
        dxf = self.dxf
        # 3DFACE is a real 3d entity
        dxf.vtx0, dxf.vtx1, dxf.vtx2, dxf.vtx3 = m.transform_vertices(
            (dxf.vtx0, dxf.vtx1, dxf.vtx2, dxf.vtx3))
        return self
Beispiel #24
0
 def test_multi_path_objects(self):
     path = Path()
     path.line_to((1, 0, 0))
     path.move_to((2, 0, 0))
     paths = transform_paths([path], Matrix44.translate(0, 1, 0))
     assert len(paths) == 1
     path2 = paths[0]
     assert path2.start.isclose((0, 1, 0))
     assert len(path2) == 2
     assert path2.end.isclose((2, 1, 0))
     assert path2.has_sub_paths is True
Beispiel #25
0
def test_transform_interface():
    text = Text()
    text.dxf.insert = (1, 0, 0)
    text.transform(Matrix44.translate(1, 2, 3))
    assert text.dxf.insert == (2, 2, 3)

    # optimized translate
    text.dxf.align_point = (3, 2, 1)
    text.translate(1, 2, 3)
    assert text.dxf.insert == (3, 4, 6)
    assert text.dxf.align_point == (4, 4, 4)
Beispiel #26
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))
Beispiel #27
0
 def test_to_hatches_with_ocs(self, path1):
     m = Matrix44.x_rotate(math.pi / 4)
     path = path1.transform(m)
     extrusion = m.transform((0, 0, 1))
     hatches = list(to_hatches(path, extrusion=extrusion))
     h0 = hatches[0]
     assert h0.dxf.elevation == (0, 0, 1)
     assert h0.dxf.extrusion.isclose(extrusion)
     polypath0 = h0.paths[0]
     assert polypath0.vertices[0] == (0, 0, 0)  # x, y, bulge
     assert polypath0.vertices[-1] == (0, 0, 0), "should be closed automatically"
Beispiel #28
0
def has_matrix_2d_stretching(m: Matrix44) -> bool:
    """Returns ``True`` if matrix `m` performs a non-uniform xy-scaling.
    Uniform scaling is not stretching in this context.

    Does not check if the target system is a cartesian coordinate system, use the
    :class:`~ezdxf.math.Matrix44` property :attr:`~ezdxf.math.Matrix44.is_cartesian`
    for that.
    """
    ux = m.transform_direction(X_AXIS)
    uy = m.transform_direction(Y_AXIS)
    return not math.isclose(ux.magnitude_square, uy.magnitude_square)
Beispiel #29
0
    def transform(self, m: Matrix44) -> 'Bezier':
        """ General transformation interface, returns a new :class:`Bezier` curve.

        Args:
             m: 4x4 transformation matrix (:class:`ezdxf.math.Matrix44`)

        .. versionadded:: 0.14

        """
        defpoints = tuple(m.transform_vertices(self.control_points))
        return Bezier(defpoints)
Beispiel #30
0
 def __init__(self, extrusion: Vec3 = None, m: Matrix44 = None):
     if m is None:
         self.m = Matrix44()
     else:
         self.m = m
     self.scale_uniform: bool = True
     if extrusion is None:  # fill in dummy values
         self._reset_ocs(_PLACEHOLDER_OCS, _PLACEHOLDER_OCS, True)
     else:
         new_extrusion, scale_uniform = transform_extrusion(extrusion, m)
         self._reset_ocs(OCS(extrusion), OCS(new_extrusion), scale_uniform)