diff --git a/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidget.cpp b/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidget.cpp index 15c6b52c82..4985f541f4 100644 --- a/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidget.cpp +++ b/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidget.cpp @@ -1,272 +1,276 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkInteractiveTransformationWidget.h" // mitk includes #include "mitkRenderingManager.h" #include "mitkNavigationData.h" // vtk includes #include "vtkMatrix4x4.h" #include "vtkLinearTransform.h" const std::string QmitkInteractiveTransformationWidget::VIEW_ID = "org.mitk.views.interactivetransformationwidget"; QmitkInteractiveTransformationWidget::QmitkInteractiveTransformationWidget(QWidget* parent, Qt::WindowFlags f) - : QWidget(parent, f), m_Controls(nullptr), m_Geometry(nullptr), m_ResetGeometry(nullptr) + : QWidget(parent, f), m_Controls(nullptr), m_Geometry(nullptr) { CreateQtPartControl(this); CreateConnections(); + + m_ResetGeometry = mitk::Geometry3D::New(); } QmitkInteractiveTransformationWidget::~QmitkInteractiveTransformationWidget() { } void QmitkInteractiveTransformationWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkInteractiveTransformationWidgetControls; m_Controls->setupUi(parent); } } void QmitkInteractiveTransformationWidget::CreateConnections() { if (m_Controls) { // translations - connect(m_Controls->m_XTransSpinBox, static_cast(&QSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnXTranslationValueChanged); + connect(m_Controls->m_XTransSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnXTranslationValueChanged); connect(m_Controls->m_XTransSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnXTranslationValueChanged); - connect(m_Controls->m_YTransSpinBox, static_cast(&QSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnYTranslationValueChanged); + connect(m_Controls->m_YTransSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnYTranslationValueChanged); connect(m_Controls->m_YTransSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnYTranslationValueChanged); - connect(m_Controls->m_ZTransSpinBox, static_cast(&QSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnZTranslationValueChanged); + connect(m_Controls->m_ZTransSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnZTranslationValueChanged); connect(m_Controls->m_ZTransSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnZTranslationValueChanged); // rotations - connect(m_Controls->m_XRotSpinBox, static_cast(&QSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnXRotationValueChanged); + connect(m_Controls->m_XRotSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnXRotationValueChanged); connect(m_Controls->m_XRotSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnXRotationValueChanged); - connect(m_Controls->m_YRotSpinBox, static_cast(&QSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnYRotationValueChanged); + connect(m_Controls->m_YRotSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnYRotationValueChanged); connect(m_Controls->m_YRotSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnYRotationValueChanged); - connect(m_Controls->m_ZRotSpinBox, static_cast(&QSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnZRotationValueChanged); + connect(m_Controls->m_ZRotSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnZRotationValueChanged); connect(m_Controls->m_ZRotSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnZRotationValueChanged); connect((QObject*)(m_Controls->m_ResetPB), SIGNAL(clicked()), this, SLOT(OnResetGeometryToIdentity())); connect((QObject*)(m_Controls->m_RevertChanges), SIGNAL(clicked()), this, SLOT(OnRevertChanges())); connect((QObject*)(m_Controls->m_UseManipulatedToolTipPB), SIGNAL(clicked()), this, SLOT(OnApplyManipulatedToolTip())); connect((QObject*)(m_Controls->m_Cancel), SIGNAL(clicked()), this, SLOT(OnCancel())); } } void QmitkInteractiveTransformationWidget::SetGeometryPointer(mitk::BaseGeometry::Pointer geometry) { m_Geometry = geometry; - m_ResetGeometry = geometry->Clone(); //Remember the original values to be able to reset and abort everything + //For ResetGeometry, use the set-fuction via vtk matrix, 'cause this garantees a deep copy and not just sharing a pointer. + m_ResetGeometry->SetIndexToWorldTransformByVtkMatrix(geometry->GetVtkMatrix()); //Remember the original values to be able to reset and abort everything } void QmitkInteractiveTransformationWidget::SetGeometryDefaultValues(const mitk::AffineTransform3D::Pointer _defaultValues) { m_Geometry->SetIndexToWorldTransform(_defaultValues); - m_ResetGeometry->SetIndexToWorldTransform(_defaultValues); //Remember the original values to be able to reset and abort everything + //For ResetGeometry, use the set-fuction via vtk matrix, 'cause this garantees a deep copy and not just sharing a pointer. + m_ResetGeometry->SetIndexToWorldTransformByVtkMatrix(m_Geometry->GetVtkMatrix()); //Remember the original values to be able to reset and abort everything SetValuesToGUI(_defaultValues); } void QmitkInteractiveTransformationWidget::SetValuesToGUI(const mitk::AffineTransform3D::Pointer _defaultValues) { //Set toolTip values in gui m_Controls->m_XTransSlider->setValue(_defaultValues->GetOffset()[0]); m_Controls->m_YTransSlider->setValue(_defaultValues->GetOffset()[1]); m_Controls->m_ZTransSlider->setValue(_defaultValues->GetOffset()[2]); //first: some conversion mitk::NavigationData::Pointer transformConversionHelper = mitk::NavigationData::New(_defaultValues); double eulerAlphaDegrees = transformConversionHelper->GetOrientation().rotation_euler_angles()[0] / vnl_math::pi * 180; double eulerBetaDegrees = transformConversionHelper->GetOrientation().rotation_euler_angles()[1] / vnl_math::pi * 180; double eulerGammaDegrees = transformConversionHelper->GetOrientation().rotation_euler_angles()[2] / vnl_math::pi * 180; m_Controls->m_XRotSpinBox->setValue(eulerAlphaDegrees); m_Controls->m_YRotSpinBox->setValue(eulerBetaDegrees); m_Controls->m_ZRotSpinBox->setValue(eulerGammaDegrees); //Update view mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } ///////////////////////////////////////////////////////////////////////////////////////////// // Section to allow interactive positioning of the moving surface ///////////////////////////////////////////////////////////////////////////////////////////// -void QmitkInteractiveTransformationWidget::OnXTranslationValueChanged(int v) +void QmitkInteractiveTransformationWidget::OnXTranslationValueChanged(double v) { this->blockSignals(true);//block signals to avoid loop between slider and spinbox. Unblock at the end of the function! //Set values to member variable mitk::Point3D translationParams = m_Geometry->GetOrigin(); translationParams[0] = v; m_Geometry->SetOrigin(translationParams); //Update Gui (change may come either from spin box or from slider) m_Controls->m_XTransSlider->setValue(v); m_Controls->m_XTransSpinBox->setValue(v); //Update view mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->blockSignals(false);//unblock signals. See above, don't remove this line. Unblock at the end of the function! } -void QmitkInteractiveTransformationWidget::OnYTranslationValueChanged(int v) +void QmitkInteractiveTransformationWidget::OnYTranslationValueChanged(double v) { this->blockSignals(true);//block signals to avoid loop between slider and spinbox. Unblock at the end of the function! //Set values to member variable mitk::Point3D translationParams = m_Geometry->GetOrigin(); translationParams[1] = v; m_Geometry->SetOrigin(translationParams); //Update Gui (change may come either from spin box or from slider) m_Controls->m_YTransSlider->setValue(v); m_Controls->m_YTransSpinBox->setValue(v); //Update view mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->blockSignals(false);//unblock signals. See above, don't remove this line. Unblock at the end of the function! } -void QmitkInteractiveTransformationWidget::OnZTranslationValueChanged(int v) +void QmitkInteractiveTransformationWidget::OnZTranslationValueChanged(double v) { this->blockSignals(true);//block signals to avoid loop between slider and spinbox. Unblock at the end of the function! //Set values to member variable mitk::Point3D translationParams = m_Geometry->GetOrigin(); translationParams[2] = v; m_Geometry->SetOrigin(translationParams); //Update Gui (change may come either from spin box or from slider) m_Controls->m_ZTransSlider->setValue(v); m_Controls->m_ZTransSpinBox->setValue(v); //Update view mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->blockSignals(false);//unblock signals. See above, don't remove this line. Unblock at the end of the function! } -void QmitkInteractiveTransformationWidget::OnXRotationValueChanged(int v) +void QmitkInteractiveTransformationWidget::OnXRotationValueChanged(double v) { this->blockSignals(true);//block signals to avoid loop between slider and spinbox. Unblock at the end of the function! mitk::Vector3D rotationParams; rotationParams[0] = v; rotationParams[1] = m_Controls->m_YRotSlider->value(); rotationParams[2] = m_Controls->m_ZRotSlider->value(); //Update Gui (change may come either from spin box or from slider) m_Controls->m_XRotSlider->setValue(v); m_Controls->m_XRotSpinBox->setValue(v); this->Rotate(rotationParams); this->blockSignals(false);//unblock signals. See above, don't remove this line. Unblock at the end of the function! } -void QmitkInteractiveTransformationWidget::OnYRotationValueChanged(int v) +void QmitkInteractiveTransformationWidget::OnYRotationValueChanged(double v) { this->blockSignals(true);//block signals to avoid loop between slider and spinbox. Unblock at the end of the function! mitk::Vector3D rotationParams; rotationParams[0] = m_Controls->m_XRotSlider->value(); rotationParams[1] = v; rotationParams[2] = m_Controls->m_ZRotSlider->value(); //Update Gui (change may come either from spin box or from slider) m_Controls->m_YRotSlider->setValue(v); m_Controls->m_YRotSpinBox->setValue(v); this->Rotate(rotationParams); this->blockSignals(false);//unblock signals. See above, don't remove this line. Unblock at the end of the function! } -void QmitkInteractiveTransformationWidget::OnZRotationValueChanged(int v) +void QmitkInteractiveTransformationWidget::OnZRotationValueChanged(double v) { this->blockSignals(true);//block signals to avoid loop between slider and spinbox. Unblock at the end of the function! mitk::Vector3D rotationParams; rotationParams[0] = m_Controls->m_XRotSlider->value(); rotationParams[1] = m_Controls->m_YRotSlider->value(); rotationParams[2] = v; //Update Gui (change may come either from spin box or from slider) m_Controls->m_ZRotSlider->setValue(v); m_Controls->m_ZRotSpinBox->setValue(v); this->Rotate(rotationParams); this->blockSignals(false);//unblock signals. See above, don't remove this line. Unblock at the end of the function! } void QmitkInteractiveTransformationWidget::Rotate(mitk::Vector3D rotateVector) { //0: from degrees to radians double radianX = rotateVector[0] * vnl_math::pi / 180; double radianY = rotateVector[1] * vnl_math::pi / 180; double radianZ = rotateVector[2] * vnl_math::pi / 180; //1: from euler angles to quaternion mitk::Quaternion rotation(radianX, radianY, radianZ); //2: Conversion to navigation data / transform mitk::NavigationData::Pointer rotationTransform = mitk::NavigationData::New(m_Geometry->GetIndexToWorldTransform()); rotationTransform->SetOrientation(rotation); m_Geometry->SetIndexToWorldTransform(rotationTransform->GetAffineTransform3D()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkInteractiveTransformationWidget::OnResetGeometryToIdentity() { // reset the input to its initial state. m_Geometry->SetIdentity(); //Update Sliders this->SetValuesToGUI(m_Geometry->GetIndexToWorldTransform()); //Refresh view mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkInteractiveTransformationWidget::OnRevertChanges() { // reset the input to its initial state. - m_Geometry->SetIndexToWorldTransform(m_ResetGeometry->GetIndexToWorldTransform()); + m_Geometry->SetIndexToWorldTransformByVtkMatrix(m_ResetGeometry->GetVtkMatrix()); //Update Sliders this->SetValuesToGUI(m_Geometry->GetIndexToWorldTransform()); //Refresh view mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkInteractiveTransformationWidget::OnApplyManipulatedToolTip() { mitk::AffineTransform3D::Pointer toolTip = m_Geometry->GetIndexToWorldTransform(); emit EditToolTipFinished(toolTip); } void QmitkInteractiveTransformationWidget::OnCancel() { emit EditToolTipFinished(nullptr); } \ No newline at end of file diff --git a/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidget.h b/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidget.h index c8bc544a0b..25101a6646 100644 --- a/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidget.h +++ b/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidget.h @@ -1,90 +1,90 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkInteractiveTransformationWidget_H #define QmitkInteractiveTransformationWidget_H //QT headers #include //Mitk headers #include "MitkIGTUIExports.h" #include "mitkVector.h" #include "mitkGeometry3D.h" //ui header #include "ui_QmitkInteractiveTransformationWidgetControls.h" /** Documentation: * \brief An object of this class offers an UI to create a widget to access the advance tool creation options. * * * \ingroup IGTUI */ class MITKIGTUI_EXPORT QmitkInteractiveTransformationWidget : public QWidget { Q_OBJECT public: static const std::string VIEW_ID; QmitkInteractiveTransformationWidget(QWidget* parent = nullptr, Qt::WindowFlags f = nullptr); ~QmitkInteractiveTransformationWidget(); /** Sets the geometry which will be modified by this widget. Default values may be * provided by the second variable. These values will be applied to the geometry * in the beginning and the UI will also hold these values. */ void SetGeometryPointer(mitk::BaseGeometry::Pointer geometry); void SetGeometryDefaultValues(const mitk::AffineTransform3D::Pointer _defaultValues); protected slots: - void OnZTranslationValueChanged( int v ); - void OnYTranslationValueChanged( int v ); - void OnXTranslationValueChanged( int v ); - void OnZRotationValueChanged( int v ); - void OnYRotationValueChanged( int v ); - void OnXRotationValueChanged( int v ); + void OnZTranslationValueChanged( double v ); + void OnYTranslationValueChanged(double v); + void OnXTranslationValueChanged(double v); + void OnZRotationValueChanged(double v); + void OnYRotationValueChanged(double v); + void OnXRotationValueChanged(double v); void OnResetGeometryToIdentity(); void OnRevertChanges(); void OnApplyManipulatedToolTip(); void OnCancel(); signals: void EditToolTipFinished(mitk::AffineTransform3D::Pointer toolTip); protected: virtual void CreateConnections(); virtual void CreateQtPartControl(QWidget *parent); /*! \brief Method performs the rotation. \params rotateVector New rotation to be combined with geometry. */ void Rotate(mitk::Vector3D rotateVector); // Member variables Ui::QmitkInteractiveTransformationWidgetControls* m_Controls; mitk::BaseGeometry::Pointer m_Geometry; ///< \brief The geometry that is manipulated mitk::BaseGeometry::Pointer m_ResetGeometry; ///< \brief Lifeline to reset to the original geometry private: void SetValuesToGUI(const mitk::AffineTransform3D::Pointer _defaultValues); }; #endif // QmitkInteractiveTransformationWidget_H diff --git a/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidgetControls.ui b/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidgetControls.ui index add15a23be..6daf485458 100644 --- a/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidgetControls.ui +++ b/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidgetControls.ui @@ -1,451 +1,463 @@ QmitkInteractiveTransformationWidgetControls 0 0 435 381 Form Interactive Translation 50 false x-Direction (Frontal): false 0 0 ArrowCursor -500 500 1 Qt::Horizontal false false QSlider::TicksAbove 100 - + + + 1 + - -500 + -500.000000000000000 - 500 + 500.000000000000000 50 false y-Direction (Sagittal): false 0 0 -500 500 Qt::Horizontal false QSlider::TicksAbove 100 - + + + 1 + - -500 + -500.000000000000000 - 500 - - - 0 + 500.000000000000000 50 false z-Direction (Transversal): false 0 0 -500 500 0 Qt::Horizontal false QSlider::TicksAbove 100 - + + + 1 + - -500 + -500.000000000000000 - 500 - - - 1 + 500.000000000000000 Interactive Rotation 50 false x-Axis (Frontal): false 0 0 ArrowCursor -180 180 Qt::Horizontal QSlider::TicksAbove 45 - + + + 1 + - -180 + -180.000000000000000 - 180 + 180.000000000000000 50 false y-Axis (Sagittal): false 0 0 -180 180 Qt::Horizontal QSlider::TicksAbove 45 - + + + 1 + - -180 + -180.000000000000000 - 180 + 180.000000000000000 50 false z-Axis (Transversal): false 0 0 -180 180 Qt::Horizontal QSlider::TicksAbove 45 - + + + 1 + - -180 + -180.000000000000000 - 180 + 180.000000000000000 Use Manipulated ToolTip Reset To Identity Revert Changes Cancel