示例#1
0
    def transform(self, m: 'Matrix44') -> 'LWPolyline':
        """ Transform LWPOLYLINE entity by transformation matrix `m` inplace.

        .. versionadded:: 0.13

        """
        dxf = self.dxf
        ocs = OCSTransform(self.dxf.extrusion, m)
        if not ocs.scale_uniform:
            raise NonUniformScalingError(
                '2D POLYLINE with arcs does not support non uniform scaling')
            # Parent function has to catch this Exception and explode this
            # LWPOLYLINE into LINE and ELLIPSE entities.
        vertices = list(
            ocs.transform_vertex(v) for v in self.vertices_in_ocs())
        lwpoints = [(v[0], v[1], p[2], p[3], p[4])
                    for v, p in zip(vertices, self.lwpoints)]
        self.set_points(lwpoints)

        # All new OCS vertices must have the same z-axis, which is the elevation
        # of the polyline:
        if vertices:
            dxf.elevation = vertices[0][2]

        if dxf.hasattr('thickness'):
            dxf.thickness = ocs.transform_length((0, 0, dxf.thickness),
                                                 reflection=dxf.thickness)
        dxf.extrusion = ocs.new_extrusion
        return self
示例#2
0
    def transform(self, m: Matrix44) -> 'Circle':
        """ Transform CIRCLE entity by transformation matrix `m` inplace.

        Raises ``NonUniformScalingError()`` for non uniform scaling.

        .. versionadded:: 0.13

        """
        ocs = OCSTransform(self.dxf.extrusion, m)
        dxf = self.dxf
        if ocs.scale_uniform:
            dxf.extrusion = ocs.new_extrusion
            dxf.center = ocs.transform_vertex(dxf.center)
            # old_ocs has a uniform scaled xy-plane, direction of radius-vector
            # in the xy-plane is not important, choose x-axis for no reason:
            dxf.radius = ocs.transform_length((dxf.radius, 0, 0))
            if dxf.hasattr('thickness'):
                # thickness vector points in the z-direction of the old_ocs,
                # thickness can be negative
                dxf.thickness = ocs.transform_length((0, 0, dxf.thickness),
                                                     reflection=dxf.thickness)
        else:
            # Caller has to catch this Exception and convert this
            # CIRCLE/ARC into an ELLIPSE.
            raise NonUniformScalingError(
                'CIRCLE/ARC does not support non uniform scaling')

        return self
示例#3
0
    def transform(self, m: Matrix44) -> 'Text':
        """ Transform TEXT entity by transformation matrix `m` inplace.

        .. versionadded:: 0.13

        """
        dxf = self.dxf
        if not dxf.hasattr('align_point'):
            dxf.align_point = dxf.insert
        ocs = OCSTransform(self.dxf.extrusion, m)
        dxf.insert = ocs.transform_vertex(dxf.insert)
        dxf.align_point = ocs.transform_vertex(dxf.align_point)
        old_rotation = dxf.rotation
        new_rotation = ocs.transform_deg_angle(old_rotation)
        x_scale = ocs.transform_length(Vec3.from_deg_angle(old_rotation))
        y_scale = ocs.transform_length(
            Vec3.from_deg_angle(old_rotation + 90.0))

        if not ocs.scale_uniform:
            oblique_vec = Vec3.from_deg_angle(
                old_rotation + 90.0 - dxf.oblique)
            new_oblique_deg = new_rotation + 90.0 - ocs.transform_direction(
                oblique_vec).angle_deg
            dxf.oblique = new_oblique_deg
            y_scale *= math.cos(math.radians(new_oblique_deg))

        dxf.width *= x_scale / y_scale
        dxf.height *= y_scale
        dxf.rotation = new_rotation

        if dxf.hasattr('thickness'):  # can be negative
            dxf.thickness = ocs.transform_length((0, 0, dxf.thickness),
                                                 reflection=dxf.thickness)
        dxf.extrusion = ocs.new_extrusion
        return self
示例#4
0
文件: polyline.py 项目: hh-wu/ezdxf
    def transform(self, m: Matrix44) -> 'Polyline':
        """ Transform POLYLINE entity by transformation matrix `m` inplace.

        .. versionadded:: 0.13

        """
        def _ocs_locations(elevation):
            for vertex in self.vertices:
                location = vertex.dxf.location
                if elevation is not None:
                    # Older DXF version may not have written the z-axis, which is now 0 by default in ezdxf,
                    # so replace existing z-axis by elevation value
                    location = location.replace(z=elevation)
                yield location

        if self.is_2d_polyline:
            dxf = self.dxf
            ocs = OCSTransform(self.dxf.extrusion, m)
            # Newer DXF versions write 2d polylines always as LWPOLYLINE entities.
            # No need for optimizations.
            if not ocs.scale_uniform:
                raise NonUniformScalingError(
                    '2D POLYLINE with arcs does not support non uniform scaling'
                )
                # Parent function has to catch this Exception and explode this 2D POLYLINE into LINE and ELLIPSE entities.

            if dxf.hasattr('elevation'):
                z_axis = dxf.elevation.z
            else:
                z_axis = None

            # transform old OCS locations into new OCS locations by transformation matrix m
            vertices = [
                ocs.transform_vertex(vertex)
                for vertex in _ocs_locations(z_axis)
            ]

            # set new elevation, all vertices of a 2D polyline must have the same z-axis
            if vertices:
                dxf.elevation = vertices[0].replace(x=0, y=0)

            # set new vertex locations
            for vertex, location in zip(self.vertices, vertices):
                vertex.dxf.location = location

            if dxf.hasattr('thickness'):
                dxf.thickness = ocs.transform_length((0, 0, dxf.thickness))

            dxf.extrusion = ocs.new_extrusion
        else:
            for vertex in self.vertices:
                vertex.transform(m)
        return self
示例#5
0
文件: arc.py 项目: kloppen/ezdxf
    def transform(self, m: Matrix44) -> 'Arc':
        """ Transform ARC entity by transformation matrix `m` inplace.

        Raises ``NonUniformScalingError()`` for non uniform scaling.

        .. versionadded:: 0.13

        """
        ocs = OCSTransform(self.dxf.extrusion, m)
        super().transform(m)
        self.dxf.start_angle = ocs.transform_deg_angle(self.dxf.start_angle)
        self.dxf.end_angle = ocs.transform_deg_angle(self.dxf.end_angle)
        return self
示例#6
0
 def transform(self, ocs: OCSTransform, elevation: float) -> None:
     self.control_points = list(
         ocs.transform_2d_vertex(v, elevation) for v in self.control_points
     )
     self.fit_points = list(
         ocs.transform_2d_vertex(v, elevation) for v in self.fit_points
     )
     if self.start_tangent is not None:
         t = Vec3(self.start_tangent).replace(z=elevation)
         self.start_tangent = ocs.transform_direction(t).vec2
     if self.end_tangent is not None:
         t = Vec3(self.end_tangent).replace(z=elevation)
         self.end_tangent = ocs.transform_direction(t).vec2
示例#7
0
 def transform(self, m: Matrix44) -> "Solid":
     """Transform the SOLID/TRACE entity by transformation matrix `m` inplace."""
     # SOLID and TRACE are OCS entities.
     dxf = self.dxf
     ocs = OCSTransform(self.dxf.extrusion, m)
     for name in VERTEXNAMES:
         if dxf.hasattr(name):
             dxf.set(name, ocs.transform_vertex(dxf.get(name)))
     if dxf.hasattr("thickness"):
         dxf.thickness = ocs.transform_thickness(dxf.thickness)
     dxf.extrusion = ocs.new_extrusion
     self.post_transform(m)
     return self
示例#8
0
    def transform(self, m: Matrix44) -> 'Arc':
        """ Transform ARC entity by transformation matrix `m` inplace.

        Raises ``NonUniformScalingError()`` for non uniform scaling.

        """
        ocs = OCSTransform(self.dxf.extrusion, m)
        super().transform(m)
        s = self.dxf.start_angle
        e = self.dxf.end_angle
        if not math.isclose(arc_angle_span_deg(s, e), 360.0):
            self.dxf.start_angle = ocs.transform_deg_angle(s)
            self.dxf.end_angle = ocs.transform_deg_angle(e)
        return self
示例#9
0
    def transform(self, m: "Matrix44") -> "DXFPolygon":
        """Transform entity by transformation matrix `m` inplace."""
        dxf = self.dxf
        ocs = OCSTransform(dxf.extrusion, m)

        elevation = Vec3(dxf.elevation).z
        self.paths.transform(ocs, elevation=elevation)
        dxf.elevation = ocs.transform_vertex(Vec3(0, 0, elevation)).replace(
            x=0, y=0
        )
        dxf.extrusion = ocs.new_extrusion
        # todo scale pattern
        self.post_transform(m)
        return self
示例#10
0
 def transform(self, m: Matrix44) -> 'Solid':
     """ Transform the SOLID/TRACE entity by transformation matrix `m` inplace.
     """
     # SOLID/TRACE is 2d entity, placed by an OCS in 3d space
     dxf = self.dxf
     ocs = OCSTransform(self.dxf.extrusion, m)
     for name in VERTEXNAMES:
         if dxf.hasattr(name):
             dxf.set(name, ocs.transform_vertex(dxf.get(name)))
     if dxf.hasattr('thickness'):
         dxf.thickness = ocs.transform_length((0, 0, dxf.thickness),
                                              reflection=dxf.thickness)
     dxf.extrusion = ocs.new_extrusion
     return self
示例#11
0
    def transform(self, m: Matrix44) -> 'Polyline':
        """ Transform the POLYLINE entity by transformation matrix `m` inplace.
        """

        def _ocs_locations(elevation):
            for vertex in self.vertices:
                location = vertex.dxf.location
                if elevation is not None:
                    # Older DXF version may not have written the z-axis, which
                    # is now 0 by default in ezdxf, so replace existing z-axis
                    # by elevation value.
                    location = location.replace(z=elevation)
                yield location

        if self.is_2d_polyline:
            dxf = self.dxf
            ocs = OCSTransform(self.dxf.extrusion, m)
            if not ocs.scale_uniform and self.has_arc:
                # Parent function has to catch this Exception and explode this
                # 2D POLYLINE into LINE and ELLIPSE entities.
                raise NonUniformScalingError(
                    '2D POLYLINE with arcs does not support non uniform scaling'
                )

            if dxf.hasattr('elevation'):
                z_axis = dxf.elevation.z
            else:
                z_axis = None

            vertices = [
                ocs.transform_vertex(vertex) for vertex in
                _ocs_locations(z_axis)
            ]

            # All vertices of a 2D polyline have the same z-axis:
            if vertices:
                dxf.elevation = vertices[0].replace(x=0, y=0)

            for vertex, location in zip(self.vertices, vertices):
                vertex.dxf.location = location

            if dxf.hasattr('thickness'):
                dxf.thickness = ocs.transform_length((0, 0, dxf.thickness))

            dxf.extrusion = ocs.new_extrusion
        else:
            for vertex in self.vertices:
                vertex.transform(m)
        return self
示例#12
0
    def transform(self, m: 'Matrix44') -> 'Dimension':
        """ Transform the DIMENSION entity by transformation matrix `m` inplace.

        Raises ``NonUniformScalingError()`` for non uniform scaling.

        """
        def transform_if_exist(name: str, func):
            if dxf.hasattr(name):
                dxf.set(name, func(dxf.get(name)))

        dxf = self.dxf
        ocs = OCSTransform(self.dxf.extrusion, m)

        for vertex_name in ('text_midpoint', 'defpoint5', 'insert'):
            transform_if_exist(vertex_name, ocs.transform_vertex)

        for angle_name in ('text_rotation', 'horizontal_direction', 'angle'):
            transform_if_exist(angle_name, ocs.transform_deg_angle)

        for vertex_name in ('defpoint', 'defpoint2', 'defpoint3', 'defpoint4'):
            transform_if_exist(vertex_name, m.transform)

        dxf.extrusion = ocs.new_extrusion
        self._transform_block_content(m)
        return self
示例#13
0
    def transform(self, m: "Matrix44") -> "Dimension":
        """Transform the DIMENSION entity by transformation matrix `m` inplace.

        Raises ``NonUniformScalingError()`` for non uniform scaling.

        """
        def transform_if_exist(name: str, func):
            if dxf.hasattr(name):
                dxf.set(name, func(dxf.get(name)))

        dxf = self.dxf
        ocs = OCSTransform(self.dxf.extrusion, m)

        for vertex_name in ("text_midpoint", "defpoint5", "insert"):
            transform_if_exist(vertex_name, ocs.transform_vertex)

        for angle_name in ("text_rotation", "horizontal_direction", "angle"):
            transform_if_exist(angle_name, ocs.transform_deg_angle)

        for vertex_name in ("defpoint", "defpoint2", "defpoint3", "defpoint4"):
            transform_if_exist(vertex_name, m.transform)

        dxf.extrusion = ocs.new_extrusion

        # ignore cloned geometry, this would transform the block content
        # multiple times:
        if not dxf.hasattr("insert"):
            self._transform_block_content(m)
        self.post_transform(m)
        return self
示例#14
0
文件: arc.py 项目: Rahulghuge94/ezdxf
    def transform(self, m: Matrix44) -> "Arc":
        """Transform ARC entity by transformation matrix `m` inplace.

        Raises ``NonUniformScalingError()`` for non uniform scaling.

        """
        ocs = OCSTransform(self.dxf.extrusion, m)
        super()._transform(ocs)
        s: float = self.dxf.start_angle
        e: float = self.dxf.end_angle
        if not math.isclose(arc_angle_span_deg(s, e), 360.0):
            (
                self.dxf.start_angle,
                self.dxf.end_angle,
            ) = ocs.transform_ccw_arc_angles_deg(s, e)
        self.post_transform(m)
        return self
    def test_reflections(self, s, e, rotation, sx, sy):
        m = Matrix44.chain(
            Matrix44.scale(sx, sy, 1),
            Matrix44.z_rotate(rotation),
        )
        expected_start = m.transform(Vec3.from_deg_angle(s))
        expected_end = m.transform(Vec3.from_deg_angle(e))
        expected_angle_span = arc_angle_span_deg(s, e)

        ocs = OCSTransform(Z_AXIS, m)
        new_s, new_e = ocs.transform_ccw_arc_angles_deg(s, e)
        wcs_start = ocs.new_ocs.to_wcs(Vec3.from_deg_angle(new_s))
        wcs_end = ocs.new_ocs.to_wcs(Vec3.from_deg_angle(new_e))
        assert arc_angle_span_deg(new_s, new_e) == pytest.approx(
            expected_angle_span
        )
        assert wcs_start.isclose(expected_start)
        assert wcs_end.isclose(expected_end)
示例#16
0
    def transform(self, m: Matrix44) -> "Circle":
        """Transform the CIRCLE entity by transformation matrix `m` inplace.

        Raises ``NonUniformScalingError()`` for non uniform scaling.

        """
        circle = self._transform(OCSTransform(self.dxf.extrusion, m))
        self.post_transform(m)
        return circle
示例#17
0
    def _transform(self, ocs: OCSTransform) -> "Circle":
        dxf = self.dxf
        if ocs.scale_uniform:
            dxf.extrusion = ocs.new_extrusion
            dxf.center = ocs.transform_vertex(dxf.center)
            # old_ocs has a uniform scaled xy-plane, direction of radius-vector
            # in the xy-plane is not important, choose x-axis for no reason:
            dxf.radius = ocs.transform_length((dxf.radius, 0, 0))
            if dxf.hasattr("thickness"):
                # thickness vector points in the z-direction of the old_ocs,
                # thickness can be negative
                dxf.thickness = ocs.transform_thickness(dxf.thickness)
        else:
            # Caller has to catch this Exception and convert this
            # CIRCLE/ARC into an ELLIPSE.
            raise NonUniformScalingError(
                "CIRCLE/ARC does not support non uniform scaling")

        return self
示例#18
0
    def transform(self, ocs: OCSTransform, elevation: float) -> None:
        self.center = ocs.transform_2d_vertex(self.center, elevation)
        self.radius = ocs.transform_length(Vec3(self.radius, 0, 0))
        if not math.isclose(
            arc_angle_span_deg(self.start_angle, self.end_angle), 360.0
        ):  # open arc
            # The transformation of the ccw flag is not necessary for the current
            # implementation of OCS transformations. The arc angles have always
            # a counter clockwise orientation around the extrusion vector and
            # this orientation is preserved even for mirroring, which flips the
            # extrusion vector to (0, 0, -1) for entities in the xy-plane.

            self.start_angle = ocs.transform_deg_angle(self.start_angle)
            self.end_angle = ocs.transform_deg_angle(self.end_angle)
        else:  # full circle
            # Transform only start point to preserve the connection point to
            # adjacent edges:
            self.start_angle = ocs.transform_deg_angle(self.start_angle)
            # ArcEdge is represented in counter-clockwise orientation:
            self.end_angle = self.start_angle + 360.0
示例#19
0
    def transform(self, m: 'Matrix44') -> 'Insert':
        """ Transform INSERT entity by transformation matrix `m` inplace.

        Unlike the transformation matrix `m`, the INSERT entity can not
        represent a non orthogonal target coordinate system, for this case an
        :class:`InsertTransformationError` will be raised.

        .. versionadded:: 0.13

        """

        dxf = self.dxf
        m1 = self.matrix44()

        # Transform scaled source axis into target coordinate system
        ux, uy, uz = m.transform_directions((m1.ux, m1.uy, m1.uz))

        # Get new scaling factors, all are positive:
        # z-axis is the real new z-axis, no reflection required
        # x-axis is the real new x-axis, no reflection required
        # y-axis - reflection is detected below
        z_scale = uz.magnitude
        x_scale = ux.magnitude
        y_scale = uy.magnitude

        # check for orthogonal x-, y- and z-axis
        ux = ux.normalize()
        uy = uy.normalize()
        uz = uz.normalize()
        if not (math.isclose(ux.dot(uz), 0.0, abs_tol=1e-9)
                and math.isclose(ux.dot(uy), 0.0, abs_tol=1e-9)
                and math.isclose(uz.dot(uy), 0.0, abs_tol=1e-9)):
            raise InsertTransformationError(NON_ORTHO_MSG)

        # expected y-axis for an orthogonal right handed coordinate system
        expected_uy = uz.cross(ux)
        if expected_uy.isclose(-uy, abs_tol=1e-9):
            # transformed y-axis points into opposite direction of the expected
            # y-axis:
            y_scale = -y_scale

        ocs = OCSTransform.from_ocs(OCS(dxf.extrusion), OCS(uz), m)
        dxf.insert = ocs.transform_vertex(dxf.insert)
        dxf.rotation = ocs.transform_deg_angle(dxf.rotation)

        dxf.extrusion = uz
        dxf.xscale = x_scale
        dxf.yscale = y_scale
        dxf.zscale = z_scale

        for attrib in self.attribs:
            attrib.transform(m)
        return self
示例#20
0
    def transform(self, m: "Matrix44") -> "Insert":
        """Transform INSERT entity by transformation matrix `m` inplace.

        Unlike the transformation matrix `m`, the INSERT entity can not
        represent a non orthogonal target coordinate system, for this case an
        :class:`InsertTransformationError` will be raised.

        """

        dxf = self.dxf
        ocs = self.ocs()

        # Transform source OCS axis into the target coordinate system:
        ux, uy, uz = m.transform_directions((ocs.ux, ocs.uy, ocs.uz))

        # Calculate new axis scaling factors:
        x_scale = ux.magnitude * dxf.xscale
        y_scale = uy.magnitude * dxf.yscale
        z_scale = uz.magnitude * dxf.zscale

        ux = ux.normalize()
        uy = uy.normalize()
        uz = uz.normalize()
        # check for orthogonal x-, y- and z-axis
        if (abs(ux.dot(uz)) > ABS_TOL or abs(ux.dot(uy)) > ABS_TOL
                or abs(uz.dot(uy)) > ABS_TOL):
            raise InsertTransformationError(NON_ORTHO_MSG)

        # expected y-axis for an orthogonal right handed coordinate system:
        expected_uy = uz.cross(ux)
        if not expected_uy.isclose(uy, abs_tol=ABS_TOL):
            # new y-axis points into opposite direction:
            y_scale = -y_scale

        ocs_transform = OCSTransform.from_ocs(OCS(dxf.extrusion), OCS(uz), m)
        dxf.insert = ocs_transform.transform_vertex(dxf.insert)
        dxf.rotation = ocs_transform.transform_deg_angle(dxf.rotation)

        dxf.extrusion = uz
        dxf.xscale = x_scale
        dxf.yscale = y_scale
        dxf.zscale = z_scale

        for attrib in self.attribs:
            attrib.transform(m)
        self.post_transform(m)
        return self
示例#21
0
    def transform(self, m: "Matrix44") -> "LWPolyline":
        """Transform the LWPOLYLINE entity by transformation matrix `m` inplace.

        A non uniform scaling is not supported if the entity contains circular
        arc segments (bulges).

        Args:
            m: transformation :class:`~ezdxf.math.Matrix44`

        Raises:
            NonUniformScalingError: for non uniform scaling of entity containing
                circular arc segments (bulges)

        """
        dxf = self.dxf
        ocs = OCSTransform(self.dxf.extrusion, m)
        if not ocs.scale_uniform and self.has_arc:
            raise NonUniformScalingError(
                "LWPOLYLINE containing arcs (bulges) does not support non uniform scaling"
            )
            # The caller function has to catch this exception and explode the
            # LWPOLYLINE into LINE and ELLIPSE entities.
        vertices = list(
            ocs.transform_vertex(v) for v in self.vertices_in_ocs())
        lwpoints = []
        for v, p in zip(vertices, self.lwpoints):
            _, _, start_width, end_width, bulge = p
            # assume a uniform scaling!
            start_width = ocs.transform_width(start_width)
            end_width = ocs.transform_width(end_width)
            lwpoints.append((v.x, v.y, start_width, end_width, bulge))
        self.set_points(lwpoints)

        # All new OCS vertices must have the same z-axis, which is the elevation
        # of the polyline:
        if vertices:
            dxf.elevation = vertices[0].z

        if dxf.hasattr("const_width"):  # assume a uniform scaling!
            dxf.const_width = ocs.transform_width(dxf.const_width)

        if dxf.hasattr("thickness"):
            dxf.thickness = ocs.transform_thickness(dxf.thickness)
        dxf.extrusion = ocs.new_extrusion
        self.post_transform(m)
        return self
示例#22
0
    def transform(self, m: 'Matrix44') -> 'Dimension':
        """ Transform the ARC_DIMENSION entity by transformation matrix `m` inplace.

        Raises ``NonUniformScalingError()`` for non uniform scaling.

        """
        def transform_if_exist(name: str, func):
            if dxf.hasattr(name):
                dxf.set(name, func(dxf.get(name)))

        dxf = self.dxf
        ocs = OCSTransform(dxf.extrusion, m)
        super().transform(m)

        for angle_name in ('start_angle', 'end_angle'):
            transform_if_exist(angle_name, ocs.transform_deg_angle)

        for vertex_name in ('leader_point1', 'leader_point2'):
            transform_if_exist(vertex_name, m.transform)

        return self
示例#23
0
    def transform(self, m: "Matrix44") -> "Shape":
        """Transform the SHAPE entity by transformation matrix `m` inplace."""
        dxf = self.dxf
        dxf.insert = m.transform(dxf.insert)  # DXF Reference: WCS?
        ocs = OCSTransform(self.dxf.extrusion, m)

        dxf.rotation = ocs.transform_deg_angle(dxf.rotation)
        dxf.size = ocs.transform_length((0, dxf.size, 0))
        dxf.x_scale = ocs.transform_length((dxf.x_scale, 0, 0),
                                           reflection=dxf.x_scale)
        if dxf.hasattr("thickness"):
            dxf.thickness = ocs.transform_thickness(dxf.thickness)

        dxf.extrusion = ocs.new_extrusion
        self.post_transform(m)
        return self
示例#24
0
文件: shape.py 项目: luoyu-123/ezdxf
    def transform(self, m: 'Matrix44') -> 'Shape':
        """ Transform SHAPE entity by transformation matrix `m` inplace.

        .. versionadded:: 0.13

        """
        dxf = self.dxf
        dxf.insert = m.transform(dxf.insert)  # DXF Reference: WCS?
        ocs = OCSTransform(self.dxf.extrusion, m)

        dxf.rotation = ocs.transform_deg_angle(dxf.rotation)
        dxf.size = ocs.transform_length((0, dxf.size, 0))
        dxf.x_scale = ocs.transform_length((dxf.x_scale, 0, 0),
                                           reflection=dxf.x_scale)
        if dxf.hasattr('thickness'):
            dxf.thickness = ocs.transform_length((0, 0, dxf.thickness),
                                                 reflection=dxf.thickness)

        dxf.extrusion = ocs.new_extrusion
        return self
 def test_reflection_in_y_axis(self, thickness):
     ocs = OCSTransform(Z_AXIS, Matrix44.scale(1, -2, 1))
     assert ocs.new_ocs.uz.isclose(-Z_AXIS)  # flip extrusion vector
     assert ocs.transform_thickness(thickness) == pytest.approx(
         -thickness
     ), "thickness value should be inverted"
 def test_reflection_in_x_y_and_z_axis(self, thickness):
     ocs = OCSTransform(Z_AXIS, Matrix44.scale(-2, -2, -2))
     assert ocs.new_ocs.uz.isclose(Z_AXIS)  # unchanged extrusion vector
     assert ocs.transform_thickness(thickness) == pytest.approx(
         -2 * thickness
     ), "thickness value should be -2x"
def test_transform_angle_without_ocs():
    ocs = OCSTransform(Vec3(0, 0, 1), Matrix44.z_rotate(math.pi / 2))
    assert math.isclose(ocs.transform_angle(0), math.pi / 2)
 def test_no_transformation(self, width):
     ocs = OCSTransform(Z_AXIS, Matrix44())
     assert ocs.transform_width(width) == pytest.approx(abs(width))
 def test_uniform_scaling_for_all_axis(self, width):
     ocs = OCSTransform(Z_AXIS, Matrix44.scale(-2, -2, -2))
     assert ocs.transform_width(width) == pytest.approx(
         2 * abs(width)
     ), "width should always be >= 0"
 def test_x_scaling(self, width):
     ocs = OCSTransform(Z_AXIS, Matrix44.scale(2, 1, 1))
     assert ocs.transform_width(width) == pytest.approx(
         2 * abs(width)
     ), "current implementation scales by biggest x- or y-axis factor"