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://oncora1.lyon.fnclcc.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"
21 #include "vvImageReader.h"
25 #include <vtkImageData.h>
26 #include <vtkSmartPointer.h>
27 #include <vtkTransform.h>
30 #include "clitkTransformUtilities.h"
31 #include "clitkAffineRegistrationGenericFilter.h"
33 #include <QMessageBox>
34 #include <QFileDialog>
35 #include <QTextStream>
40 //------------------------------------------------------------------------------
41 // Create the tool and automagically (I like this word) insert it in
42 // the main window menu.
43 ADD_TOOL(vvToolRigidReg);
44 //------------------------------------------------------------------------------
46 //------------------------------------------------------------------------------
47 vvToolRigidReg::vvToolRigidReg(vvMainWindowBase * parent, Qt::WindowFlags f):
48 vvToolWidgetBase(parent, f),
49 vvToolBase<vvToolRigidReg>(parent),
53 Ui_vvToolRigidReg::setupUi(mToolWidget);
55 // qsize.setHeight(470);
56 // qsize.setWidth(850);
57 // mToolWidget->setFixedSize(qsize);
58 // Set how many inputs are needed for this tool
59 mFilter = new clitk::AffineRegistrationGenericFilter;
61 // Set how many inputs are needed for this tool
62 AddInputSelector("Select moving image",mFilter);
63 AddInputSelector("Select fixed image",mFilter);
65 //------------------------------------------------------------------------------
67 //------------------------------------------------------------------------------
68 vvToolRigidReg::~vvToolRigidReg()
71 //------------------------------------------------------------------------------
73 //------------------------------------------------------------------------------
74 bool vvToolRigidReg::close()
78 return vvToolWidgetBase::close();
80 //------------------------------------------------------------------------------
82 //------------------------------------------------------------------------------
83 void vvToolRigidReg::reject()
86 return vvToolWidgetBase::reject();
88 //------------------------------------------------------------------------------
90 //------------------------------------------------------------------------------
91 void vvToolRigidReg::GetArgsInfoFromGUI()
94 QFont font=QFont("Times New Roman",10);
95 tab2textedit->setTextColor(QColor(255,0,0));
96 tab2textedit->setCurrentFont(font);
97 tab2textedit->update();
99 QString file = QFileDialog::getOpenFileName(
101 "Choose the Transformation Parameters file",
102 mMainWindow->GetInputPathName(),
103 "Text (*.conf *.txt *.rtf *.doc)");
107 // ifstream readfile;
108 std::string configfile= file.toStdString();
109 cmdline_parser_clitkAffineRegistration_configfile(const_cast<char*>(configfile.c_str()),&mArgsInfo,1,1,1);
110 mArgsInfo.gradient_flag=1;
111 DD(mArgsInfo.matrix_arg);
113 //Read from File and display it on the TextBox 2
115 std::vector<QString> Qstr;
116 readfile.open(configfile.c_str());
117 if (readfile.is_open())
119 while (!readfile.eof())
121 readfile >> configfile;
122 Qstr.push_back(QString(configfile.c_str()));
127 cout << "Unable to open file";
129 for(unsigned int i=0;i<Qstr.size();i++)
131 str=tab2textedit->toPlainText();
132 str.append(Qstr.at(i));
133 tab2textedit->setText(str);
135 tab2textedit->setText(str);
139 //------------------------------------------------------------------------------
141 //------------------------------------------------------------------------------
142 void vvToolRigidReg::InitializeComboBox()
146 //------------------------------------------------------------------------------
148 //------------------------------------------------------------------------------
149 void vvToolRigidReg::InputIsSelected(std::vector<vvSlicerManager *> & l)
155 UpdateTextEditor(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix(),textEdit_2);
157 DD(*mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix());
158 for(int i =0;i<4;i++)
162 mInitialMatrix[i*4+j]=mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix()->GetElement(i,j);
166 if(mInput1->GetFileName()==mInput2->GetFileName())
168 QMessageBox::information(this, "Warning","Your Reference and Target Images are the same");
171 SetOverlay(mInput2->GetImage());
172 mImageSize=mInput1->GetImage()->GetSize();
176 //connect all sigs to slots
177 connect(resetbutton, SIGNAL(pressed()), this, SLOT(ResetTransform()));
178 connect(tab2loadbutton, SIGNAL(pressed()), this, SLOT(GetArgsInfoFromGUI()));
179 connect(tab2applybutton, SIGNAL(pressed()), this, SLOT(AutoRegister()));
182 connect(Xval, SIGNAL(editingFinished()), this, SLOT(SetXvalue()));
183 connect(Yval, SIGNAL(editingFinished()), this, SLOT(SetYvalue()));
184 connect(Zval, SIGNAL(editingFinished()), this, SLOT(SetZvalue()));
186 connect(xtrans_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
187 connect(ytrans_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
188 connect(ztrans_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
191 connect(xrot_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
192 connect(yrot_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
193 connect(zrot_slider, SIGNAL(valueChanged(int)), this, SLOT(UpdateTransform_sliders()));
195 connect(xtrans_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
196 connect(ytrans_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
197 connect(ztrans_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
198 connect(xrot_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
199 connect(yrot_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
200 connect(zrot_sb, SIGNAL(valueChanged(double)), this, SLOT(UpdateTransform_sb()));
202 connect(loadbutton, SIGNAL(pressed()), this, SLOT(ReadFile()));
203 connect(savebutton, SIGNAL(pressed()), this, SLOT(SaveFile()));
205 //------------------------------------------------------------------------------
207 //------------------------------------------------------------------------------
208 void vvToolRigidReg::apply()
212 //------------------------------------------------------------------------------
214 //------------------------------------------------------------------------------
215 void vvToolRigidReg::SetOverlay(vvImage::Pointer Image)
217 for (int i =0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
218 mCurrentSlicerManager->GetSlicer(i)->SetOverlay(Image);
219 mCurrentSlicerManager->GetSlicer(i)->SetActorVisibility("overlay",0,true);
220 mCurrentSlicerManager->SetColorMap();
221 mCurrentSlicerManager->Render();
224 //------------------------------------------------------------------------------
226 //------------------------------------------------------------------------------
227 void vvToolRigidReg::RemoveOverlay()
229 for(int i=0;i<mCurrentSlicerManager->NumberOfSlicers();i++)
231 mInput1->RemoveActor("overlay",0);
232 mInput1->SetColorMap(0);
237 //------------------------------------------------------------------------------
239 //------------------------------------------------------------------------------
240 void vvToolRigidReg::SetXvalue()
242 QString xstr = Xval->text();
244 //------------------------------------------------------------------------------
246 //------------------------------------------------------------------------------
247 void vvToolRigidReg::SetYvalue()
249 QString ystr = Yval->text();
251 //------------------------------------------------------------------------------
253 //------------------------------------------------------------------------------
254 void vvToolRigidReg::SetZvalue()
256 QString zstr = Zval->text();
258 //------------------------------------------------------------------------------
260 //------------------------------------------------------------------------------
261 void vvToolRigidReg::SetTransform(double tX, double tY, double tZ, double aX, double aY, double aZ,bool update)
263 vtkSmartPointer<vtkTransform> transform = mInput1->GetImage()->GetTransform();
264 transform->PostMultiply();
266 if (aX!=0 || aY!=0 || aZ!=0) {
268 x= Xval->text().toDouble();
269 y= Yval->text().toDouble();
270 z= Zval->text().toDouble();
271 transform->Translate(-x,-y,-z);
272 if (aX!=0) transform->RotateX(aX);
273 if (aY!=0) transform->RotateY(aY);
274 if (aZ!=0) transform->RotateZ(aZ);
275 transform->Translate(x,y,z);
278 if (tX!=0||tY!=0||tZ!=0)
279 transform->Translate(tX*mInput1->GetImage()->GetSpacing()[0],tY*mInput1->GetImage()->GetSpacing()[1],tZ*mInput1->GetImage()->GetSpacing()[2]);
281 //------------------------------------------------------------------------------
283 //------------------------------------------------------------------------------
284 void vvToolRigidReg::SetTransform(vtkMatrix4x4 *matrix)
286 vtkSmartPointer<vtkTransform> transform=vtkSmartPointer<vtkTransform>::New();
287 for(int i=0; i<4;i++)
289 mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix()->SetElement(i,j,matrix->GetElement(i,j));
293 //------------------------------------------------------------------------------
295 //------------------------------------------------------------------------------
296 void vvToolRigidReg::Render()
298 for (int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
299 mCurrentSlicerManager->GetSlicer(i)->ForceUpdateDisplayExtent();
300 mCurrentSlicerManager->GetSlicer(i)->Render();
303 //------------------------------------------------------------------------------
305 //------------------------------------------------------------------------------
306 void vvToolRigidReg::UpdateTextEditor(vtkMatrix4x4 *matrix,QTextEdit* textEdit)
308 QFont font=QFont("Times New Roman",11);
309 textEdit->setCurrentFont(font);
312 QString str1,str2,str3;
315 textEdit->setAcceptRichText(true);
316 str2=textEdit->toPlainText();
317 str2.append("#Rotation Center(mm): \n#");
318 textEdit->setText(str2);
320 str2=textEdit->toPlainText();
321 textEdit->setTextColor(QColor(255,0,0));
322 str2.append(str3.append(Xval->text()));
323 textEdit->setText(str2);
326 str2=textEdit->toPlainText();
328 textEdit->setText(str2);
330 str2=textEdit->toPlainText();
331 str2.append(str3.append(Yval->text()));
332 textEdit->setText(str2);
335 str2=textEdit->toPlainText();
337 textEdit->setText(str2);
340 str2=textEdit->toPlainText();
341 str2.append(str3.append(Zval->text()));
342 textEdit->setText(str2);
345 str2=textEdit->toPlainText();
347 textEdit->setText(str2);
350 str2=textEdit->toPlainText();
351 str2.append("#Transformation Matrix(mm):\n");
352 textEdit->setText(str2);
357 str2=textEdit->toPlainText();
358 // str2.append("\t"+str1.setNum(matrix->Element[i][j]));
359 str2.append(QString("%1\t").arg(str1.setNum(matrix->Element[i][j]),2));
360 textEdit->setText(str2);
362 str2=textEdit->toPlainText();
364 textEdit->setText(str2);
366 //QString str = QFileDialog::getOpenFileName();
367 textEdit->setTextColor(QColor(255,0,0));
368 textEdit->setFont(QFont("courrier new",12,4,true));
369 textEdit->toPlainText().toAscii();
371 str2=textEdit->toPlainText();
372 textEdit->setText(str2);
374 //------------------------------------------------------------------------------
376 //------------------------------------------------------------------------------
377 void vvToolRigidReg::UpdateTransform_sliders()
379 InitializeSliders(xtrans_slider->value()*mInput1->GetImage()->GetSpacing()[0],
380 ytrans_slider->value()*mInput1->GetImage()->GetSpacing()[1],
381 ztrans_slider->value()*mInput1->GetImage()->GetSpacing()[2],
382 xrot_slider->value(),yrot_slider->value(),zrot_slider->value(),false);
383 UpdateTransform(true);
386 //------------------------------------------------------------------------------
388 //------------------------------------------------------------------------------
389 void vvToolRigidReg::UpdateTransform_sb()
391 InitializeSliders(xtrans_sb->value(),
394 xrot_sb->value(),yrot_sb->value(),zrot_sb->value(),false);
395 UpdateTransform(false);
398 //------------------------------------------------------------------------------
400 //------------------------------------------------------------------------------
401 void vvToolRigidReg::AutoRegister()
403 if (!mCurrentSlicerManager) close();
404 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
405 std::vector<vvImage::Pointer> inputs;
407 inputs.push_back(mInput1->GetImage());
408 inputs.push_back(mInput2->GetImage());
411 clitk::AffineRegistrationGenericFilter::Pointer filter =
412 clitk::AffineRegistrationGenericFilter::New();
413 filter->SetInputVVImages(inputs);
414 filter->SetArgsInfo(mArgsInfo);
415 DD("ArgsInfo given in");
416 filter->EnableReadOnDisk(false);
418 DD("I am done...! Updated");
419 vvImage::Pointer output = filter->GetOutputVVImage();
420 DD("filter getoutput done...");
421 //osstream << "Registered" << "_ "
422 // << mCurrentSlicerManager->GetSlicer(0)->GetFileName() << ".mhd";
423 //AddImage(output,osstream.str());
424 QApplication::restoreOverrideCursor();
427 //------------------------------------------------------------------------------
429 //------------------------------------------------------------------------------
430 void vvToolRigidReg::UpdateTransform(bool slider_enabled)
432 vtkSmartPointer<vtkTransform> transform_final=vtkSmartPointer<vtkTransform>::New();
433 transform_final->SetMatrix(mInitialMatrix);
434 transform_final->PostMultiply();
436 double x=0, y=0 ,z=0;
437 x= Xval->text().toDouble();
438 y= Yval->text().toDouble();
439 z= Zval->text().toDouble();
440 transform_final->Translate(-x,-y,-z);
442 transform_final->RotateY(yrot_slider->value());
443 transform_final->RotateX(xrot_slider->value());
444 transform_final->RotateZ(zrot_slider->value());
447 transform_final->RotateY(yrot_sb->value());
448 transform_final->RotateX(xrot_sb->value());
449 transform_final->RotateZ(zrot_sb->value());
451 transform_final->Translate(x,y,z);
452 transform_final->PreMultiply();
454 transform_final->Translate(xtrans_slider->value()*mInput1->GetImage()->GetSpacing()[0],0,0);
455 transform_final->Translate(0,ytrans_slider->value()*mInput1->GetImage()->GetSpacing()[1],0);
456 transform_final->Translate(0,0,ztrans_slider->value()*mInput1->GetImage()->GetSpacing()[2]);
459 transform_final->Translate(xtrans_sb->value(),0,0);
460 transform_final->Translate(0,ytrans_sb->value(),0);
461 transform_final->Translate(0,0,ztrans_sb->value());
463 SetTransform(transform_final->GetMatrix());
464 UpdateTextEditor(transform_final->GetMatrix(),textEdit);
466 //------------------------------------------------------------------------------
469 //------------------------------------------------------------------------------
470 void vvToolRigidReg::SaveFile()
472 //Write the Transformation Matrix
473 QString f1 = QFileDialog::getSaveFileName(this, tr("Save Transformation Matrix File"),
474 mMainWindow->GetInputPathName(),
475 tr("Text (*.mat *.txt *.doc *.rtf)"));
477 std::vector<QString> transparameters;
480 for(int i =0;i<4;i++)
482 transparameters.push_back(line1.setNum(mCurrentSlicerManager->GetImage()->GetTransform()->GetMatrix()->Element[i][j]));
484 if (file1.open(QFile::WriteOnly | QFile::Truncate)) {
485 QTextStream out1(&file1);
486 for(int i =0;i<4;i++){
487 for(int j=0;j<4;j++) {
488 out1<<transparameters[i*4+j]+"\t";
495 QMessageBox::information(this,"Warning","Error Reading Parameters");
498 //------------------------------------------------------------------------------
500 //------------------------------------------------------------------------------
501 void vvToolRigidReg::ReadFile()
505 double * orientations=new double[3];
506 double * translations=new double[3];
507 vtkMatrix4x4 *matrix=vtkMatrix4x4::New();
508 vtkSmartPointer<vtkTransform> transform = mCurrentSlicerManager->GetImage()->GetTransform();
510 //Open File to read the transformation parameters
511 QString file1 = QFileDialog::getOpenFileName(
513 "Choose the Transformation Parameters file",
514 mMainWindow->GetInputPathName(),
515 "Text (*.mat *.txt *.rtf *.doc)");
519 // ifstream readfile;
520 std::string transfile= file1.toStdString();
521 std::string filename1(transfile);
522 std::ifstream f1(filename1.c_str());
526 itk::Matrix<double, 4, 4> itkMat = clitk::ReadMatrix3D(transfile);
527 for(int j=0; j<4; j++)
528 for(int i=0; i<4; i++)
529 matrix->SetElement(i,j,itkMat[i][j]);
531 UpdateTextEditor(matrix,textEdit);
532 transform->SetMatrix(matrix);
533 transform->GetOrientation(orientations);
534 transform->PostMultiply();
536 //Obtain the Rotation Center , set it to origin
537 Xval->setText(center.setNum(0));
538 Yval->setText(center.setNum(0));
539 Zval->setText(center.setNum(0));
541 //In the Order or Y X Z //
542 //now postmultiply for the rotations
543 SetTransform(0,0,0,0,0,-rint(orientations[2]),false);
544 SetTransform(0,0,0,-rint(orientations[0]),0,0,false);
545 SetTransform(0,0,0,0,-rint(orientations[1]),0,false);
547 transform->GetPosition(translations);
548 transform->Identity();
550 DD(translations[0]/mInput1->GetImage()->GetSpacing()[0]);
551 DD(translations[1]/mInput1->GetImage()->GetSpacing()[1]);
552 DD(translations[2]/mInput1->GetImage()->GetSpacing()[2]);
553 DD(mInput1->GetImage()->GetSpacing()[0]);
554 DD(mInput1->GetImage()->GetSpacing()[1]);
555 DD(mInput1->GetImage()->GetSpacing()[2]);
559 //set the sliders and spin box values
560 InitializeSliders(rint(translations[0]),rint(translations[1])
561 ,rint(translations[2]),rint(orientations[0]),rint(orientations[1]),rint(orientations[2]),true);
562 SetTransform(matrix);
564 //------------------------------------------------------------------------------
566 //------------------------------------------------------------------------------
567 void vvToolRigidReg::ResetTransform()
569 vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
572 matrix->SetElement(i,j,mInitialMatrix[i*4+j]);
573 SetTransform(matrix);
576 UpdateTextEditor(matrix,textEdit);
578 //------------------------------------------------------------------------------
580 //------------------------------------------------------------------------------
581 void vvToolRigidReg::SetRotationCenter()
583 //default image rotation center is the center of the image
584 QString xcord,ycord,zcord;
585 std::vector<double> imageorigin;
586 imageorigin=mInput1->GetImage()->GetOrigin();
588 xcord=xcord.setNum(imageorigin[0]+mImageSize[0]*mInput1->GetImage()->GetSpacing()[0]/2, 'g', 3);
589 ycord=ycord.setNum(imageorigin[1]+mImageSize[1]*mInput1->GetImage()->GetSpacing()[1]/2, 'g', 3);
590 zcord=zcord.setNum(imageorigin[2]+mImageSize[2]*mInput1->GetImage()->GetSpacing()[2]/2, 'g', 3);
592 Xval->setText(xcord);
593 Yval->setText(ycord);
594 Zval->setText(zcord);
595 InitializeSliders(0,0,0,0,0,0,true);
597 //------------------------------------------------------------------------------
599 //------------------------------------------------------------------------------
600 void vvToolRigidReg::InitializeSliders(double xtrans,double ytrans, double ztrans, double xrot, double yrot, double zrot,bool sliders)
603 xtrans_sb->blockSignals(true);
604 xtrans_sb->setSingleStep(mInput1->GetImage()->GetSpacing()[0]);
605 xtrans_sb->setValue(xtrans);
606 xtrans_sb->blockSignals(false);
607 ytrans_sb->blockSignals(true);
608 ytrans_sb->setSingleStep(mInput1->GetImage()->GetSpacing()[1]);
609 ytrans_sb->setValue(ytrans);
610 ytrans_sb->blockSignals(false);
611 ztrans_sb->blockSignals(true);
612 ztrans_sb->setSingleStep(mInput1->GetImage()->GetSpacing()[2]);
613 ztrans_sb->setValue(ztrans);
614 ztrans_sb->blockSignals(false);
618 xtrans_slider->blockSignals(true);
619 xtrans_slider->setValue(rint(xtrans/mInput1->GetImage()->GetSpacing()[0]));
620 xtrans_slider->blockSignals(false);
621 ytrans_slider->blockSignals(true);
622 ytrans_slider->setValue(rint(ytrans/mInput1->GetImage()->GetSpacing()[1]));
623 ytrans_slider->blockSignals(false);
624 ztrans_slider->blockSignals(true);
625 ztrans_slider->setValue(rint(ztrans/mInput1->GetImage()->GetSpacing()[2]));
626 ztrans_slider->blockSignals(false);
628 xrot_sb->blockSignals(true);
629 xrot_sb->setValue(xrot);
630 xrot_sb->blockSignals(false);
631 yrot_sb->blockSignals(true);
632 yrot_sb->setValue(yrot);
633 yrot_sb->blockSignals(false);
634 zrot_sb->blockSignals(true);
635 zrot_sb->setValue(zrot);
636 zrot_sb->blockSignals(false);
637 xrot_slider->blockSignals(true);
638 xrot_slider->setValue(xrot);
639 xrot_slider->blockSignals(false);
640 yrot_slider->blockSignals(true);
641 yrot_slider->setValue(yrot);
642 yrot_slider->blockSignals(false);
643 zrot_slider->blockSignals(true);
644 zrot_slider->setValue(zrot);
645 zrot_slider->blockSignals(false);
647 //------------------------------------------------------------------------------
649 //------------------------------------------------------------------------------
650 void vvToolRigidReg::SetSliderRanges()
652 xtrans_slider->blockSignals(true);
653 xtrans_slider->setRange(-2000,2000);
654 xtrans_slider->blockSignals(false);
656 ytrans_slider->blockSignals(true);
657 ytrans_slider->setRange(-2000,2000);
658 ytrans_slider->blockSignals(false);
660 ztrans_slider->blockSignals(true);
661 ztrans_slider->setRange(-2000,2000);
662 ztrans_slider->blockSignals(false);
664 xtrans_sb->blockSignals(true);
665 xtrans_sb->setRange(-2000,2000);
666 xtrans_sb->setDecimals(3);
667 xtrans_sb->blockSignals(false);
669 ytrans_sb->blockSignals(true);
670 ytrans_sb->setRange(-2000,2000);
671 ytrans_sb->setDecimals(3);
672 ytrans_sb->blockSignals(false);
674 ztrans_sb->blockSignals(true);
675 ztrans_sb->setRange(-2000,2000);
676 ztrans_sb->setDecimals(3);
677 ztrans_sb->blockSignals(false);
679 xrot_slider->blockSignals(true);
680 xrot_slider->setRange(-360,360);
681 xrot_slider->blockSignals(false);
683 yrot_slider->blockSignals(true);
684 yrot_slider->setRange(-360,360);
685 yrot_slider->blockSignals(false);
687 zrot_slider->blockSignals(true);
688 zrot_slider->setRange(-360,360);
689 zrot_slider->blockSignals(false);
691 xrot_sb->blockSignals(true);
692 xrot_sb->setRange(-360,360);
693 xrot_sb->blockSignals(false);
695 yrot_sb->blockSignals(true);
696 yrot_sb->setRange(-360,360);
697 yrot_sb->blockSignals(false);
699 zrot_sb->blockSignals(true);
700 zrot_sb->setRange(-360,360);
701 zrot_sb->blockSignals(false);