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
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"
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_no_transformation(self, width): ocs = OCSTransform(Z_AXIS, Matrix44()) assert ocs.transform_width(width) == pytest.approx(abs(width))
def test_non_uniform_xy_scaling_for_y(self, width): ocs = OCSTransform(Z_AXIS, Matrix44.scale(-2, -3, 1)) assert ocs.transform_width(width) == pytest.approx( 3 * abs(width) ), "current implementation scales by biggest x- or y-axis factor"
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