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
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