def test_translate_should_match_vtk_transformation(rotate_amounts, translate_amounts, grid): trans = vtk.vtkTransform() trans.RotateWXYZ(*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.array_from_vtkmatrix(trans.GetMatrix())) # treat INF as NAN (necessary for allclose) grid_a.points[np.isinf(grid_a.points)] = np.nan assert np.allclose(grid_a.points, grid_b.points, equal_nan=True) assert np.allclose(grid_a.points, grid_c.points, equal_nan=True) # test non homogeneous transform trans_rotate_only = vtk.vtkTransform() trans_rotate_only.RotateWXYZ(*rotate_amounts) trans_rotate_only.Update() grid_d = grid.copy() grid_d.transform(trans_rotate_only) from pyvista.utilities.transformations import apply_transformation_to_points trans_arr = pyvista.array_from_vtkmatrix( trans_rotate_only.GetMatrix())[:3, :3] trans_pts = apply_transformation_to_points(trans_arr, grid.points) assert np.allclose(grid_d.points, trans_pts, equal_nan=True)
def transform(self, trans: Union[vtk.vtkMatrix4x4, vtk.vtkTransform, np.ndarray]): """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.array_from_vtkmatrix(trans) elif isinstance(trans, vtk.vtkTransform): t = pyvista.array_from_vtkmatrix(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") transformations.apply_transformation_to_points(t, self.points, inplace=True)
def test_transforms(): position = (1, 2, 3) focal_point = (4, 5, 6) light = pyvista.Light(position=position) light.focal_point = focal_point trans_array = np.arange(4 * 4).reshape(4, 4) trans_matrix = pyvista.vtkmatrix_from_array(trans_array) assert light.transform_matrix is None light.transform_matrix = trans_array assert isinstance(light.transform_matrix, vtk.vtkMatrix4x4) array = pyvista.array_from_vtkmatrix(light.transform_matrix) assert np.array_equal(array, trans_array) light.transform_matrix = trans_matrix matrix = light.transform_matrix assert all( matrix.GetElement(i, j) == trans_matrix.GetElement(i, j) for i in range(4) for j in range(4)) linear_trans = trans_array[:-1, :-1] shift = trans_array[:-1, -1] assert light.position == position assert np.allclose(light.world_position, linear_trans @ position + shift) assert light.focal_point == focal_point assert np.allclose(light.world_focal_point, linear_trans @ focal_point + shift) with pytest.raises(ValueError): light.transform_matrix = 'invalid'
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.array_from_vtkmatrix(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.array_from_vtkmatrix(trans) elif isinstance(trans, vtk.vtkTransform): t = pyvista.array_from_vtkmatrix(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_vtkmatrix_to_from_array(): rng = np.random.default_rng() array3x3 = rng.integers(0, 10, size=(3, 3)) matrix = pyvista.vtkmatrix_from_array(array3x3) assert isinstance(matrix, vtk.vtkMatrix3x3) for i in range(3): for j in range(3): assert matrix.GetElement(i, j) == array3x3[i, j] array = pyvista.array_from_vtkmatrix(matrix) assert isinstance(array, np.ndarray) assert array.shape == (3, 3) for i in range(3): for j in range(3): assert array[i, j] == matrix.GetElement(i, j) array4x4 = rng.integers(0, 10, size=(4, 4)) matrix = pyvista.vtkmatrix_from_array(array4x4) assert isinstance(matrix, vtk.vtkMatrix4x4) for i in range(4): for j in range(4): assert matrix.GetElement(i, j) == array4x4[i, j] array = pyvista.array_from_vtkmatrix(matrix) assert isinstance(array, np.ndarray) assert array.shape == (4, 4) for i in range(4): for j in range(4): assert array[i, j] == matrix.GetElement(i, j) # invalid cases with pytest.raises(ValueError): matrix = pyvista.vtkmatrix_from_array(np.arange(3 * 4).reshape(3, 4)) with pytest.raises(TypeError): invalid = vtk.vtkTransform() array = pyvista.array_from_vtkmatrix(invalid)
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.array_from_vtkmatrix(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_from_vtk(): vtk_light = vtk.vtkLight() # set the vtk light for _, value, vtkname in configuration: vtk_setter = getattr(vtk_light, vtkname) if isinstance(value, np.ndarray): # we can't pass the array to vtkLight directly value = pyvista.vtkmatrix_from_array(value) vtk_setter(value) light = pyvista.Light.from_vtk(vtk_light) for pvname, value, _ in configuration: if isinstance(value, np.ndarray): trans_arr = pyvista.array_from_vtkmatrix(getattr(light, pvname)) assert np.array_equal(trans_arr, value) else: assert getattr(light, pvname) == value # invalid case with pytest.raises(TypeError): pyvista.Light.from_vtk('invalid') with pytest.raises(TypeError): pyvista.Light('invalid')