]> Creatis software - clitk.git/blob - vv/vvToolProfile.cxx
Debug RTStruct conversion with empty struc
[clitk.git] / vv / vvToolProfile.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 #include <QFileDialog>
20 #include <QShortcut>
21
22 #include <algorithm>
23
24 // vv
25 #include "vvToolProfile.h"
26 #include "vvProgressDialog.h"
27 #include "vvSlicerManager.h"
28 #include "vvSlicer.h"
29 #include "vvToolInputSelectorWidget.h"
30
31 // vtk
32 #include <vtkAxis.h>
33 #include <vtkImageActor.h>
34 #include <vtkCamera.h>
35 #include <vtkImageClip.h>
36 #include <vtkRenderWindow.h>
37 #include <vtkChartXY.h>
38 #include <vtkPlot.h>
39 #include <vtkRendererCollection.h>
40 #include <vtkRenderer.h>
41
42 #include <vtkLine.h>
43 #include <vtkCellArray.h>
44 #include <vtkCellData.h>
45 #include <vtkPolyDataMapper.h>
46 #include <vtkProperty.h>
47 #include <vtkBox.h>
48 #include <vtkInformation.h>
49
50 #ifdef Q_OS_OSX
51 # include "vvOSXHelper.h"
52 #endif
53
54 //------------------------------------------------------------------------------
55 // Create the tool and automagically (I like this word) insert it in
56 // the main window menu.
57 ADD_TOOL(vvToolProfile);
58 //------------------------------------------------------------------------------
59
60
61 //------------------------------------------------------------------------------
62 void vvToolProfile::Initialize()
63
64   SetToolName("Profile");
65   SetToolMenuName("Intensity Profile");
66   SetToolIconFilename(":/common/icons/profile.png");
67   SetToolTip("Display the intensity profile between 2 points of the image.");
68   SetToolExperimental(false);
69 }
70 //------------------------------------------------------------------------------
71
72
73 //------------------------------------------------------------------------------
74 vvToolProfile::vvToolProfile(vvMainWindowBase * parent, Qt::WindowFlags f)
75   :vvToolWidgetBase(parent,f),
76    vvToolBase<vvToolProfile>(parent),
77    Ui::vvToolProfile()
78
79   // GUI Initialization
80   Ui_vvToolProfile::setupUi(mToolWidget);
81   
82   QShortcut *shortcutPoint1 = new QShortcut(QKeySequence("Ctrl+1"), parent);
83   shortcutPoint1->setContext(Qt::ApplicationShortcut);
84   QObject::connect(shortcutPoint1, SIGNAL(activated()), this, SLOT(selectPoint1()));
85   QShortcut *shortcutPoint2 = new QShortcut(QKeySequence("Ctrl+2"), parent);
86   shortcutPoint2->setContext(Qt::ApplicationShortcut);
87   QObject::connect(shortcutPoint2, SIGNAL(activated()), this, SLOT(selectPoint2()));
88
89   // Connect signals & slots
90   connect(mSelectPoint1Button, SIGNAL(clicked()), this, SLOT(selectPoint1()));
91   connect(mSelectPoint2Button, SIGNAL(clicked()), this, SLOT(selectPoint2()));
92   connect(mCancelPointsButton, SIGNAL(clicked()), this, SLOT(cancelPoints()));
93   connect(mSaveProfileButton, SIGNAL(clicked()), this, SLOT(SaveAs()));
94
95   // Initialize some widget
96   ProfileWidget->hide();
97   mPoint1 = NULL;
98   mPoint2 = NULL;
99   
100   mPoint1Selected = false;
101   mPoint2Selected = false;
102     
103   mView = vtkSmartPointer<vtkContextView>::New();
104   vtkSmartPointer<vtkChartXY> chart = vtkSmartPointer<vtkChartXY>::New();
105   chart->SetAutoSize(false);
106   chart->SetRenderEmpty(true);
107   mView->GetScene()->AddItem(chart);
108   this->ProfileWidget->GetRenderWindow()->GetRenderers()->RemoveAllItems();
109   this->ProfileWidget->GetRenderWindow()->AddRenderer(mView->GetRenderer());
110   ProfileWidget->show();
111
112 #ifdef Q_OS_OSX
113   disableGLHiDPI(ProfileWidget->winId());
114 #endif
115
116   // Main filter
117   mFilter = clitk::ProfileImageGenericFilter::New();
118
119   // Set how many inputs are needed for this tool
120   AddInputSelector("Select one image", mFilter);
121 }
122 //------------------------------------------------------------------------------
123
124
125 //------------------------------------------------------------------------------
126 vvToolProfile::~vvToolProfile()
127
128   delete [] mPoint1;
129   delete [] mPoint2;
130 }
131 //------------------------------------------------------------------------------
132
133
134 //------------------------------------------------------------------------------
135 void vvToolProfile::selectPoint1()
136 {
137   QString position = "";
138   
139   if(mCurrentSlicerManager) {
140     if (mPoint1Selected) {
141       ProfileWidget->hide();
142       vtkSmartPointer<vtkChartXY> chart = vtkSmartPointer<vtkChartXY>::New();
143       chart->SetAutoSize(false);
144       chart->SetRenderEmpty(true);
145       mView->GetScene()->ClearItems();
146       mView->GetScene()->AddItem(chart);
147       this->ProfileWidget->GetRenderWindow()->GetRenderers()->RemoveAllItems();
148       this->ProfileWidget->GetRenderWindow()->AddRenderer(mView->GetRenderer());
149       ProfileWidget->show();
150       mCurrentSlicerManager->GetLandmarks()->RemoveLandmarkWithLabel("P1", mPoint1[3]);
151     }
152   
153     mPoint1Selected = false;
154
155     if(mCurrentSlicerManager->GetSelectedSlicer() != -1) {
156       double *pos;
157       pos = new double [4];
158       pos[0] = pos[1] = pos[2] = pos[3] = 0;
159           
160       int i(0);
161       while (i<mCurrentSlicerManager->GetImage()->GetNumberOfDimensions() && i<3) {
162         pos[i] = mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetCursorPosition()[i];
163         ++i;
164       }
165       double posTransformed[3];
166       mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetConcatenatedTransform()->TransformPoint(pos, posTransformed);
167       i = 0;
168       while (i<mCurrentSlicerManager->GetImage()->GetNumberOfDimensions() && i<3) {
169         pos[i] = posTransformed[i];
170         mPoint1[i] = round((pos[i] - mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetOrigin()[i])/mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetSpacing()[i]);
171         pos[i] = mPoint1[i]*mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetSpacing()[i] + mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetOrigin()[i]; //Ensure to be at the center of the voxel
172         position += QString::number(mPoint1[i],'f',0) + " ";
173         ++i;
174       }
175       if (mCurrentSlicerManager->GetImage()->GetNumberOfDimensions() == 4) {
176         pos[3] = mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetTSlice();
177         mPoint1[3] = pos[3];
178         position += QString::number(mPoint1[3],'f',0) + " ";
179       }
180       mPoint1Selected = true;
181       mCurrentSlicerManager->AddLandmarkProfile(pos[0], pos[1], pos[2], pos[3]);
182       mCurrentSlicerManager->GetLandmarks()->GetLabels()->SetNumberOfValues(mCurrentSlicerManager->GetLandmarks()->GetLabels()->GetNumberOfValues()-1);
183       mCurrentSlicerManager->GetLandmarks()->GetLabels()->Modified();
184       mCurrentSlicerManager->GetLandmarks()->GetLabels()->InsertNextValue("P1");
185     }
186   }
187   mPosPoint1Label->setText(position);
188   isPointsSelected();
189   mCurrentSlicerManager->Render();
190 }
191 //------------------------------------------------------------------------------
192
193
194 //------------------------------------------------------------------------------
195 void vvToolProfile::selectPoint2()
196 {
197   QString position = "";
198   
199   if(mCurrentSlicerManager) {
200     if (mPoint2Selected) {
201       ProfileWidget->hide();
202       vtkSmartPointer<vtkChartXY> chart = vtkSmartPointer<vtkChartXY>::New();
203       chart->SetAutoSize(false);
204       chart->SetRenderEmpty(true);
205       mView->GetScene()->ClearItems();
206       mView->GetScene()->AddItem(chart);
207       this->ProfileWidget->GetRenderWindow()->GetRenderers()->RemoveAllItems();
208       this->ProfileWidget->GetRenderWindow()->AddRenderer(mView->GetRenderer());
209       ProfileWidget->show();
210       mCurrentSlicerManager->GetLandmarks()->RemoveLandmarkWithLabel("P2", mPoint2[3]);
211     }
212   
213     mPoint2Selected = false;
214     
215     if(mCurrentSlicerManager->GetSelectedSlicer() != -1) {
216       double *pos;
217       pos = new double [4];
218       pos[0] = pos[1] = pos[2] = pos[3] = 0;;
219           
220       int i(0);
221       while (i<mCurrentSlicerManager->GetImage()->GetNumberOfDimensions() && i<3) {
222         pos[i] = mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetCursorPosition()[i];
223         ++i;
224       }
225       double posTransformed[3];
226       mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetConcatenatedTransform()->TransformPoint(pos, posTransformed);
227       i = 0;
228       while (i<mCurrentSlicerManager->GetImage()->GetNumberOfDimensions() && i<3) {
229         pos[i] = posTransformed[i];
230         mPoint2[i] = round((pos[i] - mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetOrigin()[i])/mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetSpacing()[i]);
231         pos[i] = mPoint2[i]*mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetSpacing()[i] + mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetOrigin()[i]; //Ensure to be at the center of the voxel
232         position += QString::number(mPoint2[i],'f',0) + " ";
233         ++i;
234       }
235       if (mCurrentSlicerManager->GetImage()->GetNumberOfDimensions() == 4) {
236         pos[3] = mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetTSlice();
237         mPoint2[3] = pos[3];
238         position += QString::number(mPoint2[3],'f',0) + " ";
239       }
240       mPoint2Selected = true;
241       mCurrentSlicerManager->AddLandmarkProfile(pos[0], pos[1], pos[2], pos[3]);
242       mCurrentSlicerManager->GetLandmarks()->GetLabels()->SetNumberOfValues(mCurrentSlicerManager->GetLandmarks()->GetLabels()->GetNumberOfValues()-1);
243       mCurrentSlicerManager->GetLandmarks()->GetLabels()->Modified();
244       mCurrentSlicerManager->GetLandmarks()->GetLabels()->InsertNextValue("P2");
245     }
246   }
247   mPosPoint2Label->setText(position);
248   isPointsSelected();
249   mCurrentSlicerManager->Render();
250 }
251 //------------------------------------------------------------------------------
252
253 //------------------------------------------------------------------------------
254 bool vvToolProfile::isPointsSelected()
255 {
256   if (mPoint1Selected && mPoint2Selected) {
257       mSaveProfileButton->setEnabled(true);
258       computeProfile();
259       SetPoints();
260       for(int i=0;i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
261         DisplayLine(i);
262         connect(mCurrentSlicerManager->GetSlicer(i), SIGNAL(UpdateDisplayExtentBegin(int)), this, SLOT(DeleteLine(int)));
263         connect(mCurrentSlicerManager->GetSlicer(i), SIGNAL(UpdateDisplayExtentEnd(int)), this, SLOT(DisplayLine(int)));
264       }
265       mCurrentSlicerManager->Render();
266   }
267   else {
268       mSaveProfileButton->setEnabled(false);
269       for(int i=0;i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
270         disconnect(mCurrentSlicerManager->GetSlicer(i), SIGNAL(UpdateDisplayExtentBegin(int)), this, SLOT(DeleteLine(int)));
271         disconnect(mCurrentSlicerManager->GetSlicer(i), SIGNAL(UpdateDisplayExtentEnd(int)), this, SLOT(DisplayLine(int)));
272         mCurrentSlicerManager->GetSlicer(i)->GetRenderer()->RemoveActor(mLineActors[i]);
273       }
274
275   }
276   return (mPoint1Selected && mPoint2Selected);
277 }
278 //------------------------------------------------------------------------------
279
280
281 //------------------------------------------------------------------------------
282 void vvToolProfile::computeProfile()
283 {
284     if (!mCurrentSlicerManager) close();
285     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
286     GetArgsInfoFromGUI();
287     ProfileWidget->hide();
288    
289     // Main filter
290     mFilter->SetInputVVImage(mCurrentImage);
291     mFilter->SetArgsInfo(mArgsInfo);
292     mFilter->Update();
293     
294     //Creation of the XY chart
295     vtkSmartPointer<vtkTable> table = vtkSmartPointer<vtkTable>::New();
296     vtkSmartPointer<vtkFloatArray> arrX = vtkSmartPointer<vtkFloatArray>::New();
297     vtkSmartPointer<vtkFloatArray> arrY = vtkSmartPointer<vtkFloatArray>::New();
298     arrX = mFilter->GetArrayX();
299     arrY = mFilter->GetArrayY();
300     arrX->SetName("Distance (mm)");
301     arrY->SetName("Intensity");
302     
303     table->AddColumn(arrX);
304     table->AddColumn(arrY);
305     
306     mView->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
307  
308     vtkSmartPointer<vtkChartXY> chart = vtkSmartPointer<vtkChartXY>::New();
309     chart->SetAutoSize(true);
310     mView->GetScene()->ClearItems();
311     mView->GetScene()->AddItem(chart);
312     vtkPlot *line = chart->AddPlot(vtkChart::LINE);
313 #if VTK_MAJOR_VERSION <= 5
314     line->SetInput(table, 0, 1);
315 #else
316     line->SetInputData(table, 0, 1);
317 #endif
318     line->SetColor(0, 255, 0, 255);
319     line->SetWidth(1.0);
320     chart->GetAxis(vtkAxis::LEFT)->SetTitle("Intensity");
321     chart->GetAxis(vtkAxis::BOTTOM)->SetTitle("Distance (mm)");
322     
323     this->ProfileWidget->GetRenderWindow()->GetRenderers()->RemoveAllItems();
324     this->ProfileWidget->GetRenderWindow()->AddRenderer(mView->GetRenderer());
325     ProfileWidget->show();
326     
327     QApplication::restoreOverrideCursor();
328 }
329 //------------------------------------------------------------------------------
330
331
332 //------------------------------------------------------------------------------
333 void vvToolProfile::cancelPoints()
334
335   if (mPoint1Selected)
336     mCurrentSlicerManager->GetLandmarks()->RemoveLandmarkWithLabel("P1", mPoint1[3]);
337   if (mPoint2Selected)
338     mCurrentSlicerManager->GetLandmarks()->RemoveLandmarkWithLabel("P2", mPoint2[3]);
339   ProfileWidget->hide();
340   vtkSmartPointer<vtkChartXY> chart = vtkSmartPointer<vtkChartXY>::New();
341   chart->SetAutoSize(false);
342   chart->SetRenderEmpty(true);
343   mView->GetScene()->ClearItems();
344   mView->GetScene()->AddItem(chart);
345   this->ProfileWidget->GetRenderWindow()->GetRenderers()->RemoveAllItems();
346   this->ProfileWidget->GetRenderWindow()->AddRenderer(mView->GetRenderer());
347   ProfileWidget->show();
348   
349   QString position = "";
350   mPosPoint1Label->setText(position);
351   mPosPoint2Label->setText(position);
352   mPoint1Selected = false;
353   mPoint2Selected = false;
354   mSaveProfileButton->setEnabled(false);
355   isPointsSelected();
356   mCurrentSlicerManager->Render();
357 }
358 //------------------------------------------------------------------------------
359
360
361 //------------------------------------------------------------------------------
362 void vvToolProfile::RemoveVTKObjects()
363
364   if (mCurrentSlicerManager)
365   {
366     connect(mCurrentSlicerManager, SIGNAL(callAddLandmark(float,float,float,float)), mCurrentSlicerManager, SLOT(AddLandmark(float,float,float,float)));
367
368     for(int i=0;i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
369       mCurrentSlicerManager->GetSlicer(i)->GetRenderer()->RemoveActor(mLineActors[i]);
370     }
371
372     if (mPoint1Selected)
373       mCurrentSlicerManager->GetLandmarks()->RemoveLandmarkWithLabel("P1", mPoint1[3]);
374     if (mPoint2Selected)
375       mCurrentSlicerManager->GetLandmarks()->RemoveLandmarkWithLabel("P2", mPoint2[3]);
376
377     mCurrentSlicerManager->Render();
378   }
379 }
380 //------------------------------------------------------------------------------
381
382
383 //------------------------------------------------------------------------------
384 bool vvToolProfile::close()
385
386   //RemoveVTKObjects();
387
388   return vvToolWidgetBase::close();
389 }
390 //------------------------------------------------------------------------------
391
392
393 //------------------------------------------------------------------------------
394 void vvToolProfile::closeEvent(QCloseEvent *event)
395
396   RemoveVTKObjects();
397   event->accept();
398 }
399 //------------------------------------------------------------------------------
400
401
402 //------------------------------------------------------------------------------
403 void vvToolProfile::reject()
404
405   // DD("vvToolProfile::reject");
406   RemoveVTKObjects();
407   return vvToolWidgetBase::reject();
408 }
409 //------------------------------------------------------------------------------
410
411
412 //------------------------------------------------------------------------------
413 void vvToolProfile::InputIsSelected(vvSlicerManager * m)
414
415   mCurrentSlicerManager = m;
416
417   mPoint1 = new double[4];
418   mPoint1[0] = mPoint1[1] = mPoint1[2] = mPoint1[3] = 0;
419   mPoint2 = new double[4];
420   mPoint2[0] = mPoint2[1] = mPoint2[2] = mPoint2[3] = 0;
421   
422   mSaveProfileButton->setEnabled(false);
423   mTextFileName = "Profile.txt";
424   InitializeLine();
425   
426   disconnect(mCurrentSlicerManager, SIGNAL(callAddLandmark(float,float,float,float)), mCurrentSlicerManager, SLOT(AddLandmark(float,float,float,float)));
427 }
428 //------------------------------------------------------------------------------
429
430
431 //------------------------------------------------------------------------------
432 void vvToolProfile::GetArgsInfoFromGUI()
433
434
435   /* //KEEP THIS FOR READING GGO FROM FILE
436      int argc=1;
437      std::string a = "toto";
438      char * const* argv = new char*;
439      //a.c_str();
440      struct cmdline_parser_params p;
441      p.check_required = 0;
442      int good = cmdline_parser_ext(argc, argv, &args_info, &p);
443      DD(good);
444   */
445   cmdline_parser_clitkProfileImage_init(&mArgsInfo); // Initialisation to default
446
447   mArgsInfo.verbose_flag = false;
448   
449   mArgsInfo.point1_arg = mPoint1;
450   mArgsInfo.point2_arg = mPoint2;
451   mArgsInfo.point1_given = mCurrentSlicerManager->GetImage()->GetNumberOfDimensions();
452   mArgsInfo.point2_given = mCurrentSlicerManager->GetImage()->GetNumberOfDimensions();
453   
454   // Required (even if not used)
455   mArgsInfo.input_given = 0;
456   mArgsInfo.output_given = 0;
457
458   mArgsInfo.input_arg = new char;
459   mArgsInfo.output_arg = new char;
460   
461
462 }
463 //------------------------------------------------------------------------------
464
465
466 //------------------------------------------------------------------------------
467 void vvToolProfile::apply()
468
469   close();
470 }
471 //------------------------------------------------------------------------------
472
473
474 //------------------------------------------------------------------------------
475 void vvToolProfile::SaveAs()
476
477   QStringList OutputListeFormat;
478   OutputListeFormat.clear();
479   OutputListeFormat.push_back(".txt");
480   
481   QString Extensions = "AllFiles(*.*)";
482   for (int i = 0; i < OutputListeFormat.count(); i++) {
483     Extensions += ";;Text File ( *";
484     Extensions += OutputListeFormat[i];
485     Extensions += ")";
486   }
487   QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), mTextFileName.c_str(), Extensions);
488   if (!fileName.isEmpty()) {
489     std::string fileformat = itksys::SystemTools::GetFilenameLastExtension(fileName.toStdString());
490     QString fileQFormat = fileformat.c_str();
491     if (OutputListeFormat.contains(fileformat.c_str()) || fileQFormat.isEmpty()) {
492         QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
493         std::string action = "Saving";
494         vvProgressDialog progress("Saving "+fileName.toStdString());
495         qApp->processEvents();
496         
497         if (!mCurrentSlicerManager || !isPointsSelected()) {
498             close();
499             return;
500         }
501
502         // Output
503         mTextFileName = fileName.toStdString();
504         if (fileQFormat.isEmpty())
505             mTextFileName += ".txt";
506         ofstream fileOpen(mTextFileName.c_str(), std::ofstream::trunc);
507   
508         if(!fileOpen) {
509             cerr << "Error during saving" << endl;
510             QApplication::restoreOverrideCursor();
511             close();
512             return;
513         }
514
515         mFilter->WriteOutput(mTextFileName.c_str());
516
517         fileOpen.close();
518         QApplication::restoreOverrideCursor();
519     } else {
520       QString error = fileformat.c_str();
521       error += " format unknown !!!\n";
522       QMessageBox::information(this,tr("Saving Problem"),error);
523       SaveAs();
524     }
525   }
526 }
527 //------------------------------------------------------------------------------
528
529
530 //------------------------------------------------------------------------------
531 void vvToolProfile::DeleteLine(int slicer)
532 {
533   if (!mPoint1Selected && !mPoint2Selected)
534     return;
535   
536   if(mCurrentSlicerManager) {
537       if(mCurrentSlicerManager->GetSelectedSlicer() != -1) {
538           mCurrentSlicerManager->GetSlicer(slicer)->GetRenderer()->RemoveActor(mLineActors[slicer]);
539       }
540    }
541 }
542 //------------------------------------------------------------------------------
543
544
545 //------------------------------------------------------------------------------
546 void vvToolProfile::DisplayLine(int slicer)
547
548   if (!mPoint1Selected && !mPoint2Selected)
549     return;
550   
551   if(mCurrentSlicerManager) {
552       if(mCurrentSlicerManager->GetSelectedSlicer() != -1) {
553           double currentSlice = (mCurrentSlicerManager->GetSlicer(slicer)->GetSlice()*mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetSpacing()[mCurrentSlicerManager->GetSlicer(slicer)->GetOrientation()] + mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetInput()->GetOrigin()[mCurrentSlicerManager->GetSlicer(slicer)->GetOrientation()] - mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetOrigin()[mCurrentSlicerManager->GetSlicer(slicer)->GetOrientation()] )/ mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetSpacing()[mCurrentSlicerManager->GetSlicer(slicer)->GetOrientation()];
554           if (std::min(mPoint1[mCurrentSlicerManager->GetSlicer(slicer)->GetOrientation()],mPoint2[mCurrentSlicerManager->GetSlicer(slicer)->GetOrientation()]) <= currentSlice && std::max(mPoint1[mCurrentSlicerManager->GetSlicer(slicer)->GetOrientation()],mPoint2[mCurrentSlicerManager->GetSlicer(slicer)->GetOrientation()]) >= currentSlice) {
555             vtkSmartPointer<vtkBox> clippingBox = vtkSmartPointer<vtkBox>::New();
556             double extent[6];
557             for (int j=0; j<6; ++j) {
558                 extent[j] = mCurrentSlicerManager->GetSlicer(slicer)->GetExtent()[j];
559             }
560             extent[2*mCurrentSlicerManager->GetSlicer(slicer)->GetOrientation()] = mCurrentSlicerManager->GetSlicer(slicer)->GetImageActor()->GetBounds()[ mCurrentSlicerManager->GetSlicer(slicer)->GetOrientation()*2 ]-fabs(mCurrentSlicerManager->GetSlicer(slicer)->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetSpacing()[mCurrentSlicerManager->GetSlicer(slicer)->GetOrientation()]);
561             extent[2*mCurrentSlicerManager->GetSlicer(slicer)->GetOrientation()+1] = mCurrentSlicerManager->GetSlicer(slicer)->GetImageActor()->GetBounds()[ mCurrentSlicerManager->GetSlicer(slicer)->GetOrientation()*2+1 ]+fabs(mCurrentSlicerManager->GetSlicer(slicer)->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetSpacing()[mCurrentSlicerManager->GetSlicer(slicer)->GetOrientation()]);
562             clippingBox->SetBounds(extent);
563             
564             vtkSmartPointer<vtkClipPolyData> clipper = vtkSmartPointer<vtkClipPolyData>::New();
565             clipper->SetClipFunction(clippingBox);
566 #if VTK_MAJOR_VERSION <= 5
567             clipper->SetInput(mLinesPolyData);
568 #else
569             mLineTransform = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
570             mLineTransform->SetInputData(mLinesPolyData);
571             mLineTransform->SetTransform(mCurrentSlicerManager->GetSlicer(slicer)->GetConcatenatedTransform()->GetInverse());
572             clipper->SetInputConnection(mLineTransform->GetOutputPort());
573 #endif
574             clipper->InsideOutOff();
575             clipper->Update();        
576             vtkSmartPointer<vtkPolyDataMapper> lineMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
577 #if VTK_MAJOR_VERSION <= 5
578             lineMapper->SetInput(clipper->GetOutput());
579 #else
580             lineMapper->SetInputData(clipper->GetOutput());
581 #endif 
582             
583             mLineActors[slicer]->SetMapper(lineMapper);
584             mLineActors[slicer]->GetProperty()->SetOpacity(0.995);
585
586             mCurrentSlicerManager->GetSlicer(slicer)->GetRenderer()->AddActor(mLineActors[slicer]);
587          }
588       }
589   }
590 }
591 //------------------------------------------------------------------------------
592
593
594 //------------------------------------------------------------------------------
595 void vvToolProfile::InitializeLine()
596
597   if(mCurrentSlicerManager) {
598       
599       mLinesPolyData = vtkSmartPointer<vtkPolyData>::New();
600       
601       vtkSmartPointer<vtkPoints> pts = vtkSmartPointer<vtkPoints>::New();
602       double pos[4];
603       pos[0] = pos[1] = pos[2] = pos[3] = 0;
604       pts->InsertNextPoint(pos);
605       pts->InsertNextPoint(pos);
606       mLinesPolyData->SetPoints(pts);
607       
608       vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
609       vtkSmartPointer<vtkLine> line = vtkSmartPointer<vtkLine>::New();
610       line->GetPointIds()->SetId(0, 0); // the second 0 is the index of the 1st point in mLinesPolyData's points (pts)
611       line->GetPointIds()->SetId(1, 1); // the second 1 is the index of the 2nd point in mLinesPolyData's points (pts)
612       lines->InsertNextCell(line);
613       mLinesPolyData->SetLines(lines);
614        
615       unsigned char red[3] = { 255, 0, 0 };
616       vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
617       colors->SetNumberOfComponents(3);
618 #if VTK_MAJOR_VERSION >= 8 || (VTK_MAJOR_VERSION == 7 && VTK_MINOR_VERSION >= 1)
619       colors->InsertNextTypedTuple(red);
620 #else
621       colors->InsertNextTupleValue(red);
622 #endif
623       mLinesPolyData->GetCellData()->SetScalars(colors);
624       
625       for(int i=0;i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
626         mLineActors.push_back(vtkSmartPointer<vtkActor>::New());
627       }
628    }       
629 }    
630 //------------------------------------------------------------------------------
631
632
633 //------------------------------------------------------------------------------
634 void vvToolProfile::SetPoints()
635
636   if (!mPoint1Selected && !mPoint2Selected)
637     return;
638   
639   if(mCurrentSlicerManager) {
640       if(mCurrentSlicerManager->GetSelectedSlicer() != -1) {
641           /*double *pos;
642           pos = new double [4];
643           pos[0] = pos[1] = pos[2] = pos[3] = 0;
644           
645           int i(0);
646           while (i<3) {
647             pos[i] = mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetCursorPosition()[i];
648             ++i;
649           }
650           if (mCurrentSlicerManager->GetImage()->GetNumberOfDimensions() == 4) {
651             pos[3] = mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetTSlice();
652           } */
653           
654           double p0[4], p1[4];
655           p0[0] = mPoint1[0]*mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetSpacing()[0] + mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetOrigin()[0];
656           p0[1] = mPoint1[1]*mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetSpacing()[1] + mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetOrigin()[1];
657           p0[2] = mPoint1[2]*mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetSpacing()[2] + mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetOrigin()[2];
658           p0[3] = mPoint1[3];
659
660           p1[0] = mPoint2[0]*mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetSpacing()[0] + mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetOrigin()[0];
661           p1[1] = mPoint2[1]*mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetSpacing()[1] + mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetOrigin()[1];
662           p1[2] = mPoint2[2]*mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetSpacing()[2] + mCurrentSlicerManager->GetSlicer(mCurrentSlicerManager->GetSelectedSlicer())->GetImage()->GetVTKImages()[mCurrentSlicerManager->GetTSlice()]->GetOrigin()[2];
663           p1[3] = mPoint2[3];
664               
665           vtkSmartPointer<vtkPoints> pts = mLinesPolyData->GetPoints();
666           pts->SetPoint(0,p0);
667           pts->SetPoint(1,p1);
668     }
669   }
670 }
671 //------------------------------------------------------------------------------
672
673