Example #1
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
Example #2
0
    def transform(self, m: 'Matrix44') -> 'LWPolyline':
        """ Transform the LWPOLYLINE entity by transformation matrix `m` inplace.
        """
        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
Example #3
0
    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
Example #4
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
Example #5
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
Example #6
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
Example #7
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
Example #8
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
Example #9
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
Example #10
0
    def transform(self, m: Matrix44) -> "Polyline":
        """Transform the POLYLINE entity by transformation matrix `m` inplace.

        A non uniform scaling is not supported if a 2D POLYLINE contains
        circular arc segments (bulges).

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

        Raises:
            NonUniformScalingError: for non uniform scaling of 2D POLYLINE
                containing circular arc segments (bulges)

        """
        def _ocs_locations(elevation):
            for vertex in self.vertices:
                location = vertex.dxf.location
                if elevation is not None:
                    # Older DXF versions may not have written the z-axis, so
                    # replace existing z-axis by the 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:
                raise NonUniformScalingError(
                    "2D POLYLINE containing arcs (bulges) does not support non uniform scaling"
                )
                # The caller function has to catch this exception and explode the
                # 2D POLYLINE into LINE and ELLIPSE entities.
            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 must have the same z-axis, which is
            # the elevation of the polyline:
            if vertices:
                dxf.elevation = vertices[0].replace(x=0, y=0)

            for vertex, location in zip(self.vertices, vertices):
                vdxf = vertex.dxf
                vdxf.location = location
                if vdxf.hasattr("start_width"):
                    vdxf.start_width = ocs.transform_width(vdxf.start_width)
                if vdxf.hasattr("end_width"):
                    vdxf.end_width = ocs.transform_width(vdxf.end_width)

            if dxf.hasattr("default_start_width"):
                dxf.default_start_width = ocs.transform_width(
                    dxf.default_start_width)
            if dxf.hasattr("default_end_width"):
                dxf.default_end_width = ocs.transform_width(
                    dxf.default_end_width)
            if dxf.hasattr("thickness"):
                dxf.thickness = ocs.transform_thickness(dxf.thickness)

            dxf.extrusion = ocs.new_extrusion
        else:
            for vertex in self.vertices:
                vertex.transform(m)
        self.post_transform(m)
        return self