Hi Andras.
Please try this one:
import math
import numpy as np
transformNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLTransformNode')
# transformNode = getNode('Transform')
def rotationToVtk(R):
'''
Concert a rotation matrix into the Mayavi/Vtk rotation paramaters (pitch, roll, yaw)
'''
def euler_from_matrix(matrix):
"""Return Euler angles (syxz) from rotation matrix for specified axis sequence.
:Author:
`Christoph Gohlke <http://www.lfd.uci.edu/~gohlke/>`_
full library with coplete set of euler triplets (combinations of s/r x-y-z) at
http://www.lfd.uci.edu/~gohlke/code/transformations.py.html
Note that many Euler angle triplets can describe one matrix.
"""
# epsilon for testing whether a number is close to zero
_EPS = np.finfo(float).eps * 5.0
#
# axis sequences for Euler angles
_NEXT_AXIS = [0, 0, 1, 2]
#
#inner axis: code of axis (‘x’:0, ‘y’:1, ‘z’:2) of rightmost matrix.
#parity : even (0) if inner axis ‘x’ is followed by ‘y’, ‘y’ is followed by ‘z’, or ‘z’ is followed by ‘x’. Otherwise odd (1).
#repetition : first and last axis are same (1) or different (0).
#frame : rotations are applied to static (0) or rotating (1) frame.
#
firstaxis, parity, repetition, frame = (2, 0, 0, 1) # ''
#
i = firstaxis
j = _NEXT_AXIS[i+parity]
k = _NEXT_AXIS[i-parity+1]
#
M = np.array(matrix, dtype='float', copy=False)[:3, :3]
if repetition:
sy = np.sqrt(M[i, j]*M[i, j] + M[i, k]*M[i, k])
if sy > _EPS:
ax = np.arctan2( M[i, j], M[i, k])
ay = np.arctan2( sy, M[i, i])
az = np.arctan2( M[j, i], -M[k, i])
else:
ax = np.arctan2(-M[j, k], M[j, j])
ay = np.arctan2( sy, M[i, i])
az = 0.0
else:
cy = np.sqrt(M[i, i]*M[i, i] + M[j, i]*M[j, i])
if cy > _EPS:
ax = np.arctan2( M[k, j], M[k, k])
ay = np.arctan2(-M[k, i], cy)
az = np.arctan2( M[j, i], M[i, i])
else:
ax = np.arctan2(-M[j, k], M[j, j])
ay = np.arctan2(-M[k, i], cy)
az = 0.0
#
if parity:
ax, ay, az = -ax, -ay, -az
if frame:
ax, az = az, ax
return ax, ay, az
#
r_yxz = np.array(euler_from_matrix(R))*180/math.pi
r_xyz = r_yxz[[1, 0, 2]]
return r_xyz
transformObserver = 0
# Create widget
widget = qt.QFrame()
layout = qt.QFormLayout()
widget.setLayout(layout)
axisSliderWidgets = []
for i in range(3):
axisSliderWidget = ctk.ctkSliderWidget()
axisSliderWidget.singleStep = 1.0
axisSliderWidget.minimum = -180
axisSliderWidget.maximum = 180
axisSliderWidget.value = 0
axisSliderWidget.tracking = False
layout.addRow(f"Axis {i+1}: ", axisSliderWidget)
axisSliderWidgets.append(axisSliderWidget)
def updateTransformFromWidget(value):
global transformObserver
transform = vtk.vtkTransform()
transform.RotateY(axisSliderWidgets[1].value)
axisOfRotation = [1,0,0,0]
transform.GetMatrix().MultiplyPoint(axisOfRotation,axisOfRotation)
transform.RotateWXYZ(axisSliderWidgets[0].value,axisOfRotation[0],axisOfRotation[1],axisOfRotation[2])
#transform.RotateX(axisSliderWidgets[0].value)
axisOfRotation = [0,0,1,0]
transform.GetMatrix().MultiplyPoint(axisOfRotation,axisOfRotation)
transform.RotateWXYZ(axisSliderWidgets[2].value,axisOfRotation[0],axisOfRotation[1],axisOfRotation[2])
#transform.RotateZ(axisSliderWidgets[1].value)
transformNode.RemoveObserver(transformObserver)
transformNode.SetMatrixTransformToParent(transform.GetMatrix())
transformObserver = transformNode.AddObserver(slicer.vtkMRMLTransformableNode.TransformModifiedEvent, updateWidgetFromTransform)
def updateWidgetFromTransform(caller, event):
transformMatrix = transformNode.GetMatrixTransformToParent()
transformMatrix_np = arrayFromVTKMatrix(transformMatrix)
angles_xyz = rotationToVtk(transformMatrix_np)
for i in range(3):
axisSliderWidget = axisSliderWidgets[i]
wasBlocked = axisSliderWidget.blockSignals(True)
axisSliderWidget.value = angles_xyz[i]
axisSliderWidget.blockSignals(wasBlocked)
def resetTransform():
transformNode.SetMatrixTransformToParent(vtk.vtkMatrix4x4())
for i in range(3):
axisSliderWidgets[i].connect("valueChanged(double)", updateTransformFromWidget)
resetButton = qt.QPushButton("Reset")
layout.addWidget(resetButton)
resetButton.connect("clicked()", resetTransform)
widget.show()
transformObserver = transformNode.AddObserver(slicer.vtkMRMLTransformableNode.TransformModifiedEvent, updateWidgetFromTransform)
# transformNode.RemoveObserver(transformObserver)
I think it works