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