]> Creatis software - clitk.git/blob - vv/vvToolROIManager.cxx
First version that allow to open file (no button feedback yet)
[clitk.git] / vv / vvToolROIManager.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 // vv
20 #include "vvToolROIManager.h"
21 #include "vvImageReader.h"
22 #include "vvROIActor.h"
23 #include "vvSlicer.h"
24 #include "vvROIActor.h"
25
26 // Qt
27 #include <QFileDialog>
28 #include <QMessageBox>
29 #include <QColorDialog>
30 #include <QAbstractEventDispatcher>
31  
32 // vtk
33 #include <vtkLookupTable.h>
34 #include <vtkRenderWindow.h>
35
36 //------------------------------------------------------------------------------
37 // Create the tool and automagically (I like this word) insert it in
38 // the main window menu.
39 ADD_TOOL(vvToolROIManager);
40 //------------------------------------------------------------------------------
41
42 //------------------------------------------------------------------------------
43 vvToolROIManager::vvToolROIManager(vvMainWindowBase * parent, Qt::WindowFlags f):
44   // vvToolWidgetBase(parent, f), 
45   // if Qt::Widget -> No dialog in this case (in tab) ; PB = "invisible widget on menu" !
46   // if "f" normal widget
47   QWidget(parent->GetTab()->widget(4)), 
48   vvToolBase<vvToolROIManager>(parent),
49   Ui::vvToolROIManager()
50 {
51   //  Insert the current QWidget into the tab layout (required)
52   QWidget * mother = qFindChild<QWidget*>(parent->GetTab(), "ROItab");
53   mother->layout()->addWidget(this);
54   mMainWindow = parent;
55   
56   // Build the UI
57   Ui_vvToolROIManager::setupUi(this);
58   setAttribute(Qt::WA_DeleteOnClose);
59   mTree->clear();
60   mTree->header()->resizeSection(0, 30);
61   parent->GetTab()->setCurrentIndex(2);
62
63   // Set default LUT
64   mDefaultLUTColor = vtkSmartPointer<vtkLookupTable>::New();
65   DD(mDefaultLUTColor->GetNumberOfTableValues());
66   for(int i=0; i<mDefaultLUTColor->GetNumberOfTableValues(); i++) {
67     double r = (rand()/(RAND_MAX+1.0));
68     double v = (rand()/(RAND_MAX+1.0));
69     double b = (rand()/(RAND_MAX+1.0));
70     mDefaultLUTColor->SetTableValue(i, r, v, b);
71     //    std::cout << "mDefaultLUTColor->SetTableValue(" << i << ", " << r << ", " << v << ", " << b << ");" << std::endl;
72   }
73 #include "vvDefaultLut.h"
74
75   // Initialization
76   mNumberOfVisibleROI = 0;
77   mNumberOfVisibleContourROI = 0;
78
79   // Select the current image as the target
80   int i = parent->GetSlicerManagerCurrentIndex();
81   InputIsSelected(parent->GetSlicerManagers()[i]);
82
83   // Connect event from mainwindow to this widget
84   connect(parent, SIGNAL(AnImageIsBeingClosed(vvSlicerManager *)), 
85           this, SLOT(AnImageIsBeingClosed(vvSlicerManager *)));
86   connect(parent, SIGNAL(SelectedImageHasChanged(vvSlicerManager *)), 
87           this, SLOT(SelectedImageHasChanged(vvSlicerManager *)));
88
89   // mMainWindowBase->GetTab()->setTabIcon(mTabNumber, GetToolIcon());
90 }
91 //------------------------------------------------------------------------------
92
93
94 //------------------------------------------------------------------------------
95 vvToolROIManager::~vvToolROIManager()
96 {
97   std::cout << "vvToolROIManager::~vvToolROIManager()" << std::endl;
98 }
99 //------------------------------------------------------------------------------
100
101
102 //------------------------------------------------------------------------------
103 // STATIC
104 void vvToolROIManager::Initialize() {
105   SetToolName("ROIManager");
106   SetToolMenuName("Display ROI (binary image)");
107   SetToolIconFilename(":/common/icons/tool-roi.png");
108   SetToolTip("Display ROI from a binary image.");
109   SetToolExperimental(true);
110 }
111 //------------------------------------------------------------------------------
112
113
114 //------------------------------------------------------------------------------
115 void vvToolROIManager::InputIsSelected(vvSlicerManager *m)
116 {
117   std::cout << "vvToolROIManager::InputIsSelected()" << std::endl;
118   mSlicerManager = m;
119
120   // Signal/slot
121   connect(mCloseButton, SIGNAL(clicked()), this, SLOT(close()));
122
123   // Initialization
124   mSlicerManager = m;
125   mCurrentImage = mSlicerManager->GetImage();
126
127   // Refuse if 4D
128   if (mCurrentImage->GetNumberOfDimensions() != 3) {
129     QMessageBox::information(this,tr("Sorry only 3D yet"), tr("Sorry only 3D yet"));
130     close();
131     return;
132   }
133
134   // Auto diusplay browser to select new contours 
135   OpenBinaryImage();
136 }
137 //------------------------------------------------------------------------------
138
139
140 //------------------------------------------------------------------------------
141 void vvToolROIManager::AnImageIsBeingClosed(vvSlicerManager * m)
142 {
143   if (m == mSlicerManager) close();
144 }
145 //------------------------------------------------------------------------------
146
147
148 //------------------------------------------------------------------------------
149 void vvToolROIManager::SelectedImageHasChanged(vvSlicerManager * m) {
150   if (m != mSlicerManager) hide();
151   else show();
152 }
153 //------------------------------------------------------------------------------
154
155
156 //------------------------------------------------------------------------------
157 void vvToolROIManager::OpenBinaryImage() 
158 {
159   // Open images
160   QString Extensions = "Images files ( *.mha *.mhd *.hdr *.his)";
161   Extensions += ";;All Files (*)";
162   QStringList filename =
163     QFileDialog::getOpenFileNames(this,tr("Open binary image"),
164                                   mMainWindowBase->GetInputPathName(),Extensions);
165   if (filename.size() == 0) return;
166   
167   // For each selected file, open the image
168   for(int i=0; i<filename.size(); i++) {
169     // Open Image
170     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
171     vvImageReader::Pointer reader = vvImageReader::New();
172     std::vector<std::string> filenames;
173     filenames.push_back(filename[i].toStdString());
174     reader->SetInputFilenames(filenames);
175     reader->Update(vvImageReader::IMAGE);
176     QApplication::restoreOverrideCursor();
177
178     if (reader->GetLastError().size() != 0) {
179       std::cerr << "Error while reading " << filename[i].toStdString() << std::endl;
180       QString error = "Cannot open file \n";
181       error += reader->GetLastError().c_str();
182       QMessageBox::information(this,tr("Reading problem"),error);
183       return;
184     }
185     vvImage::Pointer binaryImage = reader->GetOutput();
186     AddImage(binaryImage, filename[i].toStdString(), mBackgroundValueSpinBox->value(),
187              (!mBGModeCheckBox->isChecked()));
188     mOpenedBinaryImage.push_back(binaryImage);
189   }
190
191   // Update the contours
192   UpdateAllContours(); 
193 }
194 //------------------------------------------------------------------------------
195
196
197 //------------------------------------------------------------------------------
198 void vvToolROIManager::AddImage(vvImage * binaryImage, std::string filename, 
199                                 double BG, bool modeBG) 
200 {
201   DD(modeBG);
202
203   // Check Dimension
204   int dim = mCurrentImage->GetNumberOfDimensions();
205   int bin_dim = binaryImage->GetNumberOfDimensions();
206   if (dim < bin_dim) {
207     std::ostringstream os;
208     os << "Error. Loaded binary image is " << bin_dim
209        << "D while selected image is " << dim << "D" << std::endl;
210     QMessageBox::information(this,tr("Reading problem"),os.str().c_str());
211     return;
212   }
213   
214   // Compute roi index
215   int n = mROIList.size();
216   DD(n);
217   
218   // Compute the name of the new ROI
219   std::ostringstream oss;
220   oss << vtksys::SystemTools::GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(filename));
221   std::string name = oss.str();
222   DD(name);
223   
224   // Set color
225   std::vector<double> color;
226   color.push_back(1);
227   color.push_back(0);
228   color.push_back(0);
229
230   // Create ROI
231   clitk::DicomRT_ROI::Pointer roi = clitk::DicomRT_ROI::New();
232   roi->SetFromBinaryImage(binaryImage, n, name, color, filename);
233
234   // Add a new roi to the list
235   mROIList.push_back(roi);
236  
237   // Set BG or FG mode
238   if (modeBG) 
239     roi->SetBackgroundValueLabelImage(BG);
240   else 
241     roi->SetForegroundValueLabelImage(BG);
242   
243   // Change color
244   DD("color");
245   if (n<mDefaultLUTColor->GetNumberOfTableValues ()) {
246     double * color = mDefaultLUTColor->GetTableValue(n % mDefaultLUTColor->GetNumberOfTableValues ());
247     roi->SetDisplayColor(color[0], color[1], color[2]);
248   }
249   
250   // Add a new roi actor
251   QSharedPointer<vvROIActor> actor = QSharedPointer<vvROIActor>(new vvROIActor);
252   actor->SetBGMode(modeBG);
253   actor->SetROI(roi);
254   actor->SetSlicerManager(mSlicerManager);
255   actor->Initialize(n+1); // depth is n+1 to start at 1
256   mROIActorsList.push_back(actor);
257   
258   // CheckBox for "All"
259   if (actor->IsVisible()) mNumberOfVisibleROI++;
260   if (actor->IsContourVisible()) mNumberOfVisibleContourROI++;
261   
262   // Add ROI in tree
263   mTreeWidgetList.push_back(QSharedPointer<QTreeWidgetItem>(new QTreeWidgetItem(mTree)));
264   QTreeWidgetItem * w = mTreeWidgetList.back().data();
265   w->setText(0, QString("%1").arg(roi->GetROINumber()));
266   w->setText(1, QString("%1").arg(roi->GetName().c_str()));
267   w->setText(3, QString("%1").arg(actor->GetDepth()));  
268   QBrush brush(QColor(roi->GetDisplayColor()[0]*255, 
269                       roi->GetDisplayColor()[1]*255, 
270                       roi->GetDisplayColor()[2]*255));
271   brush.setStyle(Qt::SolidPattern);
272   w->setBackground(2, brush);
273   mMapROIToTreeWidget[roi] = w;
274   mMapTreeWidgetToROI[w] = roi;
275   mTree->resizeColumnToContents(0);
276   mTree->resizeColumnToContents(1);
277
278   // Update 
279   UpdateAllROIStatus(); 
280 }
281 //------------------------------------------------------------------------------
282
283
284 //------------------------------------------------------------------------------
285 void vvToolROIManager::UpdateAllContours() 
286 {
287   // Render loaded ROIs (the first is sufficient)
288   for(unsigned int i=0; i<mROIList.size(); i++) {
289     mROIActorsList[i]->Update();
290   }
291   for(int i=0; i<mSlicerManager->GetNumberOfSlicers(); i++) {
292     mSlicerManager->GetSlicer(i)->Render();
293   }  
294 }
295 //------------------------------------------------------------------------------
296
297
298 //------------------------------------------------------------------------------
299 void vvToolROIManager::UpdateAllROIStatus() {
300   int nbVisible = 0;
301   int nb = mROIList.size();
302   for(int i=0; i<nb; i++) {
303     if (mROIActorsList[i]->IsVisible()) {
304       nbVisible++;
305     }
306   }
307   DD(nbVisible);
308
309   // change the states
310   disconnect(mCheckBoxShowAll, SIGNAL(stateChanged(int)), this, SLOT(AllVisibleROIToggled(int)));  
311   disconnect(mContourCheckBoxShowAll, SIGNAL(toggled(bool)), this, SLOT(AllVisibleContourROIToggled(bool)));
312   if (nbVisible == nb) mCheckBoxShowAll->setCheckState(Qt::Checked);
313   else {
314     if (nbVisible == 0) mCheckBoxShowAll->setCheckState(Qt::Unchecked);
315     else mCheckBoxShowAll->setCheckState(Qt::PartiallyChecked);
316   }
317   connect(mContourCheckBoxShowAll, SIGNAL(toggled(bool)), this, SLOT(AllVisibleContourROIToggled(bool)));
318   connect(mCheckBoxShowAll, SIGNAL(stateChanged(int)), this, SLOT(AllVisibleROIToggled(int)));
319 }
320 //------------------------------------------------------------------------------
321