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),
- vvToolBase<vvToolRigidReg>(parent),
- Ui::vvToolRigidReg()
+ vvToolWidgetBase(parent, f),
+ vvToolBase<vvToolRigidReg>(parent),
+ Ui::vvToolRigidReg()
{
// 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()
+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)
{
- return vvToolWidgetBase::reject();
-}
-//------------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------------
-void vvToolRigidReg::InputIsSelected(std::vector<vvSlicerManager *> & l)
-{
- //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)->ForceUpdateDisplayExtent();
- 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();
+}
}
+//------------------------------------------------------------------------------
+