]> Creatis software - clitk.git/blobdiff - vv/vvToolRigidReg.cxx
Debug RTStruct conversion with empty struc
[clitk.git] / vv / vvToolRigidReg.cxx
index ec94832f32f66e4f97e7b097518f67c2a5afb0b1..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 <QFile>
-#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.
@@ -44,13 +57,28 @@ 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");
-    mOrder=QString("Rotation Order: ");
-   
+  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);
+  }
 }
 //------------------------------------------------------------------------------
 
@@ -61,639 +89,396 @@ vvToolRigidReg::~vvToolRigidReg()
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-bool vvToolRigidReg::close()
+void vvToolRigidReg::Initialize()
 {
-   
-  return vvToolWidgetBase::close();
+  SetToolName("Register");
+  SetToolMenuName("Register manually");
+  SetToolIconFilename(":/common/icons/register.png");
+  SetToolTip("Register manually.");
+  SetToolExperimental(false);
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::reject()
+void vvToolRigidReg::InputIsSelected(vvSlicerManager *input)
 {
-  mInput2->Reload();   
-  for(int i=0;i<mCurrentSlicerManager->NumberOfSlicers();i++)
-      { 
-       mInput1->GetSlicer(i)->RemoveActor("overlay",0);
-       mInput1->SetColorMap(0);
-       mInput1->Render();
-      }
-  return vvToolWidgetBase::reject();
-}
-//------------------------------------------------------------------------------
+  mInput = input;
+  HideInputSelector();
+  QTabWidget * tab = dynamic_cast<vvMainWindow*>(mMainWindow)->GetTab();
+  move(tab->mapToGlobal(tab->pos()));
+  resize(tab->width(), 0);
 
-//------------------------------------------------------------------------------
-void vvToolRigidReg::InputIsSelected(std::vector<vvSlicerManager *> & l)
-{
-  //inputs
-  mInput1 = l[0];
-  mInput2 = l[1];
-  mTwoInputs = true;
-  SetOverlay();
-  this->mImageSize=mCurrentSlicerManager->GetImage()->GetSize();
-  
-  SetRotationCenter();
-  SetSliderRanges();
-  
-    //connect all sigs to slots        
-  connect(resetbutton, SIGNAL(pressed()), this, SLOT(ResetTransform()));
-  
-  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(sliderReleased()), this, SLOT(SetOrderXtrans()));
-  connect(ytrans_slider, SIGNAL(sliderReleased()), this, SLOT(SetOrderYtrans()));
-  connect(ztrans_slider, SIGNAL(sliderReleased()), this, SLOT(SetOrderZtrans()));
-  connect(xrot_slider, SIGNAL(sliderReleased()), this, SLOT(SetOrderXrot()));
-  connect(yrot_slider, SIGNAL(sliderReleased()), this, SLOT(SetOrderYrot()));
-  connect(zrot_slider, SIGNAL(sliderReleased()), this, SLOT(SetOrderZrot()));
-  
-  
-  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(xtrans_sb, SIGNAL(valueChanged(int)), this, SLOT(UpdateXtransb()));
-   connect(ytrans_sb, SIGNAL(valueChanged(int)), this, SLOT(UpdateYtransb()));
-   connect(ztrans_sb, SIGNAL(valueChanged(int)), this, SLOT(UpdateZtransb()));
-   connect(xrot_sb, SIGNAL(valueChanged(int)), this, SLOT(UpdateXrotsb()));
-   connect(yrot_sb, SIGNAL(valueChanged(int)), this, SLOT(UpdateYrotsb()));
-   connect(zrot_sb, SIGNAL(valueChanged(int)), this, SLOT(UpdateZrotsb()));
-   
-  
-  connect(loadbutton, SIGNAL(pressed()), this, SLOT(ReadFile()));
-  connect(savebutton, SIGNAL(pressed()), this, SLOT(SaveFile()));
-}
-//------------------------------------------------------------------------------
+  //default image rotation center is the center of the image
+  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);
 
-//------------------------------------------------------------------------------
-void vvToolRigidReg::apply()
-{
-  std::ostringstream osstream;
-  osstream <<  "Transformed_"  
-           << mInput2->GetSlicer(0)->GetFileName() << ".mhd";
-  AddImage(mInput2->GetImage(),osstream.str()); 
-  QApplication::restoreOverrideCursor();
-  close();
-}
-//------------------------------------------------------------------------------
+  //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);
 
-//------------------------------------------------------------------------------
-void vvToolRigidReg::SetOverlay()
-{
-  mCurrentSlicerManager=mInput2;
-  for (int i =0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
-    mInput1->GetSlicer(i)->SetOverlay(mInput2->GetImage());
-    mInput1->GetSlicer(i)->SetActorVisibility("overlay",0,true);
-    mInput1->SetColorMap();
-    mInput1->Render();
-   }
-  }
-//------------------------------------------------------------------------------
+  //connect all sigs to slots
+  connect(resetbutton, SIGNAL(pressed()), this, SLOT(ResetTransform()));
+  connect(loadbutton, SIGNAL(pressed()), this, SLOT(LoadFile()));
+  connect(savebutton, SIGNAL(pressed()), this, SLOT(SaveFile()));
 
-//------------------------------------------------------------------------------
-void vvToolRigidReg::SetXvalue()
-{
-  QString xstr = Xval->text();
-}
-//------------------------------------------------------------------------------
+  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)));
 
-//------------------------------------------------------------------------------
-void vvToolRigidReg::SetYvalue()
-{
-  QString ystr = Yval->text();
-}
-//------------------------------------------------------------------------------
+  connect(stepTransSpinBox, SIGNAL(valueChanged(double)), this, SLOT(SetTranslationStep(double)));
+  connect(stepRotSpinBox, SIGNAL(valueChanged(double)), this, SLOT(SetRotationStep(double)));
 
-//------------------------------------------------------------------------------
-void vvToolRigidReg::SetZvalue()
-{
-  QString zstr = Zval->text();
-}
-//------------------------------------------------------------------------------
+  connect(checkBoxDegrees, SIGNAL(stateChanged(int)), this, SLOT(ToggleSpinBoxAnglesUnit()));
 
-//------------------------------------------------------------------------------
-void vvToolRigidReg::SetTransform(double tX, double tY, double tZ, double aX, double aY, double aZ)
-{
-   
-  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);
-  }
-  //Translations
-  if (tX!=0||tY!=0||tZ!=0)
-    transform->Translate(tX,tY,tZ);
+  connect(Xval, SIGNAL(editingFinished()), this, SLOT(ChangeOfRotationCenter()));
+  connect(Yval, SIGNAL(editingFinished()), this, SLOT(ChangeOfRotationCenter()));
+  connect(Zval, SIGNAL(editingFinished()), this, SLOT(ChangeOfRotationCenter()));
 
-    transform->Update();
-
-  for (int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
-    mCurrentSlicerManager->GetImage()->UpdateReslice();
-    mCurrentSlicerManager->GetSlicer(i)->ForceUpdateDisplayExtent();
-    mCurrentSlicerManager->GetSlicer(i)->Render();
-  }
+  // Init step modifiers
+  stepTransSpinBox->setValue(1.);
+  stepRotSpinBox->setValue(1.);
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::SetTransform(vtkMatrix4x4 *matrix)
-{
-    vtkSmartPointer<vtkTransform> transform =mCurrentSlicerManager->GetImage()->GetTransform();
-    transform->SetMatrix(matrix);
-   // mCurrentSlicerManager->GetImage()->SetTransform(transform);
-    transform->PostMultiply();
-    transform->Concatenate(matrix);
-    transform->Update();
-    mCurrentSlicerManager->GetImage()->SetTransform(transform);
-    for (int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
-    mCurrentSlicerManager->GetImage()->UpdateReslice();
-   mCurrentSlicerManager->GetSlicer(i)->ForceUpdateDisplayExtent();
-    mCurrentSlicerManager->GetSlicer(i)->Render();
-    }
-}
-//------------------------------------------------------------------------------
-
-//------------------------------------------------------------------------------
-  void vvToolRigidReg::UpdateTextEditor(vtkMatrix4x4 *matrix,QString SetOrder)
-{
-   QString str1,str2,str3;
-   
-    QColor color;
-    textEdit->clear();
-    textEdit->setAcceptRichText(true);
-    str2=textEdit->toPlainText();
-    str2.append("Rotation Center(mm): \n");
-    textEdit->setText(str2);
-    
-    str2=textEdit->toPlainText();
-    textEdit->setTextColor(QColor(255,0,0));
-    str2.append(str3.append(Xval->text()));
-    textEdit->setText(str2);
-    str3.clear();
-
-    str2=textEdit->toPlainText();
-    str2.append("\t");
-    textEdit->setText(str2);
-
-    str2=textEdit->toPlainText();
-    str2.append(str3.append(Yval->text()));
-    textEdit->setText(str2);
-    str3.clear();
-    
-    str2=textEdit->toPlainText();
-    str2.append("\t");
-    textEdit->setText(str2);
-    
-
-    str2=textEdit->toPlainText();
-    str2.append(str3.append(Zval->text()));
-    textEdit->setText(str2);
-
-
-    str2=textEdit->toPlainText();
-    str2.append("\n");
-    textEdit->setText(str2);
-    
-
-    str2=textEdit->toPlainText();
-    str2.append("Transformation Matrix:\n");
-    textEdit->setText(str2);
-
-    
-    for(int i=0;i<4;i++)
-    {
-    for(int j=0;j<4;j++)
-      {
-    str2=textEdit->toPlainText();
-    str2.append("\t"+str1.setNum(matrix->Element[i][j]));
-    textEdit->setText(str2);
-      }
-    str2=textEdit->toPlainText();
-    str2.append("\n");  
-    textEdit->setText(str2);
-    }
-    //QString str = QFileDialog::getOpenFileName();
-    textEdit->setTextColor(QColor(255,0,0));
-    textEdit->setFont(QFont("courrier new",12,4,true));
-    textEdit->toPlainText().toAscii();
-    
-    str2=textEdit->toPlainText();
-    mOrder+=SetOrder+QString(" ");
-    str2.append(mOrder);
-    textEdit->setText(str2);
-}
-//------------------------------------------------------------------------------
-
-//------------------------------------------------------------------------------
-void vvToolRigidReg::SetOrderXtrans()
+void vvToolRigidReg::apply()
 {
-  if(mOrder.size()-mOrder.lastIndexOf("Tx")<10) //see if the same Transformation Parameter has been used back to back
-  mOrder.chop(mOrder.size()-mOrder.lastIndexOf("Tx"));
-  UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Tx: ")+xtrans_sb->text());
+  vvToolWidgetBase::close();
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::SetOrderYtrans()
+bool vvToolRigidReg::close()
 {
-  if(mOrder.size()-mOrder.lastIndexOf("Ty")<10) 
-  mOrder.chop(mOrder.size()-mOrder.lastIndexOf("Ty"));
-  UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Ty: ")+ytrans_sb->text());
+  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::SetOrderZtrans()
+void vvToolRigidReg::reject()
 {
-  if(mOrder.size()-mOrder.lastIndexOf("Tz")<10) 
-  mOrder.chop(mOrder.size()-mOrder.lastIndexOf("Tz"));
-  UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Tz: ")+ztrans_sb->text());
+  return vvToolWidgetBase::reject();
 }
-
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::SetOrderXrot()
+void vvToolRigidReg::SetTranslationStep(double v)
 {
-  if(mOrder.size()-mOrder.lastIndexOf("Rx")<10) 
-  mOrder.chop(mOrder.size()-mOrder.lastIndexOf("Rx"));
-  UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Rx: ")+xrot_sb->text());
+  xtrans_sb->setSingleStep(v);
+  ytrans_sb->setSingleStep(v);
+  ztrans_sb->setSingleStep(v);
 }
-
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::SetOrderYrot()
+void vvToolRigidReg::SetRotationStep(double v)
 {
- if(mOrder.size()-mOrder.lastIndexOf("Ry")<10) //see if the same Transformation Parameter has been used back to back
-  mOrder.chop(mOrder.size()-mOrder.lastIndexOf("Ry"));
UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Ry: ")+yrot_sb->text());
+  xrot_sb->setSingleStep(v);
+  yrot_sb->setSingleStep(v);
 zrot_sb->setSingleStep(v);
 }
-
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::SetOrderZrot()
+void vvToolRigidReg::SliderChange(int newVal)
 {
-  if(mOrder.size()-mOrder.lastIndexOf("Rz")<10) //see if the same Transformation Parameter has been used back to back
-  mOrder.chop(mOrder.size()-mOrder.lastIndexOf("Rz"));
-  UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Rz: ")+zrot_sb->text());
+  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);
+    }
+  }
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::UpdateXtransb()
+void vvToolRigidReg::SpinBoxChange(double newVal)
 {
-  int diff=0;
-  diff=xtrans_sb->value()-xtrans_slider->value();
-  this->SetTransform(diff, 0, 0, 0, 0, 0);
-  xtrans_slider->setValue(xtrans_sb->value());
- // UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Tx:")+xtrans_sb->text());
-    
-}
-//------------------------------------------------------------------------------
+  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);
+    }
+  }
 
-//------------------------------------------------------------------------------
-void vvToolRigidReg::UpdateXtranslider()
-{
-  int diff=0;
-  diff=xtrans_slider->value()-xtrans_sb->value();
-  this->SetTransform(diff, 0, 0, 0, 0, 0);
-  xtrans_sb->setValue(xtrans_slider->value());
-  //UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Tx:")+xtrans_sb->text());
+  // 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());
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+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::UpdateYtransb()
+void vvToolRigidReg::SaveFile()
 {
-
-  int diff=0;
-  diff=ytrans_sb->value()-ytrans_slider->value();
-  this->SetTransform(0, diff, 0, 0, 0, 0);
-  ytrans_slider->setValue(ytrans_sb->value());
-//  UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Ty:")+ytrans_sb->text());
+  //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");
+  }
 }
-
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::UpdateYtranslider()
+void vvToolRigidReg::LoadFile()
 {
-  int diff=0;
-  diff=ytrans_slider->value()-ytrans_sb->value();
-  this->SetTransform(0, diff, 0, 0, 0, 0);
-  ytrans_sb->setValue(ytrans_slider->value());
-// UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Ty:")+ytrans_sb->text());
-}
-//------------------------------------------------------------------------------
+  //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;
 
-//------------------------------------------------------------------------------
-void vvToolRigidReg::UpdateZtransb()
-{
 
-  int diff=0;
-  diff=ztrans_sb->value()-ztrans_slider->value();
-  this->SetTransform(0, 0, diff, 0, 0, 0);
-  ztrans_slider->setValue(ztrans_sb->value());
- // UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Tz:")+ztrans_sb->text());
+  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::UpdateZtranslider()
+void vvToolRigidReg::ChangeOfRotationCenter()
 {
-  int diff=0;
-  diff=ztrans_slider->value()-ztrans_sb->value();
-  this->SetTransform(0, 0, diff, 0, 0, 0);
-  ztrans_sb->setValue(ztrans_slider->value());
-// UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Tz:")+ztrans_sb->text());
+  // TODO SR and BP: check on the list of transforms and not the first only
+  SetTransform(mCurrentSlicerManager->GetImage()->GetTransform()[0]->GetMatrix());
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::UpdateXrotsb()
+void vvToolRigidReg::ResetTransform()
 {
-
-  int diff=0;
-  diff=xrot_sb->value()-xrot_slider->value();
-  this->SetTransform(0, 0, 0, diff, 0, 0);
-  xrot_slider->setValue(xrot_sb->value());
- // UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Rx:")+xrot_sb->text());
+  SetTransform(mInitialMatrix);
 }
-
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::UpdateXrotslider()
+void vvToolRigidReg::SetTransform(vtkMatrix4x4 *matrix)
 {
-  int diff=0;
-  diff=xrot_slider->value()-xrot_sb->value();
-  this->SetTransform(0, 0, 0, diff, 0, 0);
-  xrot_sb->setValue(xrot_slider->value());
- // UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Rx:")+xrot_sb->text());
+  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::UpdateYrotsb()
+// 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)
 {
+  transSliders.push_back(xtrans_slider);
+  transSliders.push_back(ytrans_slider);
+  transSliders.push_back(ztrans_slider);
 
-  int diff=0;
-  diff=yrot_sb->value()-yrot_slider->value();
-  this->SetTransform(0, 0, 0, 0, diff, 0);
-  yrot_slider->setValue(yrot_sb->value());
- // UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Ry:")+yrot_sb->text());
-}
-
-//------------------------------------------------------------------------------
-
-//------------------------------------------------------------------------------
-void vvToolRigidReg::UpdateYrotslider()
-{
-  int diff=0;
-  diff=yrot_slider->value()-yrot_sb->value();
-  this->SetTransform(0, 0, 0, 0, diff, 0);
-  yrot_sb->setValue(yrot_slider->value());
-//  UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Ry:")+yrot_sb->text());
-}
-//------------------------------------------------------------------------------
+  rotSliders.push_back(xrot_slider);
+  rotSliders.push_back(yrot_slider);
+  rotSliders.push_back(zrot_slider);
 
-//------------------------------------------------------------------------------
-void vvToolRigidReg::UpdateZrotsb()
-{
+  transSBs.push_back(xtrans_sb);
+  transSBs.push_back(ytrans_sb);
+  transSBs.push_back(ztrans_sb);
 
-  int diff=0;
-  diff=zrot_sb->value()-zrot_slider->value();
-  this->SetTransform(0, 0, 0, 0, 0,diff);
-  zrot_slider->setValue(zrot_sb->value());
- // UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Rz:")+zrot_sb->text());
+  rotSBs.push_back(xrot_sb);
+  rotSBs.push_back(yrot_sb);
+  rotSBs.push_back(zrot_sb);
 }
-
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvToolRigidReg::UpdateZrotslider()
+void vvToolRigidReg::ExtentMax(const double pointExtent[8][4], double maxExtent[2][3])
 {
-  int diff=0;
-  diff=zrot_slider->value()-zrot_sb->value();
-  this->SetTransform(0, 0, 0, 0, 0, diff);
-  zrot_sb->setValue(zrot_slider->value());
-//  UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),QString("Rz:")+zrot_sb->text());
-}
-//------------------------------------------------------------------------------
-
-//------------------------------------------------------------------------------
-void vvToolRigidReg::SaveFile()
-{      
-   QString s = QFileDialog::getSaveFileName(this, tr("Save File"),
-                            "/home/bharath/clitk3_27Apr/clitk3/build/bin/text.txt",
-                            tr("Text (*.txt *.doc *.rtf)"));
-    QFile file(s);
-    if (file.open(QFile::WriteOnly | QFile::Truncate)) {
-    QTextStream out(&file);
-    out << textEdit->toPlainText() ;
+    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::ReadFile()
-{      
-  QString parameters=QString("Tx: Ty: Tz:");
-   vtkSmartPointer<vtkTransform> transform = mCurrentSlicerManager->GetImage()->GetTransform();
-   
-   
-   QString s = QFileDialog::getOpenFileName(
-                    this,
-                    "Choose a file",
-                    "/home/bharath/clitk3_27Apr/clitk3/build/bin/",
-                    "Text (*.txt *.rtf *.doc)");
-   QFile file(s);
-   ifstream readfile;
-   std::string x;
-   std::vector<QString> Qstr;
-   
-   readfile.open("text.txt");
-   if (readfile.is_open()) 
-   {
-    while (!readfile.eof())
-      {
-      readfile >> x;
-      Qstr.push_back(QString(x.c_str()));
-      }
-      readfile.close();
-   }
-   else cout << "Unable to open file";
-
-   //Obtain the Rotation Center 
-    Xval->setText(Qstr.at(2));
-    Yval->setText(Qstr.at(3));
-    Zval->setText(Qstr.at(4));
-
-//    InitializeSliders();
-    double * orientations=new double[4];
-    double * translations=new double[3];
-    transform->PostMultiply();
-  //Works currently wit the ROtation order Y Z X 
-    transform->GetPosition(translations);
-    transform->GetOrientation(orientations);
-   /* xtrans_slider->setValue(Qstr.at(10).toDouble());
-    UpdateXtranslider();
-    ytrans_slider->setValue(Qstr.at(14).toDouble());
-    UpdateYtranslider();
-    ztrans_slider->setValue(Qstr.at(18).toDouble());
-    UpdateZtranslider();
-*/
-    DD(translations[0]);
-    DD(translations[1]);
-    DD(translations[2]);
-    DD(orientations[0]);
-    DD(orientations[1]);
-    DD(orientations[2]);
-    DD(orientations[3]);
-    DD(*transform->GetMatrix());
-    //Obtain the Transformation Matrix
-    /*QString str;
-   str=QString(value.at(10).c_str());
-   DD(str.toStdString());
-   */
-// DD(value[6]);
-           // DD(value[10]);   
-   //put the streamed values in matrix array
-  /* for(int i=0;i<4;i++)
-   {
-     for(int j=0;j<4;j++)
-     {
-       matrix->Element[i][j]=value[i*4+j];
-     }
-   }
-   SetTransform( matrix);*/
-
- /*xtrans_slider->setValue(value.at(10));
-   ytrans_slider->setValue(value.at(14));
-   ztrans_slider->setValue(value.at(18));
-   UpdateXtranslider();
-   UpdateYtranslider();
-   UpdateZtranslider();*/
-}
-//------------------------------------------------------------------------------
-
-//------------------------------------------------------------------------------
-void vvToolRigidReg::ResetTransform()
-{
-  vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
-   matrix->Identity();
-   
-   SetRotationCenter();
-   SetSliderRanges();
-   SetTransform(matrix);
-   mOrder.clear();
-   mOrder=QString("Rotation Order: ");
-   UpdateTextEditor(matrix,mOrder);
-}
-//------------------------------------------------------------------------------
-
-//------------------------------------------------------------------------------
-void vvToolRigidReg::SetRotationCenter()
+void vvToolRigidReg::Render()
 {
-    //default image rotation center is the center of the image
-    QString xcord,ycord,zcord;
-    std::vector<double> imageorigin;
-    imageorigin=mCurrentSlicerManager->GetImage()->GetOrigin();
-    
-    xcord=xcord.setNum(imageorigin[0]+mImageSize[0]*mCurrentSlicerManager->GetImage()->GetSpacing()[0]/2, 'g', 3);
-    ycord=ycord.setNum(imageorigin[1]+mImageSize[1]*mCurrentSlicerManager->GetImage()->GetSpacing()[1]/2, 'g', 3);
-    zcord=zcord.setNum(imageorigin[2]+mImageSize[2]*mCurrentSlicerManager->GetImage()->GetSpacing()[2]/2, 'g', 3);
-
-    Xval->setText(xcord);
-    Yval->setText(ycord);
-    Zval->setText(zcord);
-    InitializeSliders();
+for (int i=0; i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
+    mCurrentSlicerManager->GetSlicer(i)->ForceUpdateDisplayExtent();
+    mCurrentSlicerManager->GetSlicer(i)->Render();
 }
-//------------------------------------------------------------------------------
-
-//------------------------------------------------------------------------------
-void vvToolRigidReg::InitializeSliders()
-{
-     xtrans_slider->signalsBlocked();
-     ytrans_slider->signalsBlocked();
-     ztrans_slider->signalsBlocked();
-     xtrans_sb->signalsBlocked();
-     ytrans_sb->signalsBlocked();
-     ztrans_sb->signalsBlocked();
-     xrot_slider->signalsBlocked();
-     yrot_slider->signalsBlocked();
-     zrot_slider->signalsBlocked();
-     xrot_sb->signalsBlocked();
-     yrot_sb->signalsBlocked();
-     zrot_sb->signalsBlocked();
-     
-    xtrans_sb->setValue(0);
-    ytrans_sb->setValue(0);
-    ztrans_sb->setValue(0);
-    
-    xtrans_slider->setValue(0);
-    ytrans_slider->setValue(0);
-    ztrans_slider->setValue(0);
-    
-    xrot_sb->setValue(0);
-    yrot_sb->setValue(0);
-    zrot_sb->setValue(0);
-
-    xrot_slider->setValue(0);
-    yrot_slider->setValue(0);
-    zrot_slider->setValue(0);
 }
 //------------------------------------------------------------------------------
 
-//------------------------------------------------------------------------------
-void vvToolRigidReg::SetSliderRanges()
-{
-  xtrans_slider->setMaximum(1000);
-  xtrans_slider->setMinimum(-1000);
-  ytrans_slider->setMaximum(1000);
-  ytrans_slider->setMinimum(-1000);
-  ztrans_slider->setMaximum(1000);
-  ztrans_slider->setMinimum(-1000);
-
-  xtrans_sb->setMaximum(1000);
-  xtrans_sb->setMinimum(-1000);
-  ytrans_sb->setMaximum(1000);
-  ytrans_sb->setMinimum(-1000);
-  ztrans_sb->setMaximum(1000);
-  ztrans_sb->setMinimum(-1000);
-
-  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);
-}