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_reflection(): # reflect points of a square across a diagonal points = np.array([ [1, 1, 0], [-1, 1, 0], [-1, -1, 0], [1, -1, 0], ]) normal = [1, 1, 0] # default origin expected = points[[2, 1, 0, 3], :] trans = transformations.reflection(normal) actual = transformations.apply_transformation_to_points(trans, points) assert np.allclose(actual, expected) # non-default origin p0 = [1, 1, 0] expected += 2 * np.array(p0) trans = transformations.reflection(normal, point=p0) actual = transformations.apply_transformation_to_points(trans, points) assert np.allclose(actual, expected) # invalid cases with pytest.raises(ValueError): transformations.reflection([1, 0, 0, 0]) with pytest.raises(ValueError): transformations.reflection(normal, point=[1, 0, 0, 0]) with pytest.raises(ValueError): transformations.reflection([0, 0, 0])
def test_apply_transformation_to_points(): mesh = ex.load_airplane() points = mesh.points points_orig = points.copy() # identity 3 x 3 tf = np.eye(3) points_new = transformations.apply_transformation_to_points(tf, points, inplace=False) assert points_new == pytest.approx(points) # identity 4 x 4 tf = np.eye(4) points_new = transformations.apply_transformation_to_points(tf, points, inplace=False) assert points_new == pytest.approx(points) # scale in-place tf = np.eye(4) * 2 tf[3, 3] = 1 r = transformations.apply_transformation_to_points(tf, points, inplace=True) assert r is None assert mesh.points == pytest.approx(2 * points_orig)
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 test_axis_angle_rotation(): # rotate cube corners around body diagonal points = np.array([ [1, 0, 0], [0, 1, 0], [0, 0, 1], ]) axis = [1, 1, 1] # no-op case angle = 360 trans = transformations.axis_angle_rotation(axis, angle) actual = transformations.apply_transformation_to_points(trans, points) assert np.array_equal(actual, points) # default origin angle = np.radians(120) expected = points[[1, 2, 0], :] trans = transformations.axis_angle_rotation(axis, angle, deg=False) actual = transformations.apply_transformation_to_points(trans, points) assert np.allclose(actual, expected) # non-default origin p0 = [-2, -3, 4] points += p0 expected += p0 trans = transformations.axis_angle_rotation(axis, angle, point=p0, deg=False) actual = transformations.apply_transformation_to_points(trans, points) assert np.allclose(actual, expected) # invalid cases with pytest.raises(ValueError): transformations.axis_angle_rotation([1, 0, 0, 0], angle) with pytest.raises(ValueError): transformations.axis_angle_rotation(axis, angle, point=[1, 0, 0, 0]) with pytest.raises(ValueError): transformations.axis_angle_rotation([0, 0, 0], angle)