def transform(self, trans): """ Compute a transformation in place using a 4x4 transform. Parameters ---------- trans : vtk.vtkMatrix4x4, vtk.vtkTransform, or np.ndarray Accepts a vtk transformation object or a 4x4 transformation matrix. """ if isinstance(trans, vtk.vtkMatrix4x4): t = pyvista.trans_from_matrix(trans) elif isinstance(trans, vtk.vtkTransform): t = pyvista.trans_from_matrix(trans.GetMatrix()) elif isinstance(trans, np.ndarray): if trans.shape[0] != 4 or trans.shape[1] != 4: raise Exception('Transformation array must be 4x4') t = trans else: raise TypeError('Input transform must be either:\n' + '\tvtk.vtkMatrix4x4\n' + '\tvtk.vtkTransform\n' + '\t4x4 np.ndarray\n') x = (self.points * t[0, :3]).sum(1) + t[0, -1] y = (self.points * t[1, :3]).sum(1) + t[1, -1] z = (self.points * t[2, :3]).sum(1) + t[2, -1] # overwrite points self.points[:, 0] = x self.points[:, 1] = y self.points[:, 2] = z
def __init__(self, cam_id, camera_pos): self.cam_id = cam_id p = pv.Plotter() p.add_mesh(pv.Sphere()) p.camera_position = camera_pos # Now grab the matrix vmtx = p.camera.GetModelViewTransformMatrix() mtx = pv.trans_from_matrix(vmtx) self.camera_matrix = mtx[:-1, :-1]
def mvp(self): """ https://github.com/pyvista/pyvista-support/issues/85 TODO: try to project a 3D position onto the 2D screen plane so can place text using the 2d only add_text """ vmtx = self.pl.camera.GetModelViewTransformMatrix() mtx = pv.trans_from_matrix(mtx) return mtx
def cs_4x4(self, cs_cord, as_vtk_matrix=False): """ return a 4x4 transformation array for a given coordinate system """ # assemble 4 x 4 matrix csys = self.geometry['coord systems'][cs_cord] trans = np.hstack( (csys['transformation matrix'], csys['origin'].reshape(-1, 1))) matrix = trans_to_matrix(trans) if as_vtk_matrix: return matrix else: return pv.trans_from_matrix(matrix)
def test_tensor_rotation_z(): transform = vtk.vtkTransform() transform.RotateZ(20) transform.Update() rot_matrix = transform.GetMatrix() # rot_matrix.Invert() # <-- this should not be necessary trans = pv.trans_from_matrix(rot_matrix) s_test = stress.copy().reshape(1, -1) _binary_reader.tensor_arbitrary(s_test, trans) assert np.allclose(s_test, stress_rot_z)
def transform(self, trans): """Compute a transformation in place using a 4x4 transform. Parameters ---------- trans : vtk.vtkMatrix4x4, vtk.vtkTransform, or np.ndarray Accepts a vtk transformation object or a 4x4 transformation matrix. """ if isinstance(trans, vtk.vtkMatrix4x4): t = pyvista.trans_from_matrix(trans) elif isinstance(trans, vtk.vtkTransform): t = pyvista.trans_from_matrix(trans.GetMatrix()) elif isinstance(trans, np.ndarray): if trans.ndim != 2: raise ValueError('Transformation array must be 4x4') elif trans.shape[0] != 4 or trans.shape[1] != 4: raise ValueError('Transformation array must be 4x4') t = trans else: raise TypeError('Input transform must be either:\n' '\tvtk.vtkMatrix4x4\n' '\tvtk.vtkTransform\n' '\t4x4 np.ndarray\n') if t[3, 3] == 0: raise ValueError( "Transform element (3,3), the inverse scale term, is zero") # Normalize the transformation to account for the scale t /= t[3, 3] x = (self.points * t[0, :3]).sum(1) + t[0, -1] y = (self.points * t[1, :3]).sum(1) + t[1, -1] z = (self.points * t[2, :3]).sum(1) + t[2, -1] # overwrite points self.points[:, 0] = x self.points[:, 1] = y self.points[:, 2] = z
def test_translate_should_match_vtk_transformation(rotate_amounts, translate_amounts, grid): trans = vtk.vtkTransform() trans.RotateWXYZ(0, *rotate_amounts) trans.Translate(translate_amounts) trans.Update() grid_a = grid.copy() grid_b = grid.copy() grid_c = grid.copy() grid_a.transform(trans) grid_b.transform(trans.GetMatrix()) grid_c.transform(pyvista.trans_from_matrix(trans.GetMatrix())) assert np.allclose(grid_a.points, grid_b.points, equal_nan=True) assert np.allclose(grid_a.points, grid_c.points, equal_nan=True)
def test_transform(): trans = vtk.vtkTransform() trans.RotateX(30) trans.RotateY(30) trans.RotateZ(30) trans.Translate(1, 1, 2) trans.Update() grid_a = grid.copy() grid_b = grid.copy() grid_c = grid.copy() grid_a.transform(trans) grid_b.transform(trans.GetMatrix()) grid_c.transform(pyvista.trans_from_matrix(trans.GetMatrix())) assert np.allclose(grid_a.points, grid_b.points) assert np.allclose(grid_a.points, grid_c.points)
def expand_cyclic_static(self, result, tensor=False): """ expands cyclic static results """ cs_cord = self.resultheader['csCord'] if cs_cord > 1: matrix = self.cs_4x4(cs_cord, as_vtk_matrix=True) i_matrix = self.cs_4x4(cs_cord, as_vtk_matrix=True) i_matrix.Invert() else: matrix = vtk.vtkMatrix4x4() i_matrix = vtk.vtkMatrix4x4() shp = (self.n_sector, result.shape[0], result.shape[1]) full_result = np.empty(shp) full_result[:] = result rang = 360.0 / self.n_sector for i in range(self.n_sector): # transform to standard position, rotate about Z axis, # transform back transform = vtk.vtkTransform() transform.RotateZ(rang * i) transform.Update() rot_matrix = transform.GetMatrix() if cs_cord > 1: temp_matrix = vtk.vtkMatrix4x4() rot_matrix.Multiply4x4(i_matrix, rot_matrix, temp_matrix) rot_matrix.Multiply4x4(temp_matrix, matrix, rot_matrix) trans = pv.trans_from_matrix(rot_matrix) if tensor: _binary_reader.tensor_arbitrary(full_result[i], trans) else: _binary_reader.affline_transform_double(full_result[i], trans) return full_result
def expand_cyclic_modal_stress(self, result, result_r, hindex, phase, as_complex, full_rotor, scale=True): """ Combines repeated results from ANSYS """ if as_complex or full_rotor: result_combined = result + result_r * 1j if phase: result_combined *= 1 * np.cos(phase) - 1j * np.sin(phase) else: # convert to real result_combined = result * np.cos(phase) - result_r * np.sin(phase) # just return single sector if not full_rotor: return result_combined # Generate full rotor solution result_expanded = np.empty( (self.n_sector, result.shape[0], result.shape[1]), np.complex128) result_expanded[:] = result_combined # scale # if scale: # if hindex == 0 or hindex == self.n_sector/2: # result_expanded /= self.n_sector**0.5 # else: # result_expanded /= (self.n_sector/2)**0.5 f_arr = np.zeros(self.n_sector) f_arr[hindex] = 1 jang = np.fft.ifft(f_arr)[:self.n_sector] * self.n_sector cjang = jang * (np.cos(phase) - np.sin(phase) * 1j) full_result = np.real(result_expanded * cjang.reshape(-1, 1, 1)) # # rotate cyclic result inplace # angles = np.linspace(0, 2*np.pi, self.n_sector + 1)[:-1] + phase # for i, angle in enumerate(angles): # isnan = _binary_reader.tensor_rotate_z(result_expanded[i], angle) # result_expanded[i, isnan] = np.nan cs_cord = self.resultheader['csCord'] if cs_cord > 1: matrix = self.cs_4x4(cs_cord, as_vtk_matrix=True) i_matrix = self.cs_4x4(cs_cord, as_vtk_matrix=True) i_matrix.Invert() else: matrix = vtk.vtkMatrix4x4() i_matrix = vtk.vtkMatrix4x4() shp = (self.n_sector, result.shape[0], result.shape[1]) full_result = np.empty(shp) full_result[:] = result rang = 360.0 / self.n_sector for i in range(self.n_sector): # transform to standard position, rotate about Z axis, # transform back transform = vtk.vtkTransform() transform.RotateZ(rang * i) transform.Update() rot_matrix = transform.GetMatrix() if cs_cord > 1: temp_matrix = vtk.vtkMatrix4x4() rot_matrix.Multiply4x4(i_matrix, rot_matrix, temp_matrix) rot_matrix.Multiply4x4(temp_matrix, matrix, rot_matrix) trans = pv.trans_from_matrix(rot_matrix) _binary_reader.tensor_arbitrary(full_result[i], trans) return full_result