def _calcTransforms(self): """Computes transformation matrices to convert between coordinates Computes transformation matrices to convert between local and global coordinates. """ # r is the forward transformation matrix from world to local coordinates # ok i will be really honest, i cannot understand exactly why this works # something bout the order of the translation and the rotation. # the double-inverting is strange, and I don't understand it. forward = Matrix() inverse = Matrix() forwardT = gp_Trsf() inverseT = gp_Trsf() global_coord_system = gp_Ax3() local_coord_system = gp_Ax3( gp_Pnt(*self.origin.toTuple()), gp_Dir(*self.zDir.toTuple()), gp_Dir(*self.xDir.toTuple()), ) forwardT.SetTransformation(global_coord_system, local_coord_system) forward.wrapped = gp_GTrsf(forwardT) inverseT.SetTransformation(local_coord_system, global_coord_system) inverse.wrapped = gp_GTrsf(inverseT) self.lcs = local_coord_system self.rG = inverse self.fG = forward
def __init__(self, matrix=None): if matrix is None: self.wrapped = gp_GTrsf() elif isinstance(matrix, gp_GTrsf): self.wrapped = matrix elif isinstance(matrix, gp_Trsf): self.wrapped = gp_GTrsf(matrix) elif isinstance(matrix, (list, tuple)): # Validate matrix size & 4x4 last row value valid_sizes = all( (isinstance(row, (list, tuple)) and (len(row) == 4)) for row in matrix) and len(matrix) in (3, 4) if not valid_sizes: raise TypeError( "Matrix constructor requires 2d list of 4x3 or 4x4, but got: {!r}" .format(matrix)) elif (len(matrix) == 4) and (tuple(matrix[3]) != (0, 0, 0, 1)): raise ValueError( "Expected the last row to be [0,0,0,1], but got: {!r}". format(matrix[3])) # Assign values to matrix self.wrapped = gp_GTrsf() [ self.wrapped.SetValue(i + 1, j + 1, e) for i, row in enumerate(matrix[:3]) for j, e in enumerate(row) ] else: raise TypeError( "Invalid param to matrix constructor: {}".format(matrix))
def rotated(self, rotate=(0, 0, 0)): """Returns a copy of this plane, rotated about the specified axes Since the z axis is always normal the plane, rotating around Z will always produce a plane that is parallel to this one. The origin of the workplane is unaffected by the rotation. Rotations are done in order x, y, z. If you need a different order, manually chain together multiple rotate() commands. :param rotate: Vector [xDegrees, yDegrees, zDegrees] :return: a copy of this plane rotated as requested. """ # NB: this is not a geometric Vector rotate = Vector(rotate) # Convert to radians. rotate = rotate.multiply(math.pi / 180.0) # Compute rotation matrix. T1 = gp_Trsf() T1.SetRotation( gp_Ax1(gp_Pnt(*(0, 0, 0)), gp_Dir(*self.xDir.toTuple())), rotate.x) T2 = gp_Trsf() T2.SetRotation( gp_Ax1(gp_Pnt(*(0, 0, 0)), gp_Dir(*self.yDir.toTuple())), rotate.y) T3 = gp_Trsf() T3.SetRotation( gp_Ax1(gp_Pnt(*(0, 0, 0)), gp_Dir(*self.zDir.toTuple())), rotate.z) T = Matrix(gp_GTrsf(T1 * T2 * T3)) # Compute the new plane. newXdir = self.xDir.transform(T) newZdir = self.zDir.transform(T) return Plane(self.origin, newXdir, newZdir)
def _rotate(self, direction: gp_Ax1, angle: float): new = gp_Trsf() new.SetRotation(direction, angle) self.wrapped = self.wrapped * gp_GTrsf(new)