1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://www.centreleonberard.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
20 #include "vvToolRigidReg.h"
22 #include <vvBlendImageActor.h>
25 #include <vtkImageData.h>
26 #include <vtkSmartPointer.h>
27 #include <vtkInformation.h>
28 #include <vtkTransform.h>
29 #include <vtkImageActor.h>
30 #include <vtkImageMapper3D.h>
31 #include <vtkOpenGLImageSliceMapper.h>
34 #include <itkEuler3DTransform.h>
37 #include "clitkTransformUtilities.h"
38 #include "clitkMatrix.h"
41 #include <QMessageBox>
42 #include <QFileDialog>
43 #include <QTextStream>
46 //------------------------------------------------------------------------------
47 // Create the tool and automagically (I like this word) insert it in
48 // the main window menu.
49 ADD_TOOL(vvToolRigidReg);
50 //------------------------------------------------------------------------------
52 //------------------------------------------------------------------------------
53 vvToolRigidReg::vvToolRigidReg(vvMainWindowBase * parent, Qt::WindowFlags f):
54 vvToolWidgetBase(parent, f),
55 vvToolBase<vvToolRigidReg>(parent),
59 Ui_vvToolRigidReg::setupUi(mToolWidget);
61 // Set how many inputs are needed for this tool
62 AddInputSelector("Select moving image");
64 QFont font = transformationLabel->font();
65 font.setStyleHint(QFont::TypeWriter);
66 transformationLabel->setFont(font);
68 mInitialMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
70 // Set slider ranges, assume degrees, will not be changed for radians
71 std::vector<QSlider *> transSliders, rotSliders;
72 std::vector<QDoubleSpinBox *> transSBs, rotSBs;
73 GetSlidersAndSpinBoxes(transSliders, rotSliders, transSBs, rotSBs);
74 for(int i=0; i<3; i++) {
75 transSliders[i]->setRange(-2000,2000);
76 rotSliders[i]->setRange(-360,360);
77 transSBs[i]->setRange(-2000,2000);
78 transSBs[i]->setDecimals(3);
79 rotSBs[i]->setRange(-360,360);
80 rotSBs[i]->setDecimals(3);
83 //------------------------------------------------------------------------------
85 //------------------------------------------------------------------------------
86 vvToolRigidReg::~vvToolRigidReg()
89 //------------------------------------------------------------------------------
91 //------------------------------------------------------------------------------
92 void vvToolRigidReg::Initialize()
94 SetToolName("Register");
95 SetToolMenuName("Register manually");
96 SetToolIconFilename(":/common/icons/register.png");
97 SetToolTip("Register manually.");
98 SetToolExperimental(false);
100 //------------------------------------------------------------------------------
102 //------------------------------------------------------------------------------
103 void vvToolRigidReg::InputIsSelected(vvSlicerManager *input)
107 QTabWidget * tab = dynamic_cast<vvMainWindow*>(mMainWindow)->GetTab();
108 move(tab->mapToGlobal(tab->pos()));
109 resize(tab->width(), 0);
111 //default image rotation center is the center of the image
112 QString xcord,ycord,zcord;
113 std::vector<double> imageorigin;
114 imageorigin=mInput->GetImage()->GetOrigin();
115 std::vector<int> imageSize = mInput->GetImage()->GetSize();
116 std::vector<double> imageSpacing = mInput->GetImage()->GetSpacing();
117 xcord=xcord.setNum(imageorigin[0]+(imageSize[0]-1)*imageSpacing[0]*0.5, 'g', 3);
118 ycord=ycord.setNum(imageorigin[1]+(imageSize[1]-1)*imageSpacing[1]*0.5, 'g', 3);
119 zcord=zcord.setNum(imageorigin[2]+(imageSize[2]-1)*imageSpacing[2]*0.5, 'g', 3);
120 Xval->setText(xcord);
121 Yval->setText(ycord);
122 Zval->setText(zcord);
124 //backup original matrix
125 for(int j=0; j<4; j++)
126 for(int i=0; i<4; i++)
127 // TODO SR and BP: check on the list of transforms and not the first only
128 mInitialMatrix->SetElement(i,j, mCurrentSlicerManager->GetImage()->GetTransform()[0]->GetMatrix()->GetElement(i,j));
129 QString origTransformString(clitk::Get4x4MatrixDoubleAsString(mInitialMatrix).c_str());
130 transformationLabel->setText(origTransformString);
131 SetTransform(mInitialMatrix);
133 //connect all sigs to slots
134 connect(resetbutton, SIGNAL(pressed()), this, SLOT(ResetTransform()));
135 connect(loadbutton, SIGNAL(pressed()), this, SLOT(LoadFile()));
136 connect(savebutton, SIGNAL(pressed()), this, SLOT(SaveFile()));
138 connect(xtrans_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
139 connect(ytrans_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
140 connect(ztrans_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
141 connect(xrot_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
142 connect(yrot_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
143 connect(zrot_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
144 connect(xtrans_sb, SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
145 connect(ytrans_sb, SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
146 connect(ztrans_sb, SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
147 connect(xrot_sb, SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
148 connect(yrot_sb, SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
149 connect(zrot_sb, SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
151 connect(stepTransSpinBox, SIGNAL(valueChanged(double)), this, SLOT(SetTranslationStep(double)));
152 connect(stepRotSpinBox, SIGNAL(valueChanged(double)), this, SLOT(SetRotationStep(double)));
154 connect(checkBoxDegrees, SIGNAL(stateChanged(int)), this, SLOT(ToggleSpinBoxAnglesUnit()));
156 connect(Xval, SIGNAL(editingFinished()), this, SLOT(ChangeOfRotationCenter()));
157 connect(Yval, SIGNAL(editingFinished()), this, SLOT(ChangeOfRotationCenter()));
158 connect(Zval, SIGNAL(editingFinished()), this, SLOT(ChangeOfRotationCenter()));
160 // Init step modifiers
161 stepTransSpinBox->setValue(1.);
162 stepRotSpinBox->setValue(1.);
164 //------------------------------------------------------------------------------
166 //------------------------------------------------------------------------------
167 void vvToolRigidReg::apply()
169 vvToolWidgetBase::close();
171 //------------------------------------------------------------------------------
173 //------------------------------------------------------------------------------
174 bool vvToolRigidReg::close()
176 QString warning = "Are you sure you want to reset the original transform?";
177 QMessageBox msgBox(QMessageBox::Warning, tr("Reset transform"),warning, 0, this);
178 msgBox.addButton(tr("Yes"), QMessageBox::AcceptRole);
179 msgBox.addButton(tr("No"), QMessageBox::RejectRole);
180 if (msgBox.exec() == QMessageBox::AcceptRole) {
181 SetTransform(mInitialMatrix);
182 return vvToolWidgetBase::close();
186 //------------------------------------------------------------------------------
188 //------------------------------------------------------------------------------
189 void vvToolRigidReg::reject()
191 return vvToolWidgetBase::reject();
193 //------------------------------------------------------------------------------
195 //------------------------------------------------------------------------------
196 void vvToolRigidReg::SetTranslationStep(double v)
198 xtrans_sb->setSingleStep(v);
199 ytrans_sb->setSingleStep(v);
200 ztrans_sb->setSingleStep(v);
202 //------------------------------------------------------------------------------
204 //------------------------------------------------------------------------------
205 void vvToolRigidReg::SetRotationStep(double v)
207 xrot_sb->setSingleStep(v);
208 yrot_sb->setSingleStep(v);
209 zrot_sb->setSingleStep(v);
211 //------------------------------------------------------------------------------
213 //------------------------------------------------------------------------------
214 void vvToolRigidReg::SliderChange(int newVal)
216 std::vector<QSlider *> transSliders, rotSliders;
217 std::vector<QDoubleSpinBox *> transSBs, rotSBs;
218 GetSlidersAndSpinBoxes(transSliders, rotSliders, transSBs, rotSBs);
219 for(int i=0; i<3; i++) {
220 if(transSliders[i] == QObject::sender()) {
221 transSBs[i]->setValue(newVal);
223 if(rotSliders[i] == QObject::sender()) {
224 double rad = (checkBoxDegrees->checkState()==Qt::Unchecked)?itk::Math::pi/180.:1.;
225 rotSBs[i]->setValue(newVal*rad);
229 //------------------------------------------------------------------------------
231 //------------------------------------------------------------------------------
232 void vvToolRigidReg::SpinBoxChange(double newVal)
234 std::vector<QSlider *> transSliders, rotSliders;
235 std::vector<QDoubleSpinBox *> transSBs, rotSBs;
236 GetSlidersAndSpinBoxes(transSliders, rotSliders, transSBs, rotSBs);
237 for(int i=0; i<3; i++) {
238 if(transSBs[i] == QObject::sender()) {
239 transSliders[i]->blockSignals(true);
240 transSliders[i]->setValue(itk::Math::Round<double,double>(newVal));
241 transSliders[i]->blockSignals(false);
243 if(rotSBs[i] == QObject::sender()) {
244 double rad = (checkBoxDegrees->checkState()==Qt::Unchecked)?180./itk::Math::pi:1.;
245 rotSliders[i]->blockSignals(true);
246 rotSliders[i]->setValue(itk::Math::Round<double,double>(newVal*rad));
247 rotSliders[i]->blockSignals(false);
251 // Compute transform and set
252 // TODO SR and BP: check on the list of transforms and not the first only
253 vtkSmartPointer<vtkTransform> transform_final=mInput->GetImage()->GetTransform()[0];
254 transform_final->Identity();
255 transform_final->PostMultiply();
258 double x=0, y=0 ,z=0;
259 x= Xval->text().toDouble();
260 y= Yval->text().toDouble();
261 z= Zval->text().toDouble();
262 double rad = (checkBoxDegrees->checkState()==Qt::Unchecked)?180./itk::Math::pi:1.;
263 transform_final->Translate(-x,-y,-z);
264 transform_final->RotateY(yrot_sb->value()*rad);
265 transform_final->RotateX(xrot_sb->value()*rad);
266 transform_final->RotateZ(zrot_sb->value()*rad);
267 transform_final->Translate(x,y,z);
270 transform_final->Translate(xtrans_sb->value(),
273 transform_final->Update();
274 SetTransform(transform_final->GetMatrix());
276 //------------------------------------------------------------------------------
278 //------------------------------------------------------------------------------
279 void vvToolRigidReg::ToggleSpinBoxAnglesUnit()
281 double rad = (checkBoxDegrees->checkState()==Qt::Unchecked)?itk::Math::pi/180.:180./itk::Math::pi;
282 std::vector<QSlider *> transSliders, rotSliders;
283 std::vector<QDoubleSpinBox *> transSBs, rotSBs;
284 GetSlidersAndSpinBoxes(transSliders, rotSliders, transSBs, rotSBs);
285 for(int i=0; i<3; i++) {
286 rotSBs[i]->blockSignals(true);
287 rotSBs[i]->setValue(rotSBs[i]->value()*rad);
288 rotSBs[i]->blockSignals(false);
291 //------------------------------------------------------------------------------
293 //------------------------------------------------------------------------------
294 void vvToolRigidReg::SaveFile()
296 //Write the Transformation Matrix
297 std::string absPath = mCurrentSlicerManager->GetFileName();
298 absPath = itksys::SystemTools::GetFilenameWithoutExtension(absPath) + std::string(".mat");
299 QString filename = QFileDialog::getSaveFileName(this, tr("Save Transformation Matrix File"),
301 tr("Text (*.mat *.txt *.doc *.rtf)"));
303 QFile file(filename);
304 if (file.open(QFile::WriteOnly | QFile::Truncate)) {
305 // TODO SR and BP: check on the list of transforms and not the first only
306 vtkMatrix4x4* matrix = mCurrentSlicerManager->GetImage()->GetTransform()[0]->GetMatrix();
307 QString matrixStr = clitk::Get4x4MatrixDoubleAsString(matrix,16).c_str();
308 QTextStream out(&file);
313 QMessageBox::information(this,"Error","Unable to open file for writing");
316 //------------------------------------------------------------------------------
318 //------------------------------------------------------------------------------
319 void vvToolRigidReg::LoadFile()
321 //Open File to read the transformation parameters
322 QString file = QFileDialog::getOpenFileName(
324 "Choose the filename for the transformation matrix",
325 vtksys::SystemTools::GetFilenamePath(mCurrentSlicerManager->GetFileName()).c_str(),
326 "Text (*.mat *.txt *.rtf *.doc)");
331 itk::Matrix<double, 4, 4> itkMat = clitk::ReadMatrix3D(file.toStdString());
332 vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
334 for(int j=0; j<4; j++)
335 for(int i=0; i<4; i++)
336 matrix->SetElement(j,i,itkMat[j][i]);
337 SetTransform(matrix);
339 //------------------------------------------------------------------------------
341 //------------------------------------------------------------------------------
342 void vvToolRigidReg::ChangeOfRotationCenter()
344 // TODO SR and BP: check on the list of transforms and not the first only
345 SetTransform(mCurrentSlicerManager->GetImage()->GetTransform()[0]->GetMatrix());
347 //------------------------------------------------------------------------------
349 //------------------------------------------------------------------------------
350 void vvToolRigidReg::ResetTransform()
352 SetTransform(mInitialMatrix);
354 //------------------------------------------------------------------------------
356 //------------------------------------------------------------------------------
357 void vvToolRigidReg::SetTransform(vtkMatrix4x4 *matrix)
359 vtkSmartPointer<vtkTransform> transform=vtkSmartPointer<vtkTransform>::New();
360 // TODO SR and BP: check on the list of transforms and not the first only
361 mCurrentSlicerManager->GetImage()->GetTransform()[0]->SetMatrix(matrix);
362 //mCurrentSlicerManager->GetSlicer(2)->GetSlicingTransform()->SetMatrix(matrix);
365 dynamic_cast<vvMainWindow*>(mMainWindow)->ImageInfoChanged();
367 // Compute parameters from transfer using itk Euler transform
368 itk::Euler3DTransform<double>::CenterType center;
369 center[0] = Xval->text().toDouble();
370 center[1] = Yval->text().toDouble();
371 center[2] = Zval->text().toDouble();
372 itk::Euler3DTransform<double>::MatrixType rotMat;
373 itk::Euler3DTransform<double>::OutputVectorType transVec;
374 for(int i=0; i<3; i++) {
375 transVec[i] = matrix->GetElement(i,3);
376 for(int j=0; j<3; j++)
377 rotMat[i][j] = matrix->GetElement(i,j);
379 itk::Euler3DTransform<double>::Pointer euler;
380 euler = itk::Euler3DTransform<double>::New();
381 euler->SetCenter(center);
382 euler->SetMatrix(rotMat);
383 euler->SetOffset(transVec);
385 // Modify GUI according to the new parameters
386 std::vector<QSlider *> transSliders, rotSliders;
387 std::vector<QDoubleSpinBox *> transSBs, rotSBs;
388 GetSlidersAndSpinBoxes(transSliders, rotSliders, transSBs, rotSBs);
389 for(int i=0; i<3; i++) {
391 transSBs[i]->blockSignals(true);
392 transSBs[i]->setValue( euler->GetParameters()[i+3] );
393 transSBs[i]->blockSignals(false);
394 transSliders[i]->blockSignals(true);
395 transSliders[i]->setValue( itk::Math::Round<double,double>(euler->GetParameters()[i+3]) );
396 transSliders[i]->blockSignals(false);
399 double rad = (checkBoxDegrees->checkState()==Qt::Checked)?180./itk::Math::pi:1.;
400 double angleDiff = euler->GetParameters()[i]-rotSBs[i]->value()/rad+2*itk::Math::pi;
401 angleDiff = angleDiff - 2*itk::Math::pi*itk::Math::Round<double,double>(angleDiff/(2*itk::Math::pi));
402 if(angleDiff>1.e-4) {
403 rotSBs[i]->blockSignals(true);
404 rotSBs[i]->setValue( euler->GetParameters()[i]*rad );
405 rotSBs[i]->blockSignals(false);
407 int iAngle = itk::Math::Round<int,double>(euler->GetParameters()[i]*180./itk::Math::pi);
408 if((iAngle-rotSliders[i]->value()+360)%360!=0) {
409 rotSliders[i]->blockSignals(true);
410 rotSliders[i]->setValue(iAngle);
411 rotSliders[i]->blockSignals(false);
413 }cout << euler->GetParameters()[0+3] << " " << euler->GetParameters()[1+3] << " " << euler->GetParameters()[2+3] << endl;
415 //------------------------------------------------------------------------------
417 //------------------------------------------------------------------------------
418 // Just an helper function to shorten the code with loops on sliders and spinboxes
419 void vvToolRigidReg::GetSlidersAndSpinBoxes(std::vector<QSlider *>&transSliders, std::vector<QSlider *>&rotSliders,
420 std::vector<QDoubleSpinBox *>&transSBs, std::vector<QDoubleSpinBox *>&rotSBs)
422 transSliders.push_back(xtrans_slider);
423 transSliders.push_back(ytrans_slider);
424 transSliders.push_back(ztrans_slider);
426 rotSliders.push_back(xrot_slider);
427 rotSliders.push_back(yrot_slider);
428 rotSliders.push_back(zrot_slider);
430 transSBs.push_back(xtrans_sb);
431 transSBs.push_back(ytrans_sb);
432 transSBs.push_back(ztrans_sb);
434 rotSBs.push_back(xrot_sb);
435 rotSBs.push_back(yrot_sb);
436 rotSBs.push_back(zrot_sb);
438 //------------------------------------------------------------------------------
440 //------------------------------------------------------------------------------
441 void vvToolRigidReg::ExtentMax(const double pointExtent[8][4], double maxExtent[2][3])
444 for (int i=0; i<3; ++i) {
445 max = pointExtent[0][i];
446 min = pointExtent[0][i];
447 for (int j=1; j<8; ++j) {
448 if (pointExtent[j][i] > max) {
449 max = pointExtent[j][i];
451 if (pointExtent[j][i] < min) {
452 min = pointExtent[j][i];
455 maxExtent[0][i] = min;
456 maxExtent[1][i] = max;
459 //------------------------------------------------------------------------------
461 //------------------------------------------------------------------------------
462 void vvToolRigidReg::Render()
463 { //out << __func__ << endl;
464 #if VTK_MAJOR_VERSION > 7
465 double translationValues[4], translationValuesUpdate[4];
466 mCurrentSlicerManager->GetImage()->GetTransform()[0]->Print(cout);
467 vtkMatrix4x4* matrix = mCurrentSlicerManager->GetImage()->GetTransform()[0]->GetMatrix();
468 vtkMatrix4x4* matrixTranspose = matrix->NewInstance();
469 for (int i=0; i<3; ++i) {
470 for (int j=0; j<3; ++j)
472 matrixTranspose->SetElement(i,j,matrix->GetElement(j,i));
475 for (int j=0; j<3; ++j)
477 translationValues[j] = matrix->GetElement(j,3);
479 translationValues[3] = 0.0;
480 matrix->MultiplyPoint(translationValues, translationValuesUpdate);
481 for (int i=0; i<3; ++i) {
482 matrixTranspose->SetElement(i,3,translationValuesUpdate[i]);
484 for (int i=0; i<4; ++i) {
485 matrixTranspose->SetElement(3,i,matrix->GetElement(3,i));
489 for (int i=0; i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
490 #if VTK_MAJOR_VERSION > 7
491 double pointExtent[8][4], pointExtentUpdate[8][4], pointOverlayExtent[8][4], pointOverlayExtentUpdate[8][4], centre[3], translation[3];
492 std::vector<int> w_ext;
493 w_ext=mCurrentSlicerManager->GetImage()->GetSize();
494 pointExtent[0][0] = 0.0;
495 pointExtent[0][1] = 0.0;
496 pointExtent[0][2] = 0.0;
497 pointExtent[0][3] = 1.0;
498 pointExtent[1][0] = w_ext[0]-1;
499 pointExtent[1][1] = w_ext[1]-1;
500 pointExtent[1][2] = w_ext[2]-1;
501 pointExtent[1][3] = 1.0;
502 pointExtent[2][0] = 0.0;
503 pointExtent[2][1] = w_ext[1]-1;
504 pointExtent[2][2] = w_ext[2]-1;
505 pointExtent[2][3] = 1.0;
506 pointExtent[3][0] = w_ext[0]-1;
507 pointExtent[3][1] = 0.0;
508 pointExtent[3][2] = w_ext[2]-1;
509 pointExtent[3][3] = 1.0;
510 pointExtent[4][0] = w_ext[0]-1;
511 pointExtent[4][1] = w_ext[1]-1;
512 pointExtent[4][2] = 0.0;
513 pointExtent[4][3] = 1.0;
514 pointExtent[5][0] = 0.0;
515 pointExtent[5][1] = 0.0;
516 pointExtent[5][2] = w_ext[2]-1;
517 pointExtent[5][3] = 1.0;
518 pointExtent[6][0] = 0.0;
519 pointExtent[6][1] = w_ext[1]-1;
520 pointExtent[6][2] = 0.0;
521 pointExtent[6][3] = 1.0;
522 pointExtent[7][0] = w_ext[0]-1;
523 pointExtent[7][1] = 0.0;
524 pointExtent[7][2] = 0.0;
525 pointExtent[7][3] = 1.0;
527 centre[0] = Xval->text().toDouble();
528 centre[1] = Yval->text().toDouble();
529 centre[2] = Zval->text().toDouble();
531 for (int k=0; k<8; ++k) {
532 for (int j=0; j<3; ++j)
534 pointOverlayExtent[k][j] = mCurrentSlicerManager->GetImage()->GetSpacing()[j]*pointExtent[k][j] - centre[j];
536 pointOverlayExtent[k][3] = 0.0;
537 matrixTranspose->MultiplyPoint(pointOverlayExtent[k], pointOverlayExtentUpdate[k]);
538 for (int j=0; j<3; ++j)
540 pointOverlayExtentUpdate[k][j] = (pointOverlayExtentUpdate[k][j] + centre[j])/mCurrentSlicerManager->GetImage()->GetSpacing()[j];
541 cout << pointOverlayExtentUpdate[k][j] << " ";
546 for (int k=0; k<8; ++k) {
547 for (int j=0; j<3; ++j)
549 pointExtent[k][j] = mCurrentSlicerManager->GetImage()->GetSpacing()[j] * pointExtent[k][j];
551 matrixTranspose->MultiplyPoint(pointExtent[k], pointExtentUpdate[k]);
552 for (int j=0; j<3; ++j)
554 pointExtentUpdate[k][j] = (pointExtentUpdate[k][j])/mCurrentSlicerManager->GetImage()->GetSpacing()[j];
555 cout << pointExtentUpdate[k][j] << " ";
559 double extUpdateTemp[2][3], extOverlayUpdateTemp[2][3];
561 ExtentMax(pointExtentUpdate, extUpdateTemp);
562 ExtentMax(pointOverlayExtentUpdate, extOverlayUpdateTemp);
563 for (int j=0; j<3; ++j) {
565 extUpdate[2*j+1] = itk::Math::Round<double>(extUpdateTemp[1][j] - extUpdateTemp[0][j]);
567 mCurrentSlicerManager->GetSlicer(i)->SetRegisterExtent(extUpdate);
568 extUpdate[2*mCurrentSlicerManager->GetSlicer(i)->GetOrientation()] = mCurrentSlicerManager->GetSlicer(i)->GetSlice();
569 extUpdate[2*mCurrentSlicerManager->GetSlicer(i)->GetOrientation()+1] = mCurrentSlicerManager->GetSlicer(i)->GetSlice();
571 vtkSmartPointer<vtkOpenGLImageSliceMapper> mapperOpenGL= vtkSmartPointer<vtkOpenGLImageSliceMapper>::New();
573 mapperOpenGL = dynamic_cast<vtkOpenGLImageSliceMapper*>(mCurrentSlicerManager->GetSlicer(i)->GetImageActor()->GetMapper());
574 } catch (const std::bad_cast& e) {
575 std::cerr << e.what() << std::endl;
576 std::cerr << "Conversion error" << std::endl;
579 cout << extUpdate[0] << " " << extUpdate[1] << " " << extUpdate[2] << " " << extUpdate[3] << " " << extUpdate[4] << " " << extUpdate[5] << endl;
580 mapperOpenGL->SetCroppingRegion(extUpdate);
582 if (mCurrentSlicerManager->GetSlicer(i)->GetOverlay() && mCurrentSlicerManager->GetSlicer(i)->GetOverlayActor()->GetVisibility()) {
583 int extOverlayUpdate[6];
584 for (int j=0; j<3; ++j) { //Rotation
585 if (extOverlayUpdateTemp[1][j] - extOverlayUpdateTemp[0][j] > w_ext[j]-1) {
586 extOverlayUpdate[2*j] = 0;
587 extOverlayUpdate[2*j+1] = w_ext[j]-1;
589 extOverlayUpdate[2*j] = itk::Math::Round<double>(extOverlayUpdateTemp[0][j]);
590 extOverlayUpdate[2*j+1] = itk::Math::Round<double>(extOverlayUpdateTemp[1][j]);
594 //Compute translation
595 double pointOrigin[4], pointOriginUpdate[4];
596 for (int j=0; j<3; ++j)
598 pointOrigin[j] = 0 - centre[j];
600 pointOrigin[3] = 0.0;
601 matrix->MultiplyPoint(pointOrigin, pointOriginUpdate);
602 for (int j=0; j<3; ++j)
604 pointOriginUpdate[j] = (pointOriginUpdate[j] + centre[j])/mCurrentSlicerManager->GetImage()->GetSpacing()[j];
605 translation[j] = matrix->GetElement(j,3) - pointOriginUpdate[j]*mCurrentSlicerManager->GetImage()->GetSpacing()[j];
606 pointOrigin[j] = translation[j];
608 pointOrigin[3] = 0.0;
609 matrixTranspose->MultiplyPoint(pointOrigin, pointOriginUpdate);
610 for (int j=0; j<3; ++j)
612 translation[j] = pointOriginUpdate[j]/mCurrentSlicerManager->GetImage()->GetSpacing()[j];
615 for (int j=0; j<3; ++j) { //Translation
616 if (0 < extOverlayUpdateTemp[0][j] - translation[j]) {
617 extOverlayUpdate[2*j] = itk::Math::Round<double>(extOverlayUpdateTemp[0][j] - translation[j]);
619 extOverlayUpdate[2*j] = 0;
621 if (extOverlayUpdateTemp[1][j] - translation[j] < w_ext[j]-1) {
622 extOverlayUpdate[2*j+1] = itk::Math::Round<double>(extOverlayUpdateTemp[1][j] - translation[j]);
624 extOverlayUpdate[2*j+1] = w_ext[j]-1;
627 extOverlayUpdate[2*mCurrentSlicerManager->GetSlicer(i)->GetOrientation()] += mCurrentSlicerManager->GetSlicer(i)->GetSlice();
628 extOverlayUpdate[2*mCurrentSlicerManager->GetSlicer(i)->GetOrientation()+1] = extOverlayUpdate[2*mCurrentSlicerManager->GetSlicer(i)->GetOrientation()];
629 vtkSmartPointer<vtkOpenGLImageSliceMapper> mapperOpenGL= vtkSmartPointer<vtkOpenGLImageSliceMapper>::New();
631 mapperOpenGL = dynamic_cast<vtkOpenGLImageSliceMapper*>(mCurrentSlicerManager->GetSlicer(i)->GetOverlayActor()->GetMapper());
632 } catch (const std::bad_cast& e) {
633 std::cerr << e.what() << std::endl;
634 std::cerr << "Conversion error" << std::endl;
639 double spacing[4],spacingUpdate[4];
641 spacing[0] = 240*mCurrentSlicerManager->GetImage()->GetSpacing()[0]-centre[0];
642 spacing[1] = 179*mCurrentSlicerManager->GetImage()->GetSpacing()[1]-centre[1];
643 spacing[2] = 22*mCurrentSlicerManager->GetImage()->GetSpacing()[2]-centre[2];
645 matrixTranspose->MultiplyPoint(spacing, spacingUpdate);
646 spacingUpdate[0] = (spacingUpdate[0]+centre[0])/mCurrentSlicerManager->GetImage()->GetSpacing()[0];
647 spacingUpdate[1] = (spacingUpdate[1]+centre[1])/mCurrentSlicerManager->GetImage()->GetSpacing()[1];
648 spacingUpdate[2] = (spacingUpdate[2]+centre[2])/mCurrentSlicerManager->GetImage()->GetSpacing()[2];
649 cout << spacingUpdate[0] << " " << spacingUpdate[1] << " " << spacingUpdate[2] << endl;
650 sliceNumber = mCurrentSlicerManager->GetSlicer(i)->GetSlice()*spacingUpdate[mCurrentSlicerManager->GetSlicer(i)->GetOrientation()]/mCurrentSlicerManager->GetImage()->GetSpacing()[mCurrentSlicerManager->GetSlicer(i)->GetOrientation()];
651 extOverlayUpdate[2*mCurrentSlicerManager->GetSlicer(i)->GetOrientation()] = 12;//sliceNumber;
652 extOverlayUpdate[2*mCurrentSlicerManager->GetSlicer(i)->GetOrientation()+1] = 12;//sliceNumber;
654 mapperOpenGL->SetCroppingRegion(extOverlayUpdate);
657 mCurrentSlicerManager->GetSlicer(i)->ForceUpdateDisplayExtent();
658 mCurrentSlicerManager->GetSlicer(i)->Render();
661 //------------------------------------------------------------------------------