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"
24 #include <QFileDialog>
25 #include <QMessageBox>
26 #include <vtkLookupTable.h>
27 #include <vtkRenderWindow.h>
29 //------------------------------------------------------------------------------
30 // Create the tool and automagically (I like this word) insert it in
31 // the main window menu.
32 ADD_TOOL(vvToolStructureSetManager);
33 //------------------------------------------------------------------------------
35 //------------------------------------------------------------------------------
36 vvToolStructureSetManager::vvToolStructureSetManager(vvMainWindowBase * parent, Qt::WindowFlags f)
37 :vvToolWidgetBase(parent, f),
38 vvToolBase<vvToolStructureSetManager>(parent),
39 Ui::vvToolStructureSetManager() {
41 Ui_vvToolStructureSetManager::setupUi(mToolWidget);
43 mCurrentStructureSet = NULL;
45 mDefaultLUTColor = vtkLookupTable::New();
46 for(unsigned int i=0; i<mDefaultLUTColor->GetNumberOfTableValues(); i++) {
47 double r = (rand()/(RAND_MAX+1.0));
48 double v = (rand()/(RAND_MAX+1.0));
49 double b = (rand()/(RAND_MAX+1.0));
50 mDefaultLUTColor->SetTableValue(i, r, v, b);
51 // std::cout << "mDefaultLUTColor->SetTableValue(" << i << ", " << r << ", " << v << ", " << b << ");" << std::endl;
53 #include "vvDefaultLut.h"
56 AddInputSelector("Select image");
58 //------------------------------------------------------------------------------
61 //------------------------------------------------------------------------------
62 vvToolStructureSetManager::~vvToolStructureSetManager() {
63 DD("vvToolStructureSetManager DESTRUCTOR");
65 //------------------------------------------------------------------------------
68 //------------------------------------------------------------------------------
69 void vvToolStructureSetManager::Initialize() {
70 SetToolName("StructureSetManager");
71 SetToolMenuName("StructureSet");
72 SetToolIconFilename(":/common/icons/ducky.png");
73 SetToolTip("Display Structure Set.");
74 SetToolExperimental(true);
76 //------------------------------------------------------------------------------
79 //------------------------------------------------------------------------------
80 void vvToolStructureSetManager::InputIsSelected(vvSlicerManager *m) {
81 // Hide the input selector
85 splitter->setSizes(s);
87 // connect(mOpenComboBox, SIGNAL(activated(int)), this, SLOT(open(int)));
89 connect(mOpenBinaryButton, SIGNAL(clicked()), this, SLOT(openBinaryImage()));
91 DD(mCurrentImage->GetNumberOfDimensions());
93 // Seems that the following is not needed to refresh ...
94 // connect(m, SIGNAL(LeftButtonReleaseSignal(int)), SLOT(LeftButtonReleaseEvent(int)));
96 connect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(selectedItemChangedInTree()));
97 connect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(visibleROIToggled(bool)));
98 connect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(opacityChanged(int)));
100 //------------------------------------------------------------------------------
103 //------------------------------------------------------------------------------
104 void vvToolStructureSetManager::LeftButtonReleaseEvent(int slicer) {
105 DD("vvToolStructureSetManager::UpdateSlice");
109 for(int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
111 mCurrentSlicerManager->GetSlicer(i)->GetRenderWindow()->Render();
114 //------------------------------------------------------------------------------
117 //------------------------------------------------------------------------------
118 void vvToolStructureSetManager::open(int type) {
121 case 0: openBinaryImage(); return; // Open binary image;
122 case 1: DD("TODO"); return; // Open DICOM RT
123 case 2: DD("TODO"); return; // Open mesh
124 default: std::cerr << "Error ????" << std::endl; exit(0);
127 //------------------------------------------------------------------------------
130 //------------------------------------------------------------------------------
131 void vvToolStructureSetManager::addRoiInTreeWidget(clitk::DicomRT_ROI * roi, QTreeWidgetItem * ww) {
132 QTreeWidgetItem * w = new QTreeWidgetItem(ww);
133 w->setText(0, QString("%1").arg(roi->GetROINumber()));
134 w->setText(1, QString("%1").arg(roi->GetName().c_str()));
135 QBrush brush(QColor(roi->GetDisplayColor()[0]*255, roi->GetDisplayColor()[1]*255, roi->GetDisplayColor()[2]*255));
136 brush.setStyle(Qt::SolidPattern);
137 for(int i=0; i<w->columnCount (); i++) {
138 w->setBackground(i, brush);
140 mMapROIToTreeWidget[roi] = w;
141 mMapTreeWidgetToROI[w] = roi;
142 // Connect ROI TreeWidget
145 //------------------------------------------------------------------------------
148 //------------------------------------------------------------------------------
149 void vvToolStructureSetManager::updateStructureSetInTreeWidget(int index, clitk::DicomRT_StructureSet * s) {
150 QTreeWidgetItem * ss;
151 if (mMapStructureSetIndexToTreeWidget.find(index) == mMapStructureSetIndexToTreeWidget.end()) {
153 ss = new QTreeWidgetItem(mTree);
154 // ss->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsTristate);
155 ss->setText(0, QString("S%1").arg(index));
156 ss->setText(1, QString("%1").arg(s->GetLabel().c_str()));
158 mMapStructureSetIndexToTreeWidget[index] = ss;
160 // Connect Structure TreeWidget
163 else ss = mMapStructureSetIndexToTreeWidget[index];
166 const std::vector<clitk::DicomRT_ROI*> & rois = s->GetListOfROI();
167 for(unsigned int i=0; i<rois.size(); i++) {
168 if (mMapROIToTreeWidget.find(rois[i]) == mMapROIToTreeWidget.end())
169 addRoiInTreeWidget(rois[i], ss);
172 //------------------------------------------------------------------------------
175 //------------------------------------------------------------------------------
176 int vvToolStructureSetManager::addStructureSet(clitk::DicomRT_StructureSet * mStructureSet) {
178 // Create actor for this SS
179 vvStructureSetActor * mStructureSetActor = new vvStructureSetActor;
180 mStructureSetActor->SetStructureSet(mStructureSet);
181 mStructureSetActor->SetSlicerManager(mCurrentSlicerManager);
183 // Insert in lists and get index
184 mStructureSetsList.push_back(mStructureSet);
185 mStructureSetActorsList.push_back(mStructureSetActor);
186 int index = mStructureSetsList.size()-1;
191 //------------------------------------------------------------------------------
194 //------------------------------------------------------------------------------
195 void vvToolStructureSetManager::openBinaryImage() {
196 DD("openBinaryImage");
197 // Select current StructureSet (or create)
199 DD(mCurrentStructureSetIndex);
200 if (mCurrentStructureSet == NULL) {
201 if (mStructureSetsList.size() == 0) { // Create a default SS
202 clitk::DicomRT_StructureSet * mStructureSet = new clitk::DicomRT_StructureSet;
203 index = addStructureSet(mStructureSet);
206 else { // Get first SS
211 index = mCurrentStructureSetIndex;
214 // TODO -> SET THIS SS AS CURRENT
215 mCurrentStructureSet = mStructureSetsList[index];
216 mCurrentStructureSetActor = mStructureSetActorsList[index];
217 mCurrentStructureSetIndex = index;
218 DD(mCurrentStructureSetIndex);
219 DD(mCurrentStructureSet->GetName());
222 QString Extensions = "Images files ( *.mhd *.hdr *.his)";
223 Extensions += ";;All Files (*)";
224 QStringList filename =
225 QFileDialog::getOpenFileNames(this,tr("Open binary image"),
226 mMainWindowBase->GetInputPathName(),Extensions);
227 if (filename.size() == 0) return;
229 std::vector<int> mLoadedROIIndex;
230 for(int i=0; i<filename.size(); i++) {
231 DD(filename[i].toStdString());
234 //init the progress events
235 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
236 vvImageReader * mReader = new vvImageReader;
237 std::vector<std::string> filenames;
238 filenames.push_back(filename[i].toStdString());
239 mReader->SetInputFilenames(filenames);
240 mReader->Update(IMAGE);
241 QApplication::restoreOverrideCursor();
243 if (mReader->GetLastError().size() != 0) {
244 std::cerr << "Error while reading " << filename[i].toStdString() << std::endl;
245 QString error = "Cannot open file \n";
246 error += mReader->GetLastError().c_str();
247 QMessageBox::information(this,tr("Reading problem"),error);
251 vvImage::Pointer binaryImage = mReader->GetOutput();
255 int dim = mCurrentImage->GetNumberOfDimensions();
257 int bin_dim = binaryImage->GetNumberOfDimensions();
259 if (dim < bin_dim) { ////////// TO CHANGE FOR 3D/4D
260 std::ostringstream os;
261 os << "Error. Loaded binary image is " << bin_dim
262 << "D while selected image is " << dim << "D" << std::endl;
263 QMessageBox::information(this,tr("Reading problem"),os.str().c_str());
267 // Add a new roi to the structure
268 int n = mCurrentStructureSet->AddBinaryImageAsNewROI(binaryImage, filename[i].toStdString());
270 mLoadedROIIndex.push_back(n);
272 mCurrentStructureSet->GetROI(n)->SetBackgroundValueLabelImage(mBackgroundValueSpinBox->value());
274 // Change color NEED DEFAULT COLOR LIST
275 DD(mDefaultLUTColor->GetNumberOfTableValues ());
276 if (n<mDefaultLUTColor->GetNumberOfTableValues ()) {
277 double * color = mDefaultLUTColor->GetTableValue(n % mDefaultLUTColor->GetNumberOfTableValues ());
281 mCurrentStructureSet->GetROI(n)->SetDisplayColor(color[0], color[1], color[2]);
284 // Add a new roi actor
285 mCurrentStructureSetActor->CreateNewROIActor(n);
286 } // end loop on n selected filenames
288 // Update the TreeWidget
289 updateStructureSetInTreeWidget(index, mCurrentStructureSet);
291 // Render loaded ROIs (the first is sufficient)
292 for(unsigned int i=0; i<mLoadedROIIndex.size(); i++) {
293 mCurrentStructureSetActor->GetROIActor(mLoadedROIIndex[i])->Update();
295 for(int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
296 mCurrentSlicerManager->GetSlicer(i)->Render();
299 //------------------------------------------------------------------------------
302 //------------------------------------------------------------------------------
303 void vvToolStructureSetManager::apply() {
306 //------------------------------------------------------------------------------
310 //------------------------------------------------------------------------------
311 // CURRENT ROI INTERACTION
312 //------------------------------------------------------------------------------
315 //------------------------------------------------------------------------------
316 void vvToolStructureSetManager::selectedItemChangedInTree() {
317 DD("selectedItemChangedInTree");
318 QList<QTreeWidgetItem *> l = mTree->selectedItems();
320 QTreeWidgetItem * w = l[0];
321 if (mMapTreeWidgetToROI.find(w) == mMapTreeWidgetToROI.end()) return; // Search for SS (first)
322 clitk::DicomRT_ROI * roi = mMapTreeWidgetToROI[w];
324 //setCurrentSelectedROI(roi);
326 mROInameLabel->setText(roi->GetName().c_str());
327 DD(roi->GetROINumber());
328 DD(mCurrentStructureSetIndex);
329 vvROIActor * actor = mStructureSetActorsList[mCurrentStructureSetIndex]->GetROIActor(roi->GetROINumber());
331 mCurrentROIActor = actor;
334 DD(actor->IsVisible());
335 mCheckBoxShow->setChecked(actor->IsVisible());
336 mOpacitySlider->setValue((int)lrint(actor->GetOpacity()*100));
337 //actor->SetSelected(true); // remove old selection
341 //------------------------------------------------------------------------------
344 //------------------------------------------------------------------------------
345 void vvToolStructureSetManager::visibleROIToggled(bool b) {
347 mCurrentROIActor->SetVisible(b);
348 //mCurrentROIActor->Update();
350 //------------------------------------------------------------------------------
353 //------------------------------------------------------------------------------
354 void vvToolStructureSetManager::opacityChanged(int v) {
355 // if (!mCurrentROIActor) return;
357 mCurrentROIActor->SetOpacity((double)v/100.0);
359 mCurrentROIActor->Update();
361 // for(int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
362 mCurrentSlicerManager->Render();
365 //------------------------------------------------------------------------------
370 //------------------------------------------------------------------------------
371 //void vvToolStructureSetManager::getActorFromROI() {
372 // mStructureSetActorsList[mCurrentStructureSetIndex]->GetROIActor(n);
374 //------------------------------------------------------------------------------