]> Creatis software - clitk.git/blob - vv/vvToolStructureSetManager.cxx
Reformatted using new coding style
[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 #include "vvToolStructureSetManager.h"
20 #include "vvImageReader.h"
21 #include "vvStructureSetActor.h"
22 #include "vvSlicer.h"
23 #include "vvROIActor.h"
24
25 #include <QFileDialog>
26 #include <QMessageBox>
27 #include <QColorDialog>
28
29 #include <vtkLookupTable.h>
30 #include <vtkRenderWindow.h>
31
32 //------------------------------------------------------------------------------
33 // Create the tool and automagically (I like this word) insert it in
34 // the main window menu.
35 ADD_TOOL(vvToolStructureSetManager);
36 //------------------------------------------------------------------------------
37
38 //------------------------------------------------------------------------------
39 vvToolStructureSetManager::vvToolStructureSetManager(vvMainWindowBase * parent, Qt::WindowFlags f)
40   :vvToolWidgetBase(parent, f),
41    vvToolBase<vvToolStructureSetManager>(parent),
42    Ui::vvToolStructureSetManager()
43 {
44   // Setup the UI
45   Ui_vvToolStructureSetManager::setupUi(mToolWidget);
46   mTree->clear();
47   mCurrentStructureSet = NULL;
48   mCurrentStructureSetIndex = -1;
49   mGroupBoxROI->setEnabled(false);
50   mCurrentROIActor = NULL;
51
52   mDefaultLUTColor = vtkLookupTable::New();
53   for(unsigned int i=0; i<mDefaultLUTColor->GetNumberOfTableValues(); i++) {
54     double r = (rand()/(RAND_MAX+1.0));
55     double v = (rand()/(RAND_MAX+1.0));
56     double b = (rand()/(RAND_MAX+1.0));
57     mDefaultLUTColor->SetTableValue(i, r, v, b);
58     //    std::cout << "mDefaultLUTColor->SetTableValue(" << i << ", " << r << ", " << v << ", " << b << ");" << std::endl;
59   }
60 #include "vvDefaultLut.h"
61
62   // Add input selector
63   AddInputSelector("Select image");
64 }
65 //------------------------------------------------------------------------------
66
67
68 //------------------------------------------------------------------------------
69 vvToolStructureSetManager::~vvToolStructureSetManager()
70 {
71   DD("vvToolStructureSetManager DESTRUCTOR");
72 }
73 //------------------------------------------------------------------------------
74
75
76 //------------------------------------------------------------------------------
77 void vvToolStructureSetManager::Initialize()
78 {
79   SetToolName("StructureSetManager");
80   SetToolMenuName("StructureSet");
81   SetToolIconFilename(":/common/icons/ducky.png");
82   SetToolTip("Display Structure Set.");
83   SetToolExperimental(true);
84 }
85 //------------------------------------------------------------------------------
86
87
88 //------------------------------------------------------------------------------
89 void vvToolStructureSetManager::InputIsSelected(vvSlicerManager *m)
90 {
91   // Hide the input selector
92   QList<int> s;
93   s.push_back(0);
94   s.push_back(1);
95   splitter->setSizes(s);
96   // Connect open menus
97   //  connect(mOpenComboBox, SIGNAL(activated(int)), this, SLOT(open(int)));
98
99   connect(mOpenBinaryButton, SIGNAL(clicked()), this, SLOT(openBinaryImage()));
100
101   DD(mCurrentImage->GetNumberOfDimensions());
102
103   // Seems that the following is not needed to refresh ...
104   //  connect(m, SIGNAL(LeftButtonReleaseSignal(int)), SLOT(LeftButtonReleaseEvent(int)));
105
106   connect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(selectedItemChangedInTree()));
107   connect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(visibleROIToggled(bool)));
108   connect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(opacityChanged(int)));
109   connect(mChangeColorButton, SIGNAL(clicked()), this, SLOT(changeColor()));
110 }
111 //------------------------------------------------------------------------------
112
113
114 //------------------------------------------------------------------------------
115 void vvToolStructureSetManager::LeftButtonReleaseEvent(int slicer)
116 {
117   DD("vvToolStructureSetManager::UpdateSlice");
118   //DD(slicer);
119   //DD(view);
120   //DD(slices);
121   for(int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
122     if (i != slicer);
123     mCurrentSlicerManager->GetSlicer(i)->GetRenderWindow()->Render();
124   }
125 }
126 //------------------------------------------------------------------------------
127
128
129 //------------------------------------------------------------------------------
130 void vvToolStructureSetManager::open(int type)
131 {
132   DD(type);
133   switch (type) {
134   case 0:
135     openBinaryImage();
136     return; // Open binary image;
137   case 1:
138     DD("TODO");
139     return; // Open DICOM RT
140   case 2:
141     DD("TODO");
142     return; // Open mesh
143   default:
144     std::cerr << "Error ????" << std::endl;
145     exit(0);
146   }
147 }
148 //------------------------------------------------------------------------------
149
150
151 //------------------------------------------------------------------------------
152 void vvToolStructureSetManager::addRoiInTreeWidget(clitk::DicomRT_ROI * roi, QTreeWidgetItem * ww)
153 {
154   QTreeWidgetItem * w = new QTreeWidgetItem(ww);
155   w->setText(0, QString("%1").arg(roi->GetROINumber()));
156   w->setText(1, QString("%1").arg(roi->GetName().c_str()));
157   QBrush brush(QColor(roi->GetDisplayColor()[0]*255, roi->GetDisplayColor()[1]*255, roi->GetDisplayColor()[2]*255));
158   brush.setStyle(Qt::SolidPattern);
159   for(int i=0; i<w->columnCount (); i++) {
160     w->setBackground(i, brush);
161   }
162   mMapROIToTreeWidget[roi] = w;
163   mMapTreeWidgetToROI[w] = roi;
164   // Connect ROI TreeWidget
165   // TODO
166 }
167 //------------------------------------------------------------------------------
168
169
170 //------------------------------------------------------------------------------
171 void vvToolStructureSetManager::updateStructureSetInTreeWidget(int index, clitk::DicomRT_StructureSet * s)
172 {
173   QTreeWidgetItem * ss;
174   if (mMapStructureSetIndexToTreeWidget.find(index) == mMapStructureSetIndexToTreeWidget.end()) {
175     // Main row item
176     ss = new QTreeWidgetItem(mTree);
177     //  ss->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsTristate);
178     ss->setText(0, QString("S%1").arg(index));
179     ss->setText(1, QString("%1").arg(s->GetLabel().c_str()));
180     // Insert in list
181     mMapStructureSetIndexToTreeWidget[index] = ss;
182
183     // Connect Structure TreeWidget
184     // TODO
185   } else ss = mMapStructureSetIndexToTreeWidget[index];
186
187   // Insert ROI
188   const std::vector<clitk::DicomRT_ROI*> & rois = s->GetListOfROI();
189   for(unsigned int i=0; i<rois.size(); i++) {
190     if (mMapROIToTreeWidget.find(rois[i]) == mMapROIToTreeWidget.end())
191       addRoiInTreeWidget(rois[i], ss);
192   }
193 }
194 //------------------------------------------------------------------------------
195
196
197 //------------------------------------------------------------------------------
198 int vvToolStructureSetManager::addStructureSet(clitk::DicomRT_StructureSet * mStructureSet)
199 {
200
201   // Create actor for this SS
202   vvStructureSetActor * mStructureSetActor = new vvStructureSetActor;
203   mStructureSetActor->SetStructureSet(mStructureSet);
204   mStructureSetActor->SetSlicerManager(mCurrentSlicerManager);
205
206   // Insert in lists and get index
207   mStructureSetsList.push_back(mStructureSet);
208   mStructureSetActorsList.push_back(mStructureSetActor);
209   int index = mStructureSetsList.size()-1;
210
211   // Return index
212   return index;
213 }
214 //------------------------------------------------------------------------------
215
216
217 //------------------------------------------------------------------------------
218 void vvToolStructureSetManager::openBinaryImage()
219 {
220   DD("openBinaryImage");
221   // Select current StructureSet (or create)
222   int index;
223   DD(mCurrentStructureSetIndex);
224   if (mCurrentStructureSet == NULL) {
225     if (mStructureSetsList.size() == 0) { // Create a default SS
226       clitk::DicomRT_StructureSet * mStructureSet = new clitk::DicomRT_StructureSet;
227       index = addStructureSet(mStructureSet);
228       DD(index);
229     } else { // Get first SS
230       index = 0;
231     }
232   } else {
233     index = mCurrentStructureSetIndex;
234   }
235   DD(index);
236   // TODO -> SET THIS SS AS CURRENT
237   mCurrentStructureSet = mStructureSetsList[index];
238   mCurrentStructureSetActor = mStructureSetActorsList[index];
239   mCurrentStructureSetIndex = index;
240   DD(mCurrentStructureSetIndex);
241   DD(mCurrentStructureSet->GetName());
242
243   // Open images
244   QString Extensions = "Images files ( *.mhd *.hdr *.his)";
245   Extensions += ";;All Files (*)";
246   QStringList filename =
247     QFileDialog::getOpenFileNames(this,tr("Open binary image"),
248                                   mMainWindowBase->GetInputPathName(),Extensions);
249   if (filename.size() == 0) return;
250
251   std::vector<int> mLoadedROIIndex;
252   for(int i=0; i<filename.size(); i++) {
253     DD(filename[i].toStdString());
254
255     // Open Image
256     //init the progress events
257     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
258     vvImageReader * mReader = new vvImageReader;
259     std::vector<std::string> filenames;
260     filenames.push_back(filename[i].toStdString());
261     mReader->SetInputFilenames(filenames);
262     mReader->Update(IMAGE);
263     QApplication::restoreOverrideCursor();
264
265     if (mReader->GetLastError().size() != 0) {
266       std::cerr << "Error while reading " << filename[i].toStdString() << std::endl;
267       QString error = "Cannot open file \n";
268       error += mReader->GetLastError().c_str();
269       QMessageBox::information(this,tr("Reading problem"),error);
270       delete mReader;
271       return;
272     }
273     vvImage::Pointer binaryImage = mReader->GetOutput();
274     //  delete mReader;
275
276     // Check Dimension
277     int dim = mCurrentImage->GetNumberOfDimensions();
278     DD(dim);
279     int bin_dim = binaryImage->GetNumberOfDimensions();
280     DD(bin_dim);
281     if (dim < bin_dim) {  ////////// TO CHANGE FOR 3D/4D
282       std::ostringstream os;
283       os << "Error. Loaded binary image is " << bin_dim
284          << "D while selected image is " << dim << "D" << std::endl;
285       QMessageBox::information(this,tr("Reading problem"),os.str().c_str());
286       return;
287     }
288
289     // Add a new roi to the structure
290     int n = mCurrentStructureSet->AddBinaryImageAsNewROI(binaryImage, filename[i].toStdString());
291     //DD(n);
292     mLoadedROIIndex.push_back(n);
293
294     mCurrentStructureSet->GetROI(n)->SetBackgroundValueLabelImage(mBackgroundValueSpinBox->value());
295
296     // Change color NEED DEFAULT COLOR LIST
297     DD(mDefaultLUTColor->GetNumberOfTableValues ());
298     if (n<mDefaultLUTColor->GetNumberOfTableValues ()) {
299       double * color = mDefaultLUTColor->GetTableValue(n % mDefaultLUTColor->GetNumberOfTableValues ());
300       DD(color[0]);
301       DD(color[1]);
302       DD(color[2]);
303       mCurrentStructureSet->GetROI(n)->SetDisplayColor(color[0], color[1], color[2]);
304     }
305
306     // Add a new roi actor
307     mCurrentStructureSetActor->CreateNewROIActor(n);
308   } // end loop on n selected filenames
309
310   // Update the TreeWidget
311   updateStructureSetInTreeWidget(index, mCurrentStructureSet);
312
313   // Render loaded ROIs (the first is sufficient)
314   for(unsigned int i=0; i<mLoadedROIIndex.size(); i++) {
315     mCurrentStructureSetActor->GetROIActor(mLoadedROIIndex[i])->Update();
316   }
317   for(int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
318     mCurrentSlicerManager->GetSlicer(i)->Render();
319   }
320 }
321 //------------------------------------------------------------------------------
322
323
324 //------------------------------------------------------------------------------
325 void vvToolStructureSetManager::apply()
326 {
327   close();
328 }
329 //------------------------------------------------------------------------------
330
331
332
333 //------------------------------------------------------------------------------
334 // CURRENT ROI INTERACTION
335 //------------------------------------------------------------------------------
336
337
338 //------------------------------------------------------------------------------
339 void vvToolStructureSetManager::selectedItemChangedInTree()
340 {
341   DD("selectedItemChangedInTree");
342
343   // Search which roi is selected
344   QList<QTreeWidgetItem *> l = mTree->selectedItems();
345   DD(l.size());
346   QTreeWidgetItem * w = l[0];
347   if (mMapTreeWidgetToROI.find(w) == mMapTreeWidgetToROI.end()) {
348     mCurrentROIActor = NULL;
349     mCurrentROI = NULL;
350     mGroupBoxROI->setEnabled(false);
351     return; // Search for SS (first)
352   }
353   clitk::DicomRT_ROI * roi = mMapTreeWidgetToROI[w];
354   //  DD(roi->GetName());
355
356   // Get selected roi actor
357   if (mCurrentROIActor != NULL) {
358     mCurrentROIActor->SetSelected(false);
359     mCurrentROIActor->Update();
360   }
361
362   vvROIActor * actor = mStructureSetActorsList[mCurrentStructureSetIndex]->GetROIActor(roi->GetROINumber());
363   mCurrentROI = roi;
364   mCurrentROIActor = actor;
365
366   // Update GUI
367   mGroupBoxROI->setEnabled(true);
368   mROInameLabel->setText(roi->GetName().c_str());
369   mCheckBoxShow->setChecked(actor->IsVisible());
370
371   // Warning -> avoir unuseful Render here by disconnect slider
372   //
373   disconnect(mOpacitySlider, SIGNAL(valueChanged(int)),
374              this, SLOT(opacityChanged(int)));
375   mOpacitySlider->setValue((int)lrint(actor->GetOpacity()*100));
376   mOpacitySpinBox->setValue((int)lrint(actor->GetOpacity()*100));
377   connect(mOpacitySlider, SIGNAL(valueChanged(int)),
378           this, SLOT(opacityChanged(int)));
379
380   actor->SetSelected(true); // remove old selection
381   // The following must not render !!
382   DD("before update");
383   actor->Update(); // To change in UpdateSelecte
384   DD("after update");
385
386   mCurrentSlicerManager->Render();
387 }
388 //------------------------------------------------------------------------------
389
390
391 //------------------------------------------------------------------------------
392 void vvToolStructureSetManager::visibleROIToggled(bool b)
393 {
394   mCurrentROIActor->SetVisible(b);
395 }
396 //------------------------------------------------------------------------------
397
398
399 //------------------------------------------------------------------------------
400 void vvToolStructureSetManager::opacityChanged(int v)
401 {
402   mCurrentROIActor->SetOpacity((double)v/100.0);
403   mCurrentROIActor->UpdateColor();
404   mCurrentSlicerManager->Render();
405 }
406 //------------------------------------------------------------------------------
407
408
409 //------------------------------------------------------------------------------
410 void vvToolStructureSetManager::changeColor()
411 {
412   QColor color;
413   color.setRgbF(mCurrentROIActor->GetROI()->GetDisplayColor()[0],
414                 mCurrentROIActor->GetROI()->GetDisplayColor()[1],
415                 mCurrentROIActor->GetROI()->GetDisplayColor()[2]);
416   QColor c = QColorDialog::getColor(color, this, "Choose the ROI color");
417   mCurrentROIActor->GetROI()->SetDisplayColor(c.redF(), c.greenF(), c.blueF());
418   mCurrentROIActor->UpdateColor();
419
420   QTreeWidgetItem * w = mMapROIToTreeWidget[mCurrentROI];
421   QBrush brush(QColor(mCurrentROI->GetDisplayColor()[0]*255,
422                       mCurrentROI->GetDisplayColor()[1]*255,
423                       mCurrentROI->GetDisplayColor()[2]*255));
424   brush.setStyle(Qt::SolidPattern);
425   for(int i=0; i<w->columnCount (); i++) {
426     w->setBackground(i, brush);
427   }
428 }
429 //------------------------------------------------------------------------------
430
431
432
433 //------------------------------------------------------------------------------
434 //void vvToolStructureSetManager::getActorFromROI() {
435 //  mStructureSetActorsList[mCurrentStructureSetIndex]->GetROIActor(n);
436 //}
437 //------------------------------------------------------------------------------
438
439