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() {
44 Ui_vvToolStructureSetManager::setupUi(mToolWidget);
46 mCurrentStructureSet = NULL;
47 mCurrentStructureSetIndex = -1;
48 mGroupBoxROI->setEnabled(false);
49 mCurrentROIActor = NULL;
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;
59 #include "vvDefaultLut.h"
62 AddInputSelector("Select image");
64 //------------------------------------------------------------------------------
67 //------------------------------------------------------------------------------
68 vvToolStructureSetManager::~vvToolStructureSetManager() {
69 DD("vvToolStructureSetManager DESTRUCTOR");
71 //------------------------------------------------------------------------------
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);
82 //------------------------------------------------------------------------------
85 //------------------------------------------------------------------------------
86 void vvToolStructureSetManager::InputIsSelected(vvSlicerManager *m) {
87 // Hide the input selector
91 splitter->setSizes(s);
93 // connect(mOpenComboBox, SIGNAL(activated(int)), this, SLOT(open(int)));
95 connect(mOpenBinaryButton, SIGNAL(clicked()), this, SLOT(openBinaryImage()));
97 DD(mCurrentImage->GetNumberOfDimensions());
99 // Seems that the following is not needed to refresh ...
100 // connect(m, SIGNAL(LeftButtonReleaseSignal(int)), SLOT(LeftButtonReleaseEvent(int)));
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()));
107 //------------------------------------------------------------------------------
110 //------------------------------------------------------------------------------
111 void vvToolStructureSetManager::LeftButtonReleaseEvent(int slicer) {
112 DD("vvToolStructureSetManager::UpdateSlice");
116 for(int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
118 mCurrentSlicerManager->GetSlicer(i)->GetRenderWindow()->Render();
121 //------------------------------------------------------------------------------
124 //------------------------------------------------------------------------------
125 void vvToolStructureSetManager::open(int 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);
134 //------------------------------------------------------------------------------
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);
147 mMapROIToTreeWidget[roi] = w;
148 mMapTreeWidgetToROI[w] = roi;
149 // Connect ROI TreeWidget
152 //------------------------------------------------------------------------------
155 //------------------------------------------------------------------------------
156 void vvToolStructureSetManager::updateStructureSetInTreeWidget(int index, clitk::DicomRT_StructureSet * s) {
157 QTreeWidgetItem * ss;
158 if (mMapStructureSetIndexToTreeWidget.find(index) == mMapStructureSetIndexToTreeWidget.end()) {
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()));
165 mMapStructureSetIndexToTreeWidget[index] = ss;
167 // Connect Structure TreeWidget
170 else ss = mMapStructureSetIndexToTreeWidget[index];
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);
179 //------------------------------------------------------------------------------
182 //------------------------------------------------------------------------------
183 int vvToolStructureSetManager::addStructureSet(clitk::DicomRT_StructureSet * mStructureSet) {
185 // Create actor for this SS
186 vvStructureSetActor * mStructureSetActor = new vvStructureSetActor;
187 mStructureSetActor->SetStructureSet(mStructureSet);
188 mStructureSetActor->SetSlicerManager(mCurrentSlicerManager);
190 // Insert in lists and get index
191 mStructureSetsList.push_back(mStructureSet);
192 mStructureSetActorsList.push_back(mStructureSetActor);
193 int index = mStructureSetsList.size()-1;
198 //------------------------------------------------------------------------------
201 //------------------------------------------------------------------------------
202 void vvToolStructureSetManager::openBinaryImage() {
203 DD("openBinaryImage");
204 // Select current StructureSet (or create)
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);
213 else { // Get first SS
218 index = mCurrentStructureSetIndex;
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());
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;
236 std::vector<int> mLoadedROIIndex;
237 for(int i=0; i<filename.size(); i++) {
238 DD(filename[i].toStdString());
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();
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);
258 vvImage::Pointer binaryImage = mReader->GetOutput();
262 int dim = mCurrentImage->GetNumberOfDimensions();
264 int bin_dim = binaryImage->GetNumberOfDimensions();
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());
274 // Add a new roi to the structure
275 int n = mCurrentStructureSet->AddBinaryImageAsNewROI(binaryImage, filename[i].toStdString());
277 mLoadedROIIndex.push_back(n);
279 mCurrentStructureSet->GetROI(n)->SetBackgroundValueLabelImage(mBackgroundValueSpinBox->value());
281 // Change color NEED DEFAULT COLOR LIST
282 DD(mDefaultLUTColor->GetNumberOfTableValues ());
283 if (n<mDefaultLUTColor->GetNumberOfTableValues ()) {
284 double * color = mDefaultLUTColor->GetTableValue(n % mDefaultLUTColor->GetNumberOfTableValues ());
288 mCurrentStructureSet->GetROI(n)->SetDisplayColor(color[0], color[1], color[2]);
291 // Add a new roi actor
292 mCurrentStructureSetActor->CreateNewROIActor(n);
293 } // end loop on n selected filenames
295 // Update the TreeWidget
296 updateStructureSetInTreeWidget(index, mCurrentStructureSet);
298 // Render loaded ROIs (the first is sufficient)
299 for(unsigned int i=0; i<mLoadedROIIndex.size(); i++) {
300 mCurrentStructureSetActor->GetROIActor(mLoadedROIIndex[i])->Update();
302 for(int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
303 mCurrentSlicerManager->GetSlicer(i)->Render();
306 //------------------------------------------------------------------------------
309 //------------------------------------------------------------------------------
310 void vvToolStructureSetManager::apply() {
313 //------------------------------------------------------------------------------
317 //------------------------------------------------------------------------------
318 // CURRENT ROI INTERACTION
319 //------------------------------------------------------------------------------
322 //------------------------------------------------------------------------------
323 void vvToolStructureSetManager::selectedItemChangedInTree() {
324 DD("selectedItemChangedInTree");
326 // Search which roi is selected
327 QList<QTreeWidgetItem *> l = mTree->selectedItems();
329 QTreeWidgetItem * w = l[0];
330 if (mMapTreeWidgetToROI.find(w) == mMapTreeWidgetToROI.end()) {
331 mCurrentROIActor = NULL;
333 mGroupBoxROI->setEnabled(false);
334 return; // Search for SS (first)
336 clitk::DicomRT_ROI * roi = mMapTreeWidgetToROI[w];
337 // DD(roi->GetName());
339 // Get selected roi actor
340 if (mCurrentROIActor != NULL) {
341 mCurrentROIActor->SetSelected(false);
342 mCurrentROIActor->Update();
345 vvROIActor * actor = mStructureSetActorsList[mCurrentStructureSetIndex]->GetROIActor(roi->GetROINumber());
347 mCurrentROIActor = actor;
350 mGroupBoxROI->setEnabled(true);
351 mROInameLabel->setText(roi->GetName().c_str());
352 mCheckBoxShow->setChecked(actor->IsVisible());
354 // Warning -> avoir unuseful Render here by disconnect slider
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)));
363 actor->SetSelected(true); // remove old selection
364 // The following must not render !!
366 actor->Update(); // To change in UpdateSelecte
369 mCurrentSlicerManager->Render();
371 //------------------------------------------------------------------------------
374 //------------------------------------------------------------------------------
375 void vvToolStructureSetManager::visibleROIToggled(bool b) {
376 mCurrentROIActor->SetVisible(b);
378 //------------------------------------------------------------------------------
381 //------------------------------------------------------------------------------
382 void vvToolStructureSetManager::opacityChanged(int v) {
383 mCurrentROIActor->SetOpacity((double)v/100.0);
384 mCurrentROIActor->UpdateColor();
385 mCurrentSlicerManager->Render();
387 //------------------------------------------------------------------------------
390 //------------------------------------------------------------------------------
391 void vvToolStructureSetManager::changeColor() {
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();
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);
409 //------------------------------------------------------------------------------
413 //------------------------------------------------------------------------------
414 //void vvToolStructureSetManager::getActorFromROI() {
415 // mStructureSetActorsList[mCurrentStructureSetIndex]->GetROIActor(n);
417 //------------------------------------------------------------------------------