]> Creatis software - clitk.git/blob - vv/vvToolStructureSetManager.cxx
- now work in 3D with
[clitk.git] / vv / vvToolStructureSetManager.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://oncora1.lyon.fnclcc.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 "vvToolStructureSetManager.h"
21 #include "vvImageReader.h"
22 #include "vvStructureSetActor.h"
23 #include "vvSlicer.h"
24 #include "vvROIActor.h"
25
26 // Qt
27 #include <QFileDialog>
28 #include <QMessageBox>
29 #include <QColorDialog>
30
31 // vtk
32 #include <vtkLookupTable.h>
33 #include <vtkRenderWindow.h>
34
35 //------------------------------------------------------------------------------
36 // Create the tool and automagically (I like this word) insert it in
37 // the main window menu.
38 ADD_TOOL(vvToolStructureSetManager);
39 //------------------------------------------------------------------------------
40
41 //------------------------------------------------------------------------------
42 vvToolStructureSetManager::vvToolStructureSetManager(vvMainWindowBase * parent, Qt::WindowFlags f)
43   :vvToolWidgetBase(parent, f),//, true),
44    vvToolBase<vvToolStructureSetManager>(parent),
45    Ui::vvToolStructureSetManager()
46 {
47   // Setup the UI
48   /*
49   QWidget * aw = new QWidget(parent, f);
50   QVBoxLayout * verticalLayout = new QVBoxLayout(aw);
51   verticalLayout->addWidget(mToolInputSelectionWidget);
52   verticalLayout->addWidget(mToolWidget);
53   aw->setLayout(verticalLayout);
54   */
55   Ui_vvToolStructureSetManager::setupUi(mToolWidget);
56
57   // ----------------
58   // Essai TAB
59   /*
60   //int a = mMainWindowBase->GetTab()->addTab(mToolWidget, "Toto"); 
61   int a = mMainWindowBase->GetTab()->addTab(aw, "Toto"); 
62
63   // essai avec mToolWidget ? ok  mais frame à cacher ... 
64   // Changer le construceur par defautl de widgetbase -> pas dialog, pas parent (cf doc)
65   mMainWindowBase->GetTab()->setCurrentIndex(a); 
66   mMainWindowBase->GetTab()->setTabIcon(a, QIcon(vvToolCreator<vvToolStructureSetManager>::GetInstance()->mToolIconFilename));
67   DD(this->width());
68   */
69   // ---------------
70
71   mTree->clear();
72   mCurrentStructureSet = NULL;
73   mCurrentStructureSetIndex = -1;
74   mGroupBoxROI->setEnabled(false);
75   mCurrentROIActor = NULL;
76   mIsAllVisibleEnabled = false;
77   mNumberOfVisibleROI = 0;
78   mNumberOfVisibleContourROI = 0;
79   mDefaultLUTColor = vtkLookupTable::New();
80   for(unsigned int i=0; i<mDefaultLUTColor->GetNumberOfTableValues(); i++) {
81     double r = (rand()/(RAND_MAX+1.0));
82     double v = (rand()/(RAND_MAX+1.0));
83     double b = (rand()/(RAND_MAX+1.0));
84     mDefaultLUTColor->SetTableValue(i, r, v, b);
85     //    std::cout << "mDefaultLUTColor->SetTableValue(" << i << ", " << r << ", " << v << ", " << b << ");" << std::endl;
86   }
87 #include "vvDefaultLut.h"
88
89   // Add input selector
90   AddInputSelector("Select image");
91 }
92 //------------------------------------------------------------------------------
93
94
95 //------------------------------------------------------------------------------
96 vvToolStructureSetManager::~vvToolStructureSetManager()
97 {
98 }
99 //------------------------------------------------------------------------------
100
101
102 //------------------------------------------------------------------------------
103 void vvToolStructureSetManager::Initialize() {
104   SetToolName("ROIManager");
105   SetToolMenuName("Display ROI");
106   SetToolIconFilename(":/common/icons/ducky.png");
107   SetToolTip("Display ROI from label image.");
108   SetToolExperimental(true);
109 }
110 //------------------------------------------------------------------------------
111
112
113 //------------------------------------------------------------------------------
114 void vvToolStructureSetManager::InputIsSelected(vvSlicerManager *m)
115 {
116   // Refuse if 4D
117   if (mCurrentImage->GetNumberOfDimensions() != 3) {
118     QMessageBox::information(this,tr("Sorry only 3D yet"), tr("Sorry only 3D yet"));
119     close();
120     // return;
121   }
122   // Hide selector
123   HideInputSelector(); // splitter
124   //  mToolInputSelectionWidget->hide();
125   // Connect open menus
126   connect(mOpenBinaryButton, SIGNAL(clicked()), this, SLOT(OpenBinaryImage()));
127   connect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedItemChangedInTree()));
128   connect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleROIToggled(bool)));
129   connect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityChanged(int)));
130   connect(mChangeColorButton, SIGNAL(clicked()), this, SLOT(ChangeColor()));
131   connect(mContourCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleContourROIToggled(bool)));  
132   connect(mChangeContourColorButton, SIGNAL(clicked()), this, SLOT(ChangeContourColor()));
133   connect(mContourWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeContourWidth(int)));
134   connect(mReloadButton, SIGNAL(clicked()), this, SLOT(ReloadCurrentROI()));
135   connect(mCheckBoxShowAll, SIGNAL(stateChanged(int)), this, SLOT(AllVisibleROIToggled(int)));
136   connect(mContourCheckBoxShowAll, SIGNAL(toggled(bool)), this, SLOT(AllVisibleContourROIToggled(bool)));
137 }
138 //------------------------------------------------------------------------------
139
140
141 //------------------------------------------------------------------------------
142 void vvToolStructureSetManager::Open(int type) {
143   switch (type) {
144   case 0: OpenBinaryImage(); return; // Open binary image;
145   case 1: DD("TODO"); return; // Open DICOM RT
146   case 2: DD("TODO"); return; // Open mesh
147   default: std::cerr << "Error ????" << std::endl; exit(0);
148   }
149 }
150 //------------------------------------------------------------------------------
151
152
153 //------------------------------------------------------------------------------
154 void vvToolStructureSetManager::AddRoiInTreeWidget(clitk::DicomRT_ROI * roi, QTreeWidget * ww) {
155   QTreeWidgetItem * w = new QTreeWidgetItem(ww);
156   w->setText(0, QString("%1").arg(roi->GetROINumber()));
157   w->setText(1, QString("%1").arg(roi->GetName().c_str()));
158   QBrush brush(QColor(roi->GetDisplayColor()[0]*255, roi->GetDisplayColor()[1]*255, roi->GetDisplayColor()[2]*255));
159   brush.setStyle(Qt::SolidPattern);
160   w->setBackground(2, brush);
161   mMapROIToTreeWidget[roi] = w;
162   mMapTreeWidgetToROI[w] = roi;
163 }
164 //------------------------------------------------------------------------------
165
166
167 //------------------------------------------------------------------------------
168 void vvToolStructureSetManager::UpdateStructureSetInTreeWidget(int index, clitk::DicomRT_StructureSet * s) {
169   // Insert ROI
170   const std::vector<clitk::DicomRT_ROI*> & rois = s->GetListOfROI();
171   for(unsigned int i=0; i<rois.size(); i++) {
172     if (mMapROIToTreeWidget.find(rois[i]) == mMapROIToTreeWidget.end())
173       AddRoiInTreeWidget(rois[i], mTree); // replace mTree with ss if several SS
174   }
175 }
176 //------------------------------------------------------------------------------
177
178
179 //------------------------------------------------------------------------------
180 int vvToolStructureSetManager::AddStructureSet(clitk::DicomRT_StructureSet * mStructureSet) {
181   // Create actor for this SS
182   vvStructureSetActor * mStructureSetActor = new vvStructureSetActor;
183   mStructureSetActor->SetStructureSet(mStructureSet);
184   mStructureSetActor->SetSlicerManager(mCurrentSlicerManager);
185   // Insert in lists and get index
186   mStructureSetsList.push_back(mStructureSet);
187   mStructureSetActorsList.push_back(mStructureSetActor);
188   int index = mStructureSetsList.size()-1;
189   // Return index
190   return index;
191 }
192 //------------------------------------------------------------------------------
193
194
195 //------------------------------------------------------------------------------
196 void vvToolStructureSetManager::OpenBinaryImage() {
197   int index;
198   if (mCurrentStructureSet == NULL) {
199     if (mStructureSetsList.size() == 0) { // Create a default SS
200       clitk::DicomRT_StructureSet * mStructureSet = new clitk::DicomRT_StructureSet;
201       index = AddStructureSet(mStructureSet);
202     }
203     else { // Get first SS
204       index = 0;
205     }
206   } else {
207     index = mCurrentStructureSetIndex;
208   }
209   mCurrentStructureSet = mStructureSetsList[index];
210   mCurrentStructureSetActor = mStructureSetActorsList[index];
211   mCurrentStructureSetIndex = index;
212   // Open images
213   QString Extensions = "Images files ( *.mhd *.hdr *.his)";
214   Extensions += ";;All Files (*)";
215   QStringList filename =
216     QFileDialog::getOpenFileNames(this,tr("Open binary image"),
217                                   mMainWindowBase->GetInputPathName(),Extensions);
218   if (filename.size() == 0) return;
219   std::vector<int> mLoadedROIIndex;
220   for(int i=0; i<filename.size(); i++) {
221     // Open Image
222     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
223     vvImageReader * mReader = new vvImageReader;
224     std::vector<std::string> filenames;
225     filenames.push_back(filename[i].toStdString());
226     mReader->SetInputFilenames(filenames);
227     mReader->Update(IMAGE);
228     QApplication::restoreOverrideCursor();
229
230     if (mReader->GetLastError().size() != 0) {
231       std::cerr << "Error while reading " << filename[i].toStdString() << std::endl;
232       QString error = "Cannot open file \n";
233       error += mReader->GetLastError().c_str();
234       QMessageBox::information(this,tr("Reading problem"),error);
235       delete mReader;
236       return;
237     }
238     vvImage::Pointer binaryImage = mReader->GetOutput();
239
240     // Check Dimension
241     int dim = mCurrentImage->GetNumberOfDimensions();
242     int bin_dim = binaryImage->GetNumberOfDimensions();
243     if (dim < bin_dim) {  ////////// TO CHANGE FOR 3D/4D
244       std::ostringstream os;
245       os << "Error. Loaded binary image is " << bin_dim
246          << "D while selected image is " << dim << "D" << std::endl;
247       QMessageBox::information(this,tr("Reading problem"),os.str().c_str());
248       return;
249     }
250
251     // Add a new roi to the structure
252     int n = mCurrentStructureSet->AddBinaryImageAsNewROI(binaryImage, filename[i].toStdString());
253     mLoadedROIIndex.push_back(n);
254     mCurrentStructureSet->GetROI(n)->SetBackgroundValueLabelImage(mBackgroundValueSpinBox->value());
255
256     // Change color
257     if (n<mDefaultLUTColor->GetNumberOfTableValues ()) {
258       double * color = mDefaultLUTColor->GetTableValue(n % mDefaultLUTColor->GetNumberOfTableValues ());
259       mCurrentStructureSet->GetROI(n)->SetDisplayColor(color[0], color[1], color[2]);
260     }
261
262     // Add a new roi actor
263     mCurrentStructureSetActor->CreateNewROIActor(n);
264
265     // CheckBox for "All"
266     if (mCurrentStructureSetActor->GetROIActor(n)->IsVisible())
267       mNumberOfVisibleROI++;
268     if (mCurrentStructureSetActor->GetROIActor(n)->IsContourVisible())
269       mNumberOfVisibleContourROI++;
270     UpdateAllROIStatus();
271   } // end loop on n selected filenames
272
273   // Update the TreeWidget
274   UpdateStructureSetInTreeWidget(index, mCurrentStructureSet);
275   // Render loaded ROIs (the first is sufficient)
276   for(unsigned int i=0; i<mLoadedROIIndex.size(); i++) {
277     mCurrentStructureSetActor->GetROIActor(mLoadedROIIndex[i])->Update();
278   }
279   for(int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
280     mCurrentSlicerManager->GetSlicer(i)->Render();
281   }  
282 }
283 //------------------------------------------------------------------------------
284
285
286 //------------------------------------------------------------------------------
287 void vvToolStructureSetManager::apply() 
288 {
289   close();
290 }
291 //------------------------------------------------------------------------------
292
293
294 //------------------------------------------------------------------------------
295 bool vvToolStructureSetManager::close()
296 {
297   mCheckBoxShowAll->setCheckState(Qt::Unchecked);
298   mContourCheckBoxShowAll->setCheckState(Qt::Unchecked);
299   if (mCurrentSlicerManager) mCurrentSlicerManager->Render();
300   if (mCurrentStructureSetActor) {
301     for(int i=0; i<mCurrentStructureSetActor->GetNumberOfROIs(); i++) {
302       mCurrentStructureSetActor->GetROIList()[i]->SetVisible(false);
303       mCurrentStructureSetActor->GetROIList()[i]->SetContourVisible(false);
304       delete mCurrentStructureSetActor->GetROIList()[i];
305     }
306   }
307   return vvToolWidgetBase::close();
308 }
309 //------------------------------------------------------------------------------
310
311
312 //------------------------------------------------------------------------------
313 // CURRENT ROI INTERACTION
314 //------------------------------------------------------------------------------
315
316
317 //------------------------------------------------------------------------------
318 void vvToolStructureSetManager::SelectedItemChangedInTree() {
319   // Search which roi is selected
320   QList<QTreeWidgetItem *> l = mTree->selectedItems();
321   if (l.size() == 0) {
322     mCurrentROIActor = NULL;
323     mCurrentROI = NULL;
324     mGroupBoxROI->setEnabled(false);
325     return;
326   }
327   QTreeWidgetItem * w = l[0];
328   if (mMapTreeWidgetToROI.find(w) == mMapTreeWidgetToROI.end()) {
329     mCurrentROIActor = NULL;
330     mCurrentROI = NULL;
331     mGroupBoxROI->setEnabled(false);
332     return;
333   }
334   clitk::DicomRT_ROI * roi = mMapTreeWidgetToROI[w];
335   // Get selected roi actor
336   vvROIActor * actor = mStructureSetActorsList[mCurrentStructureSetIndex]->GetROIActor(roi->GetROINumber());
337   mCurrentROI = roi;
338   mCurrentROIActor = actor;
339
340   // Update GUI
341   mGroupBoxROI->setEnabled(true);
342   mROInameLabel->setText(roi->GetName().c_str());
343   mCheckBoxShow->setChecked(actor->IsVisible());
344   mContourCheckBoxShow->setChecked(actor->IsContourVisible());
345   mContourWidthSpinBox->setValue(actor->GetContourWidth());
346   
347   // Warning -> avoir unuseful Render here by disconnect slider 
348   disconnect(mOpacitySlider, SIGNAL(valueChanged(int)), 
349              this, SLOT(OpacityChanged(int)));
350   mOpacitySlider->setValue((int)lrint(actor->GetOpacity()*100));
351   mOpacitySpinBox->setValue((int)lrint(actor->GetOpacity()*100));
352   connect(mOpacitySlider, SIGNAL(valueChanged(int)), 
353           this, SLOT(OpacityChanged(int)));
354   actor->Update(); 
355
356   // Final rendering
357   mCurrentSlicerManager->Render();
358 }
359 //------------------------------------------------------------------------------
360
361
362 //------------------------------------------------------------------------------
363 void vvToolStructureSetManager::UpdateAllROIStatus() {
364   int nbVisible = 0;
365   int nb = mCurrentStructureSetActor->GetROIList().size();
366   for(int i=0; i<nb; i++) {
367     if (mCurrentStructureSetActor->GetROIList()[i]->IsVisible()) {
368       nbVisible++;
369     }
370   }
371
372   disconnect(mCheckBoxShowAll, SIGNAL(stateChanged(int)), this, SLOT(AllVisibleROIToggled(int)));  
373   disconnect(mContourCheckBoxShowAll, SIGNAL(toggled(bool)), this, SLOT(AllVisibleContourROIToggled(bool)));
374   if (nbVisible == nb) mCheckBoxShowAll->setCheckState(Qt::Checked);
375   else {
376     if (nbVisible == 0) mCheckBoxShowAll->setCheckState(Qt::Unchecked);
377     else mCheckBoxShowAll->setCheckState(Qt::PartiallyChecked);
378   }
379   connect(mContourCheckBoxShowAll, SIGNAL(toggled(bool)), this, SLOT(AllVisibleContourROIToggled(bool)));
380   connect(mCheckBoxShowAll, SIGNAL(stateChanged(int)), this, SLOT(AllVisibleROIToggled(int)));
381 }
382 //------------------------------------------------------------------------------
383
384 //------------------------------------------------------------------------------
385 void vvToolStructureSetManager::VisibleROIToggled(bool b) {
386   if (mCurrentROIActor == NULL) return;
387   if (b == mCurrentROIActor->IsVisible()) return; // nothing to do
388   mCurrentROIActor->SetVisible(b);
389   UpdateAllROIStatus();
390   mCurrentSlicerManager->Render(); 
391 }
392 //------------------------------------------------------------------------------
393
394
395 //------------------------------------------------------------------------------
396 void vvToolStructureSetManager::VisibleContourROIToggled(bool b) {
397   if (mCurrentROIActor == NULL) return;
398   if (mCurrentROIActor->IsContourVisible() == b) return; // nothing to do
399   mCurrentROIActor->SetContourVisible(b);
400   mCurrentROIActor->UpdateColor();
401   mCurrentSlicerManager->Render(); 
402 }
403 //------------------------------------------------------------------------------
404
405
406 //------------------------------------------------------------------------------
407 void vvToolStructureSetManager::OpacityChanged(int v) {
408   if (mCurrentROIActor == NULL) return;
409   mCurrentROIActor->SetOpacity((double)v/100.0);
410   mCurrentROIActor->UpdateColor();
411   mCurrentSlicerManager->Render(); 
412 }
413 //------------------------------------------------------------------------------
414
415
416 //------------------------------------------------------------------------------
417 void vvToolStructureSetManager::AllVisibleROIToggled(int b) {
418   bool status = false;
419   if ((mCheckBoxShowAll->checkState() == Qt::Checked) ||
420       (mCheckBoxShowAll->checkState() == Qt::PartiallyChecked))  status = true;
421
422   for(int i=0; i<mCurrentStructureSetActor->GetNumberOfROIs(); i++) {
423     mCurrentStructureSetActor->GetROIList()[i]->SetVisible(status);
424   }
425   if (status) mCheckBoxShowAll->setCheckState(Qt::Checked);
426   else  mCheckBoxShowAll->setCheckState(Qt::Unchecked);
427   mCheckBoxShow->setChecked(status);
428   mCurrentSlicerManager->Render(); 
429 }
430 //------------------------------------------------------------------------------
431
432
433 //------------------------------------------------------------------------------
434 void vvToolStructureSetManager::AllVisibleContourROIToggled(bool b) {
435   bool status = false;
436   if ((mContourCheckBoxShowAll->checkState() == Qt::Checked) ||
437       (mContourCheckBoxShowAll->checkState() == Qt::PartiallyChecked))  status = true;
438   // Update current 
439   for(int i=0; i<mCurrentStructureSetActor->GetNumberOfROIs(); i++) {
440     mCurrentStructureSetActor->GetROIList()[i]->SetContourVisible(status);
441   }
442   // Update current selection
443   if (status) mContourCheckBoxShowAll->setCheckState(Qt::Checked);
444   else  mContourCheckBoxShowAll->setCheckState(Qt::Unchecked);
445   mContourCheckBoxShow->setChecked(status);
446   mCurrentSlicerManager->Render(); 
447 }
448 //------------------------------------------------------------------------------
449
450
451 //------------------------------------------------------------------------------
452 void vvToolStructureSetManager::ChangeColor() {
453   QColor color;
454   color.setRgbF(mCurrentROIActor->GetROI()->GetDisplayColor()[0],
455                 mCurrentROIActor->GetROI()->GetDisplayColor()[1],
456                 mCurrentROIActor->GetROI()->GetDisplayColor()[2]);
457   QColor c = QColorDialog::getColor(color, this, "Choose the ROI color");
458   mCurrentROIActor->GetROI()->SetDisplayColor(c.redF(), c.greenF(), c.blueF());
459   mCurrentROIActor->UpdateColor();
460
461   QTreeWidgetItem * w = mMapROIToTreeWidget[mCurrentROI];
462   QBrush brush(QColor(mCurrentROI->GetDisplayColor()[0]*255,
463                       mCurrentROI->GetDisplayColor()[1]*255,
464                       mCurrentROI->GetDisplayColor()[2]*255));
465   brush.setStyle(Qt::SolidPattern);
466   w->setBackground(2, brush);
467   // Render
468   mCurrentSlicerManager->Render();
469 }
470 //------------------------------------------------------------------------------
471
472
473 //------------------------------------------------------------------------------
474 void vvToolStructureSetManager::ChangeContourColor() {
475   QColor color;
476   color.setRgbF(mCurrentROIActor->GetContourColor()[0], 
477                 mCurrentROIActor->GetContourColor()[1], 
478                 mCurrentROIActor->GetContourColor()[2]);
479   QColor c = QColorDialog::getColor(color, this, "Choose the contour color");
480   mCurrentROIActor->SetContourColor(c.redF(), c.greenF(), c.blueF());
481   mCurrentROIActor->UpdateColor();
482   mCurrentSlicerManager->Render();
483 }
484 //------------------------------------------------------------------------------
485
486
487 //------------------------------------------------------------------------------
488 void vvToolStructureSetManager::ChangeContourWidth(int n) {
489   mCurrentROIActor->SetContourWidth(n);
490   mCurrentROIActor->UpdateColor();
491   mCurrentSlicerManager->Render();
492 }
493 //------------------------------------------------------------------------------
494
495
496 //------------------------------------------------------------------------------
497 void vvToolStructureSetManager::ReloadCurrentROI() {
498   // Reload image
499   vvImageReader * mReader = new vvImageReader;
500   mReader->SetInputFilename(mCurrentROI->GetFilename());
501   mReader->Update(IMAGE);
502   if (mReader->GetLastError() != "") {
503     QMessageBox::information(mMainWindowBase, tr("Sorry, error. Could not reload"), mReader->GetLastError().c_str());
504     return;
505   }
506   mCurrentROI->SetImage(mReader->GetOutput());
507   
508   // Update visu"
509   mCurrentROIActor->UpdateImage();
510   mCurrentSlicerManager->Render();    
511 }
512 //------------------------------------------------------------------------------
513
514