]> Creatis software - clitk.git/blob - vv/vvToolRigidReg.cxx
Merge branch 'master' into VTK6_Qt5
[clitk.git] / vv / vvToolRigidReg.cxx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to:
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
8
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.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
18
19 // vv
20 #include "vvToolRigidReg.h"
21 #include "vvSlicer.h"
22
23 // vtk
24 #include <vtkImageData.h>
25 #include <vtkSmartPointer.h>
26 #include <vtkInformation.h>
27 #include <vtkTransform.h>
28 #include <vtkImageActor.h>
29 #include <vtkImageMapper3D.h>
30 #include <vtkOpenGLImageSliceMapper.h>
31
32 // itk
33 #include <itkEuler3DTransform.h>
34
35 // clitk
36 #include "clitkTransformUtilities.h"
37 #include "clitkMatrix.h"
38
39 // qt
40 #include <QMessageBox>
41 #include <QFileDialog>
42 #include <QTextStream>
43
44
45 //------------------------------------------------------------------------------
46 // Create the tool and automagically (I like this word) insert it in
47 // the main window menu.
48 ADD_TOOL(vvToolRigidReg);
49 //------------------------------------------------------------------------------
50
51 //------------------------------------------------------------------------------
52 vvToolRigidReg::vvToolRigidReg(vvMainWindowBase * parent, Qt::WindowFlags f):
53     vvToolWidgetBase(parent, f),
54     vvToolBase<vvToolRigidReg>(parent),
55     Ui::vvToolRigidReg()
56 {
57   // GUI Initialization
58   Ui_vvToolRigidReg::setupUi(mToolWidget);
59   
60   // Set how many inputs are needed for this tool
61   AddInputSelector("Select moving image");
62
63   QFont font = transformationLabel->font();
64   font.setStyleHint(QFont::TypeWriter);
65   transformationLabel->setFont(font);
66
67   mInitialMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
68
69   // Set slider ranges, assume degrees, will not be changed for radians
70   std::vector<QSlider *> transSliders, rotSliders;
71   std::vector<QDoubleSpinBox *> transSBs, rotSBs;
72   GetSlidersAndSpinBoxes(transSliders, rotSliders, transSBs, rotSBs);
73   for(int i=0; i<3; i++) {
74     transSliders[i]->setRange(-2000,2000);
75     rotSliders[i]->setRange(-360,360);
76     transSBs[i]->setRange(-2000,2000);
77     transSBs[i]->setDecimals(3);
78     rotSBs[i]->setRange(-360,360);
79     rotSBs[i]->setDecimals(3);
80   }
81 }
82 //------------------------------------------------------------------------------
83
84 //------------------------------------------------------------------------------
85 vvToolRigidReg::~vvToolRigidReg()
86 {
87 }
88 //------------------------------------------------------------------------------
89
90 //------------------------------------------------------------------------------
91 void vvToolRigidReg::Initialize()
92 {
93   SetToolName("Register");
94   SetToolMenuName("Register manually");
95   SetToolIconFilename(":/common/icons/register.png");
96   SetToolTip("Register manually.");
97   SetToolExperimental(false);
98 }
99 //------------------------------------------------------------------------------
100
101 //------------------------------------------------------------------------------
102 void vvToolRigidReg::InputIsSelected(vvSlicerManager *input)
103 {
104   mInput = input;
105   HideInputSelector();
106   QTabWidget * tab = dynamic_cast<vvMainWindow*>(mMainWindow)->GetTab();
107   move(tab->mapToGlobal(tab->pos()));
108   resize(tab->width(), 0);
109
110   //default image rotation center is the center of the image
111   QString xcord,ycord,zcord;
112   std::vector<double> imageorigin;
113   imageorigin=mInput->GetImage()->GetOrigin();
114   std::vector<int> imageSize = mInput->GetImage()->GetSize();
115   std::vector<double> imageSpacing = mInput->GetImage()->GetSpacing();
116   xcord=xcord.setNum(imageorigin[0]+(imageSize[0]-1)*imageSpacing[0]*0.5, 'g', 3);
117   ycord=ycord.setNum(imageorigin[1]+(imageSize[1]-1)*imageSpacing[1]*0.5, 'g', 3);
118   zcord=zcord.setNum(imageorigin[2]+(imageSize[2]-1)*imageSpacing[2]*0.5, 'g', 3);
119   Xval->setText(xcord);
120   Yval->setText(ycord);
121   Zval->setText(zcord);
122
123   //backup original matrix
124   for(int j=0; j<4; j++)
125     for(int i=0; i<4; i++)
126       // TODO SR and BP: check on the list of transforms and not the first only
127       mInitialMatrix->SetElement(i,j, mCurrentSlicerManager->GetImage()->GetTransform()[0]->GetMatrix()->GetElement(i,j));
128   QString origTransformString(clitk::Get4x4MatrixDoubleAsString(mInitialMatrix).c_str());
129   transformationLabel->setText(origTransformString);
130   SetTransform(mInitialMatrix);
131
132   //connect all sigs to slots
133   connect(resetbutton, SIGNAL(pressed()), this, SLOT(ResetTransform()));
134   connect(loadbutton, SIGNAL(pressed()), this, SLOT(LoadFile()));
135   connect(savebutton, SIGNAL(pressed()), this, SLOT(SaveFile()));
136
137   connect(xtrans_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
138   connect(ytrans_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
139   connect(ztrans_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
140   connect(xrot_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
141   connect(yrot_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
142   connect(zrot_slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChange(int)));
143   connect(xtrans_sb, SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
144   connect(ytrans_sb, SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
145   connect(ztrans_sb, SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
146   connect(xrot_sb,   SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
147   connect(yrot_sb,   SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
148   connect(zrot_sb,   SIGNAL(valueChanged(double)), this, SLOT(SpinBoxChange(double)));
149
150   connect(stepTransSpinBox, SIGNAL(valueChanged(double)), this, SLOT(SetTranslationStep(double)));
151   connect(stepRotSpinBox, SIGNAL(valueChanged(double)), this, SLOT(SetRotationStep(double)));
152
153   connect(checkBoxDegrees, SIGNAL(stateChanged(int)), this, SLOT(ToggleSpinBoxAnglesUnit()));
154
155   connect(Xval, SIGNAL(editingFinished()), this, SLOT(ChangeOfRotationCenter()));
156   connect(Yval, SIGNAL(editingFinished()), this, SLOT(ChangeOfRotationCenter()));
157   connect(Zval, SIGNAL(editingFinished()), this, SLOT(ChangeOfRotationCenter()));
158
159   // Init step modifiers
160   stepTransSpinBox->setValue(1.);
161   stepRotSpinBox->setValue(1.);
162 }
163 //------------------------------------------------------------------------------
164
165 //------------------------------------------------------------------------------
166 void vvToolRigidReg::apply()
167 {
168   vvToolWidgetBase::close();
169 }
170 //------------------------------------------------------------------------------
171
172 //------------------------------------------------------------------------------
173 bool vvToolRigidReg::close()
174 {
175   QString warning = "Are you sure you want to reset the original transform?";
176   QMessageBox msgBox(QMessageBox::Warning, tr("Reset transform"),warning, 0, this);
177   msgBox.addButton(tr("Yes"), QMessageBox::AcceptRole);
178   msgBox.addButton(tr("No"), QMessageBox::RejectRole);
179   if (msgBox.exec() == QMessageBox::AcceptRole) {
180     SetTransform(mInitialMatrix);
181     return vvToolWidgetBase::close();
182   }
183   return false;
184 }
185 //------------------------------------------------------------------------------
186
187 //------------------------------------------------------------------------------
188 void vvToolRigidReg::reject()
189 {
190   return vvToolWidgetBase::reject();
191 }
192 //------------------------------------------------------------------------------
193
194 //------------------------------------------------------------------------------
195 void vvToolRigidReg::SetTranslationStep(double v)
196 {
197   xtrans_sb->setSingleStep(v);
198   ytrans_sb->setSingleStep(v);
199   ztrans_sb->setSingleStep(v);
200 }
201 //------------------------------------------------------------------------------
202
203 //------------------------------------------------------------------------------
204 void vvToolRigidReg::SetRotationStep(double v)
205 {
206   xrot_sb->setSingleStep(v);
207   yrot_sb->setSingleStep(v);
208   zrot_sb->setSingleStep(v);
209 }
210 //------------------------------------------------------------------------------
211
212 //------------------------------------------------------------------------------
213 void vvToolRigidReg::SliderChange(int newVal)
214 {
215   std::vector<QSlider *> transSliders, rotSliders;
216   std::vector<QDoubleSpinBox *> transSBs, rotSBs;
217   GetSlidersAndSpinBoxes(transSliders, rotSliders, transSBs, rotSBs);
218   for(int i=0; i<3; i++) {
219     if(transSliders[i] == QObject::sender()) {
220       transSBs[i]->setValue(newVal);
221     }
222     if(rotSliders[i] == QObject::sender()) {
223       double rad = (checkBoxDegrees->checkState()==Qt::Unchecked)?itk::Math::pi/180.:1.;
224       rotSBs[i]->setValue(newVal*rad);
225     }
226   }
227 }
228 //------------------------------------------------------------------------------
229
230 //------------------------------------------------------------------------------
231 void vvToolRigidReg::SpinBoxChange(double newVal)
232 {
233   std::vector<QSlider *> transSliders, rotSliders;
234   std::vector<QDoubleSpinBox *> transSBs, rotSBs;
235   GetSlidersAndSpinBoxes(transSliders, rotSliders, transSBs, rotSBs);
236   for(int i=0; i<3; i++) {
237     if(transSBs[i] == QObject::sender()) {
238       transSliders[i]->blockSignals(true);
239       transSliders[i]->setValue(itk::Math::Round<double,double>(newVal));
240       transSliders[i]->blockSignals(false);
241     }
242     if(rotSBs[i] == QObject::sender()) {
243       double rad = (checkBoxDegrees->checkState()==Qt::Unchecked)?180./itk::Math::pi:1.;
244       rotSliders[i]->blockSignals(true);
245       rotSliders[i]->setValue(itk::Math::Round<double,double>(newVal*rad));
246       rotSliders[i]->blockSignals(false);
247     }
248   }
249
250   // Compute transform and set
251   // TODO SR and BP: check on the list of transforms and not the first only
252   vtkSmartPointer<vtkTransform> transform_final=mInput->GetImage()->GetTransform()[0];
253   transform_final->Identity();
254   transform_final->PostMultiply();
255
256   // Rotations
257   double x=0, y=0 ,z=0;
258   x= Xval->text().toDouble();
259   y= Yval->text().toDouble();
260   z= Zval->text().toDouble();
261   double rad = (checkBoxDegrees->checkState()==Qt::Unchecked)?180./itk::Math::pi:1.;
262   transform_final->Translate(-x,-y,-z);
263   transform_final->RotateY(yrot_sb->value()*rad);
264   transform_final->RotateX(xrot_sb->value()*rad);
265   transform_final->RotateZ(zrot_sb->value()*rad);
266   transform_final->Translate(x,y,z);
267
268   // Translation
269   transform_final->Translate(xtrans_sb->value(),
270                              ytrans_sb->value(),
271                              ztrans_sb->value());
272   transform_final->Update();
273   SetTransform(transform_final->GetMatrix());
274 }
275 //------------------------------------------------------------------------------
276
277 //------------------------------------------------------------------------------
278 void vvToolRigidReg::ToggleSpinBoxAnglesUnit()
279 {
280   double rad = (checkBoxDegrees->checkState()==Qt::Unchecked)?itk::Math::pi/180.:180./itk::Math::pi;
281   std::vector<QSlider *> transSliders, rotSliders;
282   std::vector<QDoubleSpinBox *> transSBs, rotSBs;
283   GetSlidersAndSpinBoxes(transSliders, rotSliders, transSBs, rotSBs);
284   for(int i=0; i<3; i++) {
285     rotSBs[i]->blockSignals(true);
286     rotSBs[i]->setValue(rotSBs[i]->value()*rad);
287     rotSBs[i]->blockSignals(false);
288   }
289 }
290 //------------------------------------------------------------------------------
291
292 //------------------------------------------------------------------------------
293 void vvToolRigidReg::SaveFile()
294 {
295   //Write the Transformation Matrix
296   std::string absPath = mCurrentSlicerManager->GetFileName();
297   absPath = itksys::SystemTools::GetFilenameWithoutExtension(absPath) + std::string(".mat");
298   QString filename = QFileDialog::getSaveFileName(this, tr("Save Transformation Matrix File"),
299                                             absPath.c_str(),
300                                             tr("Text (*.mat *.txt *.doc *.rtf)"));
301
302   QFile file(filename);
303   if (file.open(QFile::WriteOnly | QFile::Truncate)) {
304     // TODO SR and BP: check on the list of transforms and not the first only
305     vtkMatrix4x4* matrix = mCurrentSlicerManager->GetImage()->GetTransform()[0]->GetMatrix();
306     QString matrixStr = clitk::Get4x4MatrixDoubleAsString(matrix,16).c_str();
307     QTextStream out(&file);
308     out << matrixStr;
309   }
310   else
311   {
312     QMessageBox::information(this,"Error","Unable to open file for writing");
313   }
314 }
315 //------------------------------------------------------------------------------
316
317 //------------------------------------------------------------------------------
318 void vvToolRigidReg::LoadFile()
319 {
320   //Open File to read the transformation parameters
321   QString file = QFileDialog::getOpenFileName(
322                    this,
323                    "Choose the filename for the transformation matrix",
324                    vtksys::SystemTools::GetFilenamePath(mCurrentSlicerManager->GetFileName()).c_str(),
325                    "Text (*.mat *.txt *.rtf *.doc)");
326    if (file.isEmpty())
327      return;
328
329
330   itk::Matrix<double, 4, 4> itkMat = clitk::ReadMatrix3D(file.toStdString());
331   vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
332   matrix->Identity();
333   for(int j=0; j<4; j++)
334     for(int i=0; i<4; i++)
335       matrix->SetElement(j,i,itkMat[j][i]);
336   SetTransform(matrix);
337 }
338 //------------------------------------------------------------------------------
339   
340 //------------------------------------------------------------------------------
341 void vvToolRigidReg::ChangeOfRotationCenter()
342 {
343   // TODO SR and BP: check on the list of transforms and not the first only
344   SetTransform(mCurrentSlicerManager->GetImage()->GetTransform()[0]->GetMatrix());
345 }
346 //------------------------------------------------------------------------------
347
348 //------------------------------------------------------------------------------
349 void vvToolRigidReg::ResetTransform()
350 {
351   SetTransform(mInitialMatrix);
352 }
353 //------------------------------------------------------------------------------
354
355 //------------------------------------------------------------------------------
356 void vvToolRigidReg::SetTransform(vtkMatrix4x4 *matrix)
357 {
358   vtkSmartPointer<vtkTransform> transform=vtkSmartPointer<vtkTransform>::New();
359   // TODO SR and BP: check on the list of transforms and not the first only
360   mCurrentSlicerManager->GetImage()->GetTransform()[0]->SetMatrix(matrix);
361   transform->Update();
362   Render();
363   dynamic_cast<vvMainWindow*>(mMainWindow)->ImageInfoChanged();
364
365   // Compute parameters from transfer using itk Euler transform
366   itk::Euler3DTransform<double>::CenterType center;
367   center[0] = Xval->text().toDouble();
368   center[1] = Yval->text().toDouble();
369   center[2] = Zval->text().toDouble();
370   itk::Euler3DTransform<double>::MatrixType rotMat;
371   itk::Euler3DTransform<double>::OutputVectorType transVec;
372   for(int i=0; i<3; i++) {
373     transVec[i] = matrix->GetElement(i,3);
374     for(int j=0; j<3; j++)
375       rotMat[i][j] = matrix->GetElement(i,j);
376   }
377   itk::Euler3DTransform<double>::Pointer euler;
378   euler = itk::Euler3DTransform<double>::New();
379   euler->SetCenter(center);
380   euler->SetMatrix(rotMat);
381   euler->SetOffset(transVec);
382
383   // Modify GUI according to the new parameters
384   std::vector<QSlider *> transSliders, rotSliders;
385   std::vector<QDoubleSpinBox *> transSBs, rotSBs;
386   GetSlidersAndSpinBoxes(transSliders, rotSliders, transSBs, rotSBs);
387   for(int i=0; i<3; i++) {
388     // Translations
389     transSBs[i]->blockSignals(true);
390     transSBs[i]->setValue( euler->GetParameters()[i+3] );
391     transSBs[i]->blockSignals(false);
392     transSliders[i]->blockSignals(true);
393     transSliders[i]->setValue( itk::Math::Round<double,double>(euler->GetParameters()[i+3]) );
394     transSliders[i]->blockSignals(false);
395
396     // Rotations
397     double rad = (checkBoxDegrees->checkState()==Qt::Checked)?180./itk::Math::pi:1.;
398     double angleDiff = euler->GetParameters()[i]-rotSBs[i]->value()/rad+2*itk::Math::pi;
399     angleDiff = angleDiff - 2*itk::Math::pi*itk::Math::Round<double,double>(angleDiff/(2*itk::Math::pi));
400     if(angleDiff>1.e-4) {
401       rotSBs[i]->blockSignals(true);
402       rotSBs[i]->setValue( euler->GetParameters()[i]*rad );
403       rotSBs[i]->blockSignals(false);
404     }
405     int iAngle = itk::Math::Round<int,double>(euler->GetParameters()[i]*180./itk::Math::pi);
406     if((iAngle-rotSliders[i]->value()+360)%360!=0) {
407       rotSliders[i]->blockSignals(true);
408       rotSliders[i]->setValue(iAngle);
409       rotSliders[i]->blockSignals(false);
410     }
411   }
412 }
413 //------------------------------------------------------------------------------
414
415 //------------------------------------------------------------------------------
416 // Just an helper function to shorten the code with loops on sliders and spinboxes
417 void vvToolRigidReg::GetSlidersAndSpinBoxes(std::vector<QSlider *>&transSliders, std::vector<QSlider *>&rotSliders,
418                                             std::vector<QDoubleSpinBox *>&transSBs, std::vector<QDoubleSpinBox *>&rotSBs)
419 {
420   transSliders.push_back(xtrans_slider);
421   transSliders.push_back(ytrans_slider);
422   transSliders.push_back(ztrans_slider);
423
424   rotSliders.push_back(xrot_slider);
425   rotSliders.push_back(yrot_slider);
426   rotSliders.push_back(zrot_slider);
427
428   transSBs.push_back(xtrans_sb);
429   transSBs.push_back(ytrans_sb);
430   transSBs.push_back(ztrans_sb);
431
432   rotSBs.push_back(xrot_sb);
433   rotSBs.push_back(yrot_sb);
434   rotSBs.push_back(zrot_sb);
435 }
436 //------------------------------------------------------------------------------
437
438 //------------------------------------------------------------------------------
439 void vvToolRigidReg::ExtentMax(const double pointExtent[8][4], double maxExtent[2][3])
440 {
441     double max, min;
442     for (int i=0; i<3; ++i) {
443         max = pointExtent[0][i];
444         min = pointExtent[0][i];
445         for (int j=1; j<8; ++j) {
446             if (pointExtent[j][i] > max) {
447                 max = pointExtent[j][i];
448             }
449             if (pointExtent[j][i] < min) {
450                 min = pointExtent[j][i];
451             }
452         }
453         maxExtent[0][i] = min;
454         maxExtent[1][i] = max;
455     }
456 }
457 //------------------------------------------------------------------------------
458
459 //------------------------------------------------------------------------------
460 void vvToolRigidReg::Render()
461 { //out << __func__ << endl;
462 #if VTK_MAJOR_VERSION > 5
463 vtkMatrix4x4* matrix = mCurrentSlicerManager->GetImage()->GetTransform()[0]->GetMatrix();
464 vtkMatrix4x4* matrixTranspose = matrix->NewInstance();
465 for (int i=0; i<3; ++i) {
466     for (int j=0; j<3; ++j)
467     {
468         matrixTranspose->SetElement(i,j,matrix->GetElement(j,i));
469     }
470 }
471 for (int i=0; i<4; ++i) {
472    matrixTranspose->SetElement(3,i,matrix->GetElement(3,i));
473 }
474 for (int i=0; i<4; ++i) {
475    matrixTranspose->SetElement(i,3,matrix->GetElement(i,3));
476 }
477 #endif
478   for (int i=0; i<mCurrentSlicerManager->GetNumberOfSlicers(); i++)
479     {
480 #if VTK_MAJOR_VERSION > 5 
481     double pointExtent[8][4], pointExtentUpdate[8][4];
482     std::vector<int> w_ext;
483     w_ext=mCurrentSlicerManager->GetImage()->GetSize();
484     pointExtent[0][0] = 0.0;
485         pointExtent[0][1] = 0.0;
486         pointExtent[0][2] = 0.0;
487         pointExtent[0][3] = 1.0;
488     pointExtent[1][0] = w_ext[0]-1;
489         pointExtent[1][1] = w_ext[1]-1;
490         pointExtent[1][2] = w_ext[2]-1;
491         pointExtent[1][3] = 1.0;
492         pointExtent[2][0] = 0.0;
493         pointExtent[2][1] = w_ext[1]-1;
494         pointExtent[2][2] = w_ext[2]-1;
495         pointExtent[2][3] = 1.0;
496         pointExtent[3][0] = w_ext[0]-1;
497         pointExtent[3][1] = 0.0;
498         pointExtent[3][2] = w_ext[2]-1;
499         pointExtent[3][3] = 1.0;
500         pointExtent[4][0] = w_ext[0]-1;
501         pointExtent[4][1] = w_ext[1]-1;
502         pointExtent[4][2] = 0.0;
503         pointExtent[4][3] = 1.0;
504         pointExtent[5][0] = 0.0;
505         pointExtent[5][1] = 0.0;
506         pointExtent[5][2] = w_ext[2]-1;
507         pointExtent[5][3] = 1.0;
508         pointExtent[6][0] = 0.0;
509         pointExtent[6][1] = w_ext[1]-1;
510         pointExtent[6][2] = 0.0;
511         pointExtent[6][3] = 1.0;
512         pointExtent[7][0] = w_ext[0]-1;
513         pointExtent[7][1] = 0.0;
514         pointExtent[7][2] = 0.0;
515         pointExtent[7][3] = 1.0;
516         
517         for (int k=0; k<8; ++k) {
518             for (int j=0; j<3; ++j)
519             {
520                 pointExtent[k][j] = mCurrentSlicerManager->GetImage()->GetOrigin()[j] + mCurrentSlicerManager->GetImage()->GetSpacing()[j] * pointExtent[k][j];
521             }
522             matrixTranspose->MultiplyPoint(pointExtent[k], pointExtentUpdate[k]);
523                 for (int j=0; j<3; ++j)
524             {
525                 pointExtentUpdate[k][j] = (pointExtentUpdate[k][j] - mCurrentSlicerManager->GetImage()->GetOrigin()[j])/mCurrentSlicerManager->GetImage()->GetSpacing()[j];
526             }
527     }
528 double extUpdateTemp[2][3];
529 int extUpdate[6];
530 ExtentMax(pointExtentUpdate, extUpdateTemp);
531 for (int j=0; j<3; ++j) {
532     extUpdate[2*j] = 0;
533     extUpdate[2*j+1] = itk::Math::Round<double>(extUpdateTemp[1][j] - extUpdateTemp[0][j]);
534 }
535     mCurrentSlicerManager->GetSlicer(i)->SetRegisterExtent(extUpdate);
536     extUpdate[2*mCurrentSlicerManager->GetSlicer(i)->GetOrientation()] = mCurrentSlicerManager->GetSlicer(i)->GetSlice();
537     extUpdate[2*mCurrentSlicerManager->GetSlicer(i)->GetOrientation()+1] = mCurrentSlicerManager->GetSlicer(i)->GetSlice();
538     
539     vtkSmartPointer<vtkOpenGLImageSliceMapper> mapperOpenGL= vtkSmartPointer<vtkOpenGLImageSliceMapper>::New();
540     try {
541         mapperOpenGL = dynamic_cast<vtkOpenGLImageSliceMapper*>(mCurrentSlicerManager->GetSlicer(i)->GetImageActor()->GetMapper());
542     } catch (const std::bad_cast& e) {
543                 std::cerr << e.what() << std::endl;
544                 std::cerr << "Conversion error" << std::endl;
545                 return;
546         }
547         mapperOpenGL->SetCroppingRegion(extUpdate);
548 #endif
549     mCurrentSlicerManager->GetSlicer(i)->ForceUpdateDisplayExtent();
550     mCurrentSlicerManager->GetSlicer(i)->Render();
551     }
552 }
553 //------------------------------------------------------------------------------
554