1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
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
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.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ======================================================================-====*/
19 #include "vvToolStructureSetManager.h"
20 #include "vvImageReader.h"
21 #include "vvStructureSetActor.h"
23 #include "vvROIActor.h"
25 #include <QFileDialog>
26 #include <QMessageBox>
27 #include <QColorDialog>
29 #include <vtkLookupTable.h>
30 #include <vtkRenderWindow.h>
32 //------------------------------------------------------------------------------
33 // Create the tool and automagically (I like this word) insert it in
34 // the main window menu.
35 ADD_TOOL(vvToolStructureSetManager);
36 //------------------------------------------------------------------------------
38 //------------------------------------------------------------------------------
39 vvToolStructureSetManager::vvToolStructureSetManager(vvMainWindowBase * parent, Qt::WindowFlags f)
40 :vvToolWidgetBase(parent, f),
41 vvToolBase<vvToolStructureSetManager>(parent),
42 Ui::vvToolStructureSetManager()
45 Ui_vvToolStructureSetManager::setupUi(mToolWidget);
47 mCurrentStructureSet = NULL;
48 mCurrentStructureSetIndex = -1;
49 mGroupBoxROI->setEnabled(false);
50 mCurrentROIActor = NULL;
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;
60 #include "vvDefaultLut.h"
63 AddInputSelector("Select image");
65 //------------------------------------------------------------------------------
68 //------------------------------------------------------------------------------
69 vvToolStructureSetManager::~vvToolStructureSetManager()
71 DD("vvToolStructureSetManager DESTRUCTOR");
73 //------------------------------------------------------------------------------
76 //------------------------------------------------------------------------------
77 void vvToolStructureSetManager::Initialize()
79 SetToolName("StructureSetManager");
80 SetToolMenuName("StructureSet");
81 SetToolIconFilename(":/common/icons/ducky.png");
82 SetToolTip("Display Structure Set.");
83 SetToolExperimental(true);
85 //------------------------------------------------------------------------------
88 //------------------------------------------------------------------------------
89 void vvToolStructureSetManager::InputIsSelected(vvSlicerManager *m)
91 // Hide the input selector
95 splitter->setSizes(s);
97 // connect(mOpenComboBox, SIGNAL(activated(int)), this, SLOT(open(int)));
99 connect(mOpenBinaryButton, SIGNAL(clicked()), this, SLOT(openBinaryImage()));
101 DD(mCurrentImage->GetNumberOfDimensions());
103 // Seems that the following is not needed to refresh ...
104 // connect(m, SIGNAL(LeftButtonReleaseSignal(int)), SLOT(LeftButtonReleaseEvent(int)));
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()));
111 //------------------------------------------------------------------------------
114 //------------------------------------------------------------------------------
115 void vvToolStructureSetManager::LeftButtonReleaseEvent(int slicer)
117 DD("vvToolStructureSetManager::UpdateSlice");
121 for(int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
123 mCurrentSlicerManager->GetSlicer(i)->GetRenderWindow()->Render();
126 //------------------------------------------------------------------------------
129 //------------------------------------------------------------------------------
130 void vvToolStructureSetManager::open(int type)
136 return; // Open binary image;
139 return; // Open DICOM RT
144 std::cerr << "Error ????" << std::endl;
148 //------------------------------------------------------------------------------
151 //------------------------------------------------------------------------------
152 void vvToolStructureSetManager::addRoiInTreeWidget(clitk::DicomRT_ROI * roi, QTreeWidgetItem * ww)
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);
162 mMapROIToTreeWidget[roi] = w;
163 mMapTreeWidgetToROI[w] = roi;
164 // Connect ROI TreeWidget
167 //------------------------------------------------------------------------------
170 //------------------------------------------------------------------------------
171 void vvToolStructureSetManager::updateStructureSetInTreeWidget(int index, clitk::DicomRT_StructureSet * s)
173 QTreeWidgetItem * ss;
174 if (mMapStructureSetIndexToTreeWidget.find(index) == mMapStructureSetIndexToTreeWidget.end()) {
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()));
181 mMapStructureSetIndexToTreeWidget[index] = ss;
183 // Connect Structure TreeWidget
185 } else ss = mMapStructureSetIndexToTreeWidget[index];
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);
194 //------------------------------------------------------------------------------
197 //------------------------------------------------------------------------------
198 int vvToolStructureSetManager::addStructureSet(clitk::DicomRT_StructureSet * mStructureSet)
201 // Create actor for this SS
202 vvStructureSetActor * mStructureSetActor = new vvStructureSetActor;
203 mStructureSetActor->SetStructureSet(mStructureSet);
204 mStructureSetActor->SetSlicerManager(mCurrentSlicerManager);
206 // Insert in lists and get index
207 mStructureSetsList.push_back(mStructureSet);
208 mStructureSetActorsList.push_back(mStructureSetActor);
209 int index = mStructureSetsList.size()-1;
214 //------------------------------------------------------------------------------
217 //------------------------------------------------------------------------------
218 void vvToolStructureSetManager::openBinaryImage()
220 DD("openBinaryImage");
221 // Select current StructureSet (or create)
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);
229 } else { // Get first SS
233 index = mCurrentStructureSetIndex;
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());
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;
251 std::vector<int> mLoadedROIIndex;
252 for(int i=0; i<filename.size(); i++) {
253 DD(filename[i].toStdString());
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();
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);
273 vvImage::Pointer binaryImage = mReader->GetOutput();
277 int dim = mCurrentImage->GetNumberOfDimensions();
279 int bin_dim = binaryImage->GetNumberOfDimensions();
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());
289 // Add a new roi to the structure
290 int n = mCurrentStructureSet->AddBinaryImageAsNewROI(binaryImage, filename[i].toStdString());
292 mLoadedROIIndex.push_back(n);
294 mCurrentStructureSet->GetROI(n)->SetBackgroundValueLabelImage(mBackgroundValueSpinBox->value());
296 // Change color NEED DEFAULT COLOR LIST
297 DD(mDefaultLUTColor->GetNumberOfTableValues ());
298 if (n<mDefaultLUTColor->GetNumberOfTableValues ()) {
299 double * color = mDefaultLUTColor->GetTableValue(n % mDefaultLUTColor->GetNumberOfTableValues ());
303 mCurrentStructureSet->GetROI(n)->SetDisplayColor(color[0], color[1], color[2]);
306 // Add a new roi actor
307 mCurrentStructureSetActor->CreateNewROIActor(n);
308 } // end loop on n selected filenames
310 // Update the TreeWidget
311 updateStructureSetInTreeWidget(index, mCurrentStructureSet);
313 // Render loaded ROIs (the first is sufficient)
314 for(unsigned int i=0; i<mLoadedROIIndex.size(); i++) {
315 mCurrentStructureSetActor->GetROIActor(mLoadedROIIndex[i])->Update();
317 for(int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
318 mCurrentSlicerManager->GetSlicer(i)->Render();
321 //------------------------------------------------------------------------------
324 //------------------------------------------------------------------------------
325 void vvToolStructureSetManager::apply()
329 //------------------------------------------------------------------------------
333 //------------------------------------------------------------------------------
334 // CURRENT ROI INTERACTION
335 //------------------------------------------------------------------------------
338 //------------------------------------------------------------------------------
339 void vvToolStructureSetManager::selectedItemChangedInTree()
341 DD("selectedItemChangedInTree");
343 // Search which roi is selected
344 QList<QTreeWidgetItem *> l = mTree->selectedItems();
346 QTreeWidgetItem * w = l[0];
347 if (mMapTreeWidgetToROI.find(w) == mMapTreeWidgetToROI.end()) {
348 mCurrentROIActor = NULL;
350 mGroupBoxROI->setEnabled(false);
351 return; // Search for SS (first)
353 clitk::DicomRT_ROI * roi = mMapTreeWidgetToROI[w];
354 // DD(roi->GetName());
356 // Get selected roi actor
357 if (mCurrentROIActor != NULL) {
358 mCurrentROIActor->SetSelected(false);
359 mCurrentROIActor->Update();
362 vvROIActor * actor = mStructureSetActorsList[mCurrentStructureSetIndex]->GetROIActor(roi->GetROINumber());
364 mCurrentROIActor = actor;
367 mGroupBoxROI->setEnabled(true);
368 mROInameLabel->setText(roi->GetName().c_str());
369 mCheckBoxShow->setChecked(actor->IsVisible());
371 // Warning -> avoir unuseful Render here by disconnect slider
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)));
380 actor->SetSelected(true); // remove old selection
381 // The following must not render !!
383 actor->Update(); // To change in UpdateSelecte
386 mCurrentSlicerManager->Render();
388 //------------------------------------------------------------------------------
391 //------------------------------------------------------------------------------
392 void vvToolStructureSetManager::visibleROIToggled(bool b)
394 mCurrentROIActor->SetVisible(b);
396 //------------------------------------------------------------------------------
399 //------------------------------------------------------------------------------
400 void vvToolStructureSetManager::opacityChanged(int v)
402 mCurrentROIActor->SetOpacity((double)v/100.0);
403 mCurrentROIActor->UpdateColor();
404 mCurrentSlicerManager->Render();
406 //------------------------------------------------------------------------------
409 //------------------------------------------------------------------------------
410 void vvToolStructureSetManager::changeColor()
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();
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);
429 //------------------------------------------------------------------------------
433 //------------------------------------------------------------------------------
434 //void vvToolStructureSetManager::getActorFromROI() {
435 // mStructureSetActorsList[mCurrentStructureSetIndex]->GetROIActor(n);
437 //------------------------------------------------------------------------------