Reformat module Values not resetting

Hi,
Why the values in reformat module do not reset by default? Even if I close the scene (Ctlr W) still the what ever the rotation values remain there in the next scene.

Also when I change the rotation value in red slice, and click the yellow slice the values i change in the red slice is what i get from default.

Is this expected?

I guess after closing the scene the sliders should reset at least.

The sliders are used only for relative rotations. See more details here: Is the rotation of the 3D Slicer's Transform module Euler or Quaternion? - #2 by lassoan

We should reset them to 0 more often to make sure users don’t mistake it for Euler angles or something similar.

Euler angles (and similar representations that rely on successive rotations along multiple axes) are not well suited for representing arbitrary orientations, as it suffers from gimbal lock and there are multiple parametrizations for the same orientation. Having multiple parametrizations for the same orientation means that conversion between Euler<->matrix representations is not invertible, which means that in general it is not possible to create 3 independent sliders for specifying orientation using Euler angles.

Just to illustrate the problem, you can copy-paste the code snippet below to get orientation sliders that operate in Euler angles (YXZ order). Note how the angles are modified after you release the slider if any of the angles >=90 deg (numerical instabilities may start to appear a few degrees before 90deg).

transformNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLTransformNode')
# transformNode = getNode('Transform')

### 

def updateTransformFromWidget(value):
    transform = vtk.vtkTransform()
    transform.RotateZ(axisSliderWidgets[2].value)
    transform.RotateX(axisSliderWidgets[0].value)
    transform.RotateY(axisSliderWidgets[1].value)
    transformNode.SetMatrixTransformToParent(transform.GetMatrix())

def updateWidgetFromTransform(caller, event):
    transformMatrix = transformNode.GetMatrixTransformToParent()
    transform = vtk.vtkTransform()
    transform.SetMatrix(transformMatrix)
    orientation = transform.GetOrientation()
    for i in range(3):
        axisSliderWidget = axisSliderWidgets[i]
        wasBlocked = axisSliderWidget.blockSignals(True)
        axisSliderWidget.value = orientation[i]
        axisSliderWidget.blockSignals(wasBlocked)

def resetTransform():
    transformNode.SetMatrixTransformToParent(vtk.vtkMatrix4x4())

# 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)
    axisSliderWidget.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)
1 Like