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
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
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 _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
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_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_no_transformation(self, thickness): ocs = OCSTransform(Z_AXIS, Matrix44()) assert ocs.transform_thickness(thickness) == pytest.approx(thickness)
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