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
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
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
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') -> '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 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
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
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
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 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
def test_transform_length_without_ocs(): ocs = OCSTransform(Z_AXIS, Matrix44.scale(2, 3, 4)) assert math.isclose(ocs.transform_length((2, 0, 0)), 2 * 2) assert math.isclose(ocs.transform_length((0, 2, 0)), 2 * 3) assert math.isclose(ocs.transform_length((0, 0, 2)), 2 * 4)