]> Creatis software - clitk.git/blobdiff - vv/vvToolRigidReg.cxx
Debug RTStruct conversion with empty struc
[clitk.git] / vv / vvToolRigidReg.cxx
index 2473e655b0f84e078868120dbbf93c98087e5608..5a11c7f8e367dad022cf08bc8b54cf06a92e92ed 100644 (file)
@@ -3,7 +3,7 @@
 
   Authors belong to:
   - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
 
   This software is distributed WITHOUT ANY WARRANTY; without even
 
   - BSD        See included LICENSE.txt file
   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-======================================================================-====*/
+===========================================================================**/
+
+// vv
 #include "vvToolRigidReg.h"
-#include <QComboBox>
-#include <QCursor>
-#include <QApplication>
+#include "vvSlicer.h"
+#include <vvBlendImageActor.h>
+
+// vtk
 #include <vtkImageData.h>
 #include <vtkSmartPointer.h>
+#include <vtkInformation.h>
 #include <vtkTransform.h>
-#include "vvImage.h"
-#include "vvSlicer.h"
-#include <QString>
+#include <vtkImageActor.h>
+#include <vtkImageMapper3D.h>
+#include <vtkOpenGLImageSliceMapper.h>
+
+// itk
+#include <itkEuler3DTransform.h>
+
+// clitk
+#include "clitkTransformUtilities.h"
+#include "clitkMatrix.h"
+
+// qt
 #include <QMessageBox>
-#include <vvMainWindow.h>
+#include <QFileDialog>
+#include <QTextStream>
+
+
 //------------------------------------------------------------------------------
 // Create the tool and automagically (I like this word) insert it in
 // the main window menu.
 ADD_TOOL(vvToolRigidReg);
 //------------------------------------------------------------------------------
 
-
 //------------------------------------------------------------------------------
 vvToolRigidReg::vvToolRigidReg(vvMainWindowBase * parent, Qt::WindowFlags f):
     vvToolWidgetBase(parent, f),
@@ -42,236 +57,428 @@ vvToolRigidReg::vvToolRigidReg(vvMainWindowBase * parent, Qt::WindowFlags f):
 {
   // GUI Initialization
   Ui_vvToolRigidReg::setupUi(mToolWidget);
-
+  
   // Set how many inputs are needed for this tool
-  AddInputSelector("Select the Reference Image");
-  AddInputSelector("Select the Target Image");
+  AddInputSelector("Select moving image");
+
+  QFont font = transformationLabel->font();
+  font.setStyleHint(QFont::TypeWriter);
+  transformationLabel->setFont(font);
+
+  mInitialMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
+
+  // Set slider ranges, assume degrees, will not be changed for radians
+  std::vector<QSlider *> transSliders, rotSliders;
+  std::vector<QDoubleSpinBox *> transSBs, rotSBs;
+  GetSlidersAndSpinBoxes(transSliders, rotSliders, transSBs, rotSBs);
+  for(int i=0; i<3; i++) {
+    transSliders[i]->setRange(-2000,2000);
+    rotSliders[i]->setRange(-360,360);
+    transSBs[i]->setRange(-2000,2000);
+    transSBs[i]->setDecimals(3);
+    rotSBs[i]->setRange(-360,360);
+    rotSBs[i]->setDecimals(3);
+  }
 }
 //------------------------------------------------------------------------------
 
-
 //------------------------------------------------------------------------------
 vvToolRigidReg::~vvToolRigidReg()
 {
 }
 //------------------------------------------------------------------------------
 
-
-//------------------------------------------------------------------------------
-bool vvToolRigidReg::close()
-{
-  return vvToolWidgetBase::close();
-}
-//------------------------------------------------------------------------------
-
-
 //------------------------------------------------------------------------------
-void vvToolRigidReg::reject()
+void vvToolRigidReg::Initialize()
 {
-  return vvToolWidgetBase::reject();
+  SetToolName("Register");
+  SetToolMenuName("Register manually");
+  SetToolIconFilename(":/common/icons/register.png");
+  SetToolTip("Register manually.");
+  SetToolExperimental(false);
 }
 //------------------------------------------------------------------------------
 
-
 //------------------------------------------------------------------------------
-void vvToolRigidReg::InputIsSelected(std::vector<vvSlicerManager *> & l)
+void vvToolRigidReg::InputIsSelected(vvSlicerManager *input)
 {
-  //inputs
-  mInput1 = l[0];
-  mInput2 = l[1];
-  mTwoInputs = true;
-
-
-  SetOverlay();
-  for (int j = 1; j <= 4; j++) {
-    mCurrentSlicerManager->GetSlicer(j-1)->SetActorVisibility("overlay",0,true);
-  }
-  mCurrentSlicerManager->Render();
-
-  std::vector<int> imagesize;
-  imagesize=mCurrentSlicerManager->GetImage()->GetSize();
-  std::vector<double> imageorigin;
-  imageorigin=mCurrentSlicerManager->GetImage()->GetOrigin();
-  QString xcord,ycord,zcord;
+  mInput = input;
+  HideInputSelector();
+  QTabWidget * tab = dynamic_cast<vvMainWindow*>(mMainWindow)->GetTab();
+  move(tab->mapToGlobal(tab->pos()));
+  resize(tab->width(), 0);
 
   //default image rotation center is the center of the image
-  xcord=xcord.setNum(imageorigin[0]+imagesize[0]*mCurrentSlicerManager->GetImage()->GetSpacing()[0]/2, 'g', 3);
-  ycord=ycord.setNum(imageorigin[1]+imagesize[1]*mCurrentSlicerManager->GetImage()->GetSpacing()[1]/2, 'g', 3);
-  zcord=zcord.setNum(imageorigin[2]+imagesize[2]*mCurrentSlicerManager->GetImage()->GetSpacing()[2]/2, 'g', 3);
-
+  QString xcord,ycord,zcord;
+  std::vector<double> imageorigin;
+  imageorigin=mInput->GetImage()->GetOrigin();
+  std::vector<int> imageSize = mInput->GetImage()->GetSize();
+  std::vector<double> imageSpacing = mInput->GetImage()->GetSpacing();
+  xcord=xcord.setNum(imageorigin[0]+(imageSize[0]-1)*imageSpacing[0]*0.5, 'g', 3);
+  ycord=ycord.setNum(imageorigin[1]+(imageSize[1]-1)*imageSpacing[1]*0.5, 'g', 3);
+  zcord=zcord.setNum(imageorigin[2]+(imageSize[2]-1)*imageSpacing[2]*0.5, 'g', 3);
   Xval->setText(xcord);
   Yval->setText(ycord);
   Zval->setText(zcord);
 
-  xtrans_slider->setMaximum(2*mCurrentSlicerManager->GetImage()->GetSize()[0]);
-  xtrans_slider->setMinimum(-2*mCurrentSlicerManager->GetImage()->GetSize()[0]);
-  ytrans_slider->setMaximum(2*mCurrentSlicerManager->GetImage()->GetSize()[1]);
-  ytrans_slider->setMinimum(-2*mCurrentSlicerManager->GetImage()->GetSize()[1]);
-  ztrans_slider->setMaximum(2*mCurrentSlicerManager->GetImage()->GetSize()[2]);
-  ztrans_slider->setMinimum(-2*mCurrentSlicerManager->GetImage()->GetSize()[2]);
-
-
-  xtrans_sb->setMaximum(2*mCurrentSlicerManager->GetImage()->GetSize()[0]);
-  xtrans_sb->setMinimum(-2*mCurrentSlicerManager->GetImage()->GetSize()[0]);
-  ytrans_sb->setMaximum(2*mCurrentSlicerManager->GetImage()->GetSize()[1]);
-  ytrans_sb->setMinimum(-2*mCurrentSlicerManager->GetImage()->GetSize()[1]);
-  ztrans_sb->setMaximum(2*mCurrentSlicerManager->GetImage()->GetSize()[2]);
-  ztrans_sb->setMinimum(-2*mCurrentSlicerManager->GetImage()->GetSize()[2]);
-
-  xrot_slider->setMaximum(360);
-  xrot_slider->setMinimum(-360);
-  yrot_slider->setMaximum(360);
-  yrot_slider->setMinimum(-360);
-  zrot_slider->setMaximum(360);
-  zrot_slider->setMinimum(-360);
-
-
-  xrot_sb->setMaximum(360);
-  xrot_sb->setMinimum(-360);
-  yrot_sb->setMaximum(360);
-  yrot_sb->setMinimum(-360);
-  zrot_sb->setMaximum(360);
-  zrot_sb->setMinimum(-360);
+  //backup original matrix
+  for(int j=0; j<4; j++)
+    for(int i=0; i<4; i++)
+      // TODO SR and BP: check on the list of transforms and not the first only
+      mInitialMatrix->SetElement(i,j, mCurrentSlicerManager->GetImage()->GetTransform()[0]->GetMatrix()->GetElement(i,j));
+  QString origTransformString(clitk::Get4x4MatrixDoubleAsString(mInitialMatrix).c_str());
+  transformationLabel->setText(origTransformString);
+  SetTransform(mInitialMatrix);
 
   //connect all sigs to slots
-  connect(Xval, SIGNAL(editingFinished()), this, SLOT(SetXvalue()));
-  connect(Yval, SIGNAL(editingFinished()), this, SLOT(SetYvalue()));
-  connect(Zval, SIGNAL(editingFinished()), this, SLOT(SetZvalue()));
-  connect(xtrans_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateXtranslider()));
-  connect(ytrans_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateYtranslider()));
-  connect(ztrans_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateZtranslider()));
-  connect(xrot_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateXrotslider()));
-  connect(yrot_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateYrotslider()));
-  connect(zrot_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateZrotslider()));
+  connect(resetbutton, SIGNAL(pressed()), this, SLOT(ResetTransform()));
+  connect(loadbutton, SIGNAL(pressed()), this, SLOT(LoadFile()));
+  connect(savebutton, SIGNAL(pressed()), this, SLOT(SaveFile()));
+
+  connect(xtrans_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
+  connect(ytrans_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
+  connect(ztrans_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
+  connect(xrot_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
+  connect(yrot_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
+  connect(zrot_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
+  connect(xtrans_sb, SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
+  connect(ytrans_sb, SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
+  connect(ztrans_sb, SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
+  connect(xrot_sb,   SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
+  connect(yrot_sb,   SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
+  connect(zrot_sb,   SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
+
+  connect(stepTransSpinBox, SIGNAL(valueChanged(double)), this, SLOT(SetTranslationStep(double)));
+  connect(stepRotSpinBox, SIGNAL(valueChanged(double)), this, SLOT(SetRotationStep(double)));
+
+  connect(checkBoxDegrees, SIGNAL(stateChanged(int)), this, SLOT(ToggleSpinBoxAnglesUnit()));
+
+  connect(Xval, SIGNAL(editingFinished()), this, SLOT(ChangeOfRotationCenter()));
+  connect(Yval, SIGNAL(editingFinished()), this, SLOT(ChangeOfRotationCenter()));
+  connect(Zval, SIGNAL(editingFinished()), this, SLOT(ChangeOfRotationCenter()));
+
+  // Init step modifiers
+  stepTransSpinBox->setValue(1.);
+  stepRotSpinBox->setValue(1.);
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
 void vvToolRigidReg::apply()
 {
-
+  vvToolWidgetBase::close();
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::SetOverlay()
+bool vvToolRigidReg::close()
 {
-  for (int i =0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
-    mCurrentSlicerManager->GetSlicer(i)->SetOverlay(mInput2->GetImage());
+  QString warning = "Are you sure you want to reset the original transform?";
+  QMessageBox msgBox(QMessageBox::Warning, tr("Reset transform"),warning, 0, this);
+  msgBox.addButton(tr("Yes"), QMessageBox::AcceptRole);
+  msgBox.addButton(tr("No"), QMessageBox::RejectRole);
+  if (msgBox.exec() == QMessageBox::AcceptRole) {
+    if (mCurrentSlicerManager)
+        SetTransform(mInitialMatrix);
+    return vvToolWidgetBase::close();
   }
+  return false;
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::SetXvalue()
+void vvToolRigidReg::reject()
 {
-  QString xstr = Xval->text();
+  return vvToolWidgetBase::reject();
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::SetYvalue()
+void vvToolRigidReg::SetTranslationStep(double v)
 {
-  QString ystr = Yval->text();
+  xtrans_sb->setSingleStep(v);
+  ytrans_sb->setSingleStep(v);
+  ztrans_sb->setSingleStep(v);
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::SetZvalue()
+void vvToolRigidReg::SetRotationStep(double v)
 {
-  QString zstr = Zval->text();
+  xrot_sb->setSingleStep(v);
+  yrot_sb->setSingleStep(v);
+  zrot_sb->setSingleStep(v);
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::SetTransform(double tX, double tY, double tZ, double aX, double aY, double aZ)
+void vvToolRigidReg::SliderChange(int newVal)
 {
-
-  vtkSmartPointer<vtkTransform> transform = mCurrentSlicerManager->GetImage()->GetTransform();
-  transform->PostMultiply();
-
-  //Rotations
-  if (aX!=0 || aY!=0 || aZ!=0) {
-    double x, y ,z;
-    x= Xval->text().toDouble();
-    y= Yval->text().toDouble();
-    z= Zval->text().toDouble();
-    transform->Translate(-x,-y,-z);
-    if (aX!=0) transform->RotateX(aX);
-    if (aY!=0) transform->RotateY(aY);
-    if (aZ!=0) transform->RotateZ(aZ);
-    transform->Translate(x,y,z);
+  std::vector<QSlider *> transSliders, rotSliders;
+  std::vector<QDoubleSpinBox *> transSBs, rotSBs;
+  GetSlidersAndSpinBoxes(transSliders, rotSliders, transSBs, rotSBs);
+  for(int i=0; i<3; i++) {
+    if(transSliders[i] == QObject::sender()) {
+      transSBs[i]->setValue(newVal);
+    }
+    if(rotSliders[i] == QObject::sender()) {
+      double rad = (checkBoxDegrees->checkState()==Qt::Unchecked)?itk::Math::pi/180.:1.;
+      rotSBs[i]->setValue(newVal*rad);
+    }
   }
+}
+//------------------------------------------------------------------------------
 
-  //Translations
-  if (tX!=0 || tY!=0 || tZ!=0)
-    transform->Translate(tX,tY,tZ);
+//------------------------------------------------------------------------------
+void vvToolRigidReg::SpinBoxChange(double newVal)
+{
+  std::vector<QSlider *> transSliders, rotSliders;
+  std::vector<QDoubleSpinBox *> transSBs, rotSBs;
+  GetSlidersAndSpinBoxes(transSliders, rotSliders, transSBs, rotSBs);
+  for(int i=0; i<3; i++) {
+    if(transSBs[i] == QObject::sender()) {
+      transSliders[i]->blockSignals(true);
+      transSliders[i]->setValue(itk::Math::Round<double,double>(newVal));
+      transSliders[i]->blockSignals(false);
+    }
+    if(rotSBs[i] == QObject::sender()) {
+      double rad = (checkBoxDegrees->checkState()==Qt::Unchecked)?180./itk::Math::pi:1.;
+      rotSliders[i]->blockSignals(true);
+      rotSliders[i]->setValue(itk::Math::Round<double,double>(newVal*rad));
+      rotSliders[i]->blockSignals(false);
+    }
+  }
 
-  transform->Update();
+  // Compute transform and set
+  // TODO SR and BP: check on the list of transforms and not the first only
+  vtkSmartPointer<vtkTransform> transform_final=mInput->GetImage()->GetTransform()[0];
+  transform_final->Identity();
+  transform_final->PostMultiply();
+
+  // Rotations
+  double x=0, y=0 ,z=0;
+  x= Xval->text().toDouble();
+  y= Yval->text().toDouble();
+  z= Zval->text().toDouble();
+  double rad = (checkBoxDegrees->checkState()==Qt::Unchecked)?180./itk::Math::pi:1.;
+  transform_final->Translate(-x,-y,-z);
+  transform_final->RotateY(yrot_sb->value()*rad);
+  transform_final->RotateX(xrot_sb->value()*rad);
+  transform_final->RotateZ(zrot_sb->value()*rad);
+  transform_final->Translate(x,y,z);
+
+  // Translation
+  transform_final->Translate(xtrans_sb->value(),
+                             ytrans_sb->value(),
+                             ztrans_sb->value());
+  transform_final->Update();
+  SetTransform(transform_final->GetMatrix());
+}
+//------------------------------------------------------------------------------
 
-  for (int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
-    mCurrentSlicerManager->GetImage()->UpdateReslice();
-    mCurrentSlicerManager->GetSlicer(i)->Render();
+//------------------------------------------------------------------------------
+void vvToolRigidReg::ToggleSpinBoxAnglesUnit()
+{
+  double rad = (checkBoxDegrees->checkState()==Qt::Unchecked)?itk::Math::pi/180.:180./itk::Math::pi;
+  std::vector<QSlider *> transSliders, rotSliders;
+  std::vector<QDoubleSpinBox *> transSBs, rotSBs;
+  GetSlidersAndSpinBoxes(transSliders, rotSliders, transSBs, rotSBs);
+  for(int i=0; i<3; i++) {
+    rotSBs[i]->blockSignals(true);
+    rotSBs[i]->setValue(rotSBs[i]->value()*rad);
+    rotSBs[i]->blockSignals(false);
   }
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::UpdateXtranslider()
+void vvToolRigidReg::SaveFile()
 {
+  //Write the Transformation Matrix
+  std::string absPath = mCurrentSlicerManager->GetFileName();
+  absPath = itksys::SystemTools::GetFilenameWithoutExtension(absPath) + std::string(".mat");
+  QString filename = QFileDialog::getSaveFileName(this, tr("Save Transformation Matrix File"),
+                                            absPath.c_str(),
+                                            tr("Text (*.mat *.txt *.doc *.rtf)"));
+
+  QFile file(filename);
+  if (file.open(QFile::WriteOnly | QFile::Truncate)) {
+    // TODO SR and BP: check on the list of transforms and not the first only
+    vtkMatrix4x4* matrix = mCurrentSlicerManager->GetImage()->GetTransform()[0]->GetMatrix();
+    QString matrixStr = clitk::Get4x4MatrixDoubleAsString(matrix,16).c_str();
+    QTextStream out(&file);
+    out << matrixStr;
+  }
+  else
+  {
+    QMessageBox::information(this,"Error","Unable to open file for writing");
+  }
+}
+//------------------------------------------------------------------------------
 
-  int diff=0;
-  diff=xtrans_slider->value()-xtrans_sb->value();
-  this->SetTransform(diff, 0, 0, 0, 0, 0);
-  xtrans_sb->setValue(xtrans_slider->value());
+//------------------------------------------------------------------------------
+void vvToolRigidReg::LoadFile()
+{
+  //Open File to read the transformation parameters
+  QString file = QFileDialog::getOpenFileName(
+                   this,
+                   "Choose the filename for the transformation matrix",
+                   vtksys::SystemTools::GetFilenamePath(mCurrentSlicerManager->GetFileName()).c_str(),
+                   "Text (*.mat *.txt *.rtf *.doc)");
+   if (file.isEmpty())
+     return;
+
+
+  itk::Matrix<double, 4, 4> itkMat = clitk::ReadMatrix3D(file.toStdString());
+  vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
+  matrix->Identity();
+  for(int j=0; j<4; j++)
+    for(int i=0; i<4; i++)
+      matrix->SetElement(j,i,itkMat[j][i]);
+  SetTransform(matrix);
+}
+//------------------------------------------------------------------------------
+  
+//------------------------------------------------------------------------------
+void vvToolRigidReg::ChangeOfRotationCenter()
+{
+  // TODO SR and BP: check on the list of transforms and not the first only
+  SetTransform(mCurrentSlicerManager->GetImage()->GetTransform()[0]->GetMatrix());
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::UpdateYtranslider()
+void vvToolRigidReg::ResetTransform()
 {
-  int diff=0;
-  diff=ytrans_slider->value()-ytrans_sb->value();
-  this->SetTransform(0, diff, 0, 0, 0, 0);
-  ytrans_sb->setValue(ytrans_slider->value());
+  SetTransform(mInitialMatrix);
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::UpdateZtranslider()
+void vvToolRigidReg::SetTransform(vtkMatrix4x4 *matrix)
 {
-  int diff=0;
-  diff=ztrans_slider->value()-ztrans_sb->value();
-  this->SetTransform(0, 0, diff, 0, 0, 0);
-  ztrans_sb->setValue(ztrans_slider->value());
+  vtkSmartPointer<vtkTransform> transform=vtkSmartPointer<vtkTransform>::New();
+  // TODO SR and BP: check on the list of transforms and not the first only
+  mCurrentSlicerManager->GetImage()->GetTransform()[0]->SetMatrix(matrix);
+  transform->Update();
+  Render();
+  dynamic_cast<vvMainWindow*>(mMainWindow)->ImageInfoChanged();
+
+  // Compute parameters from transfer using itk Euler transform
+  itk::Euler3DTransform<double>::CenterType center;
+  center[0] = Xval->text().toDouble();
+  center[1] = Yval->text().toDouble();
+  center[2] = Zval->text().toDouble();
+  itk::Euler3DTransform<double>::MatrixType rotMat;
+  itk::Euler3DTransform<double>::OutputVectorType transVec;
+  for(int i=0; i<3; i++) {
+    transVec[i] = matrix->GetElement(i,3);
+    for(int j=0; j<3; j++)
+      rotMat[i][j] = matrix->GetElement(i,j);
+  }
+  itk::Euler3DTransform<double>::Pointer euler;
+  euler = itk::Euler3DTransform<double>::New();
+  euler->SetCenter(center);
+  try {
+#if ITK_VERSION_MAJOR > 4 || (ITK_VERSION_MAJOR == 4 && ITK_VERSION_MINOR > 6)
+    euler->SetMatrix(rotMat,0.00001);
+#else
+    euler->SetMatrix(rotMat);
+#endif
+  } catch (itk::ExceptionObject) {
+    QString warning = "The matrice is a non-orthogonal rotation matrix.\nThe manual registration doesn't work.";
+    QMessageBox msgBox(QMessageBox::Warning, tr("Reset transform"),warning, 0, this);
+    msgBox.addButton(tr("OK"), QMessageBox::AcceptRole);
+    if (msgBox.exec() == QMessageBox::AcceptRole) {
+        //SetTransform(mInitialMatrix);
+        vvToolWidgetBase::close();
+    }
+  }
+  euler->SetOffset(transVec);
+
+  // Modify GUI according to the new parameters
+  std::vector<QSlider *> transSliders, rotSliders;
+  std::vector<QDoubleSpinBox *> transSBs, rotSBs;
+  GetSlidersAndSpinBoxes(transSliders, rotSliders, transSBs, rotSBs);
+  for(int i=0; i<3; i++) {
+    // Translations
+    transSBs[i]->blockSignals(true);
+    transSBs[i]->setValue( euler->GetParameters()[i+3] );
+    transSBs[i]->blockSignals(false);
+    transSliders[i]->blockSignals(true);
+    transSliders[i]->setValue( itk::Math::Round<double,double>(euler->GetParameters()[i+3]) );
+    transSliders[i]->blockSignals(false);
+
+    // Rotations
+    double rad = (checkBoxDegrees->checkState()==Qt::Checked)?180./itk::Math::pi:1.;
+    double angleDiff = euler->GetParameters()[i]-rotSBs[i]->value()/rad+2*itk::Math::pi;
+    angleDiff = angleDiff - 2*itk::Math::pi*itk::Math::Round<double,double>(angleDiff/(2*itk::Math::pi));
+    if(std::abs(angleDiff)>1.e-4) {
+      rotSBs[i]->blockSignals(true);
+      rotSBs[i]->setValue( euler->GetParameters()[i]*rad );
+      rotSBs[i]->blockSignals(false);
+    }
+    int iAngle = itk::Math::Round<int,double>(euler->GetParameters()[i]*180./itk::Math::pi);
+    if((iAngle-rotSliders[i]->value()+360)%360!=0) {
+      rotSliders[i]->blockSignals(true);
+      rotSliders[i]->setValue(iAngle);
+      rotSliders[i]->blockSignals(false);
+    }
+  }
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::UpdateXrotslider()
+// Just an helper function to shorten the code with loops on sliders and spinboxes
+void vvToolRigidReg::GetSlidersAndSpinBoxes(std::vector<QSlider *>&transSliders, std::vector<QSlider *>&rotSliders,
+                                            std::vector<QDoubleSpinBox *>&transSBs, std::vector<QDoubleSpinBox *>&rotSBs)
 {
-  int diff=0;
-  diff=xrot_slider->value()-xrot_sb->value();
-  this->SetTransform(0, 0, 0, diff, 0, 0);
-  xrot_sb->setValue(xrot_slider->value());
+  transSliders.push_back(xtrans_slider);
+  transSliders.push_back(ytrans_slider);
+  transSliders.push_back(ztrans_slider);
+
+  rotSliders.push_back(xrot_slider);
+  rotSliders.push_back(yrot_slider);
+  rotSliders.push_back(zrot_slider);
+
+  transSBs.push_back(xtrans_sb);
+  transSBs.push_back(ytrans_sb);
+  transSBs.push_back(ztrans_sb);
+
+  rotSBs.push_back(xrot_sb);
+  rotSBs.push_back(yrot_sb);
+  rotSBs.push_back(zrot_sb);
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::UpdateYrotslider()
+void vvToolRigidReg::ExtentMax(const double pointExtent[8][4], double maxExtent[2][3])
 {
-  int diff=0;
-  diff=yrot_slider->value()-yrot_sb->value();
-  this->SetTransform(0, 0, 0, 0, diff, 0);
-  yrot_sb->setValue(yrot_slider->value());
+    double max, min;
+    for (int i=0; i<3; ++i) {
+        max = pointExtent[0][i];
+        min = pointExtent[0][i];
+        for (int j=1; j<8; ++j) {
+            if (pointExtent[j][i] > max) {
+                max = pointExtent[j][i];
+            }
+            if (pointExtent[j][i] < min) {
+                min = pointExtent[j][i];
+            }
+        }
+        maxExtent[0][i] = min;
+        maxExtent[1][i] = max;
+    }
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::UpdateZrotslider()
+void vvToolRigidReg::Render()
 {
-  int diff=0;
-  diff=zrot_slider->value()-zrot_sb->value();
-  this->SetTransform(0, 0, 0, 0, 0, diff);
-  zrot_sb->setValue(zrot_slider->value());
+for (int i=0; i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
+    mCurrentSlicerManager->GetSlicer(i)->ForceUpdateDisplayExtent();
+    mCurrentSlicerManager->GetSlicer(i)->Render();
+}
 }
+//------------------------------------------------------------------------------
+