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://www.centreleonberard.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 ===========================================================================**/
20 #include "vvToolROIManager.h"
21 #include "vvImageReader.h"
22 #include "vvImageWriter.h"
23 #include "vvROIActor.h"
25 #include "vvMeshReader.h"
26 #include "vvStructSelector.h"
27 #include "vvToolManager.h"
28 #include "vvProgressDialog.h"
31 #include "clitkDicomRTStruct2ImageFilter.h"
32 #include "clitkDicomRT_StructureSet.h"
35 #include <QFileDialog>
36 #include <QMessageBox>
37 #include <QColorDialog>
38 #include <QAbstractEventDispatcher>
39 #include <QXmlStreamReader>
42 #include <vtkLookupTable.h>
43 #include <vtkRenderWindow.h>
45 //------------------------------------------------------------------------------
46 // Create the tool and automagically (I like this word) insert it in
47 // the main window menu.
48 ADD_TOOL(vvToolROIManager);
49 //------------------------------------------------------------------------------
51 //------------------------------------------------------------------------------
52 vvToolROIManager::vvToolROIManager(vvMainWindowBase * parent, Qt::WindowFlags f):
53 QWidget(parent->GetTab()),
54 vvToolBase<vvToolROIManager>(parent),
55 Ui::vvToolROIManager()
56 { //out << __func__ << endl;
60 // Assume the initial tab ROI index is 2
64 Ui_vvToolROIManager::setupUi(this);
65 setAttribute(Qt::WA_DeleteOnClose);
67 mTree->header()->resizeSection(0, 30);
68 mGroupBoxROI->setEnabled(false);
70 // Disable "Load dicom" button -> not useful
74 mDefaultLUTColor = vtkSmartPointer<vtkLookupTable>::New();
75 for(int i=0; i<mDefaultLUTColor->GetNumberOfTableValues(); i++) {
76 double r = (rand()/(RAND_MAX+1.0));
77 double v = (rand()/(RAND_MAX+1.0));
78 double b = (rand()/(RAND_MAX+1.0));
79 mDefaultLUTColor->SetTableValue(i, r, v, b);
81 #include "vvDefaultLut.h"
84 mCurrentSlicerManager = NULL;
85 mNumberOfVisibleROI = 0;
86 mNumberOfVisibleContourROI = 0;
87 mOpenFileBrowserFlag = true; // by default, open the file browser when the tool is launched
89 // InitializeNewTool must be called to start
91 //------------------------------------------------------------------------------
94 //------------------------------------------------------------------------------
95 vvToolROIManager::~vvToolROIManager()
96 { //out << __func__ << endl;
97 mROIActorsList.clear();
99 //------------------------------------------------------------------------------
102 //------------------------------------------------------------------------------
104 void vvToolROIManager::Initialize()
105 { //out << __func__ << endl;
106 SetToolName("ROIManager");
107 SetToolMenuName("Open ROI (binary image or RT-STRUCT)");
108 SetToolIconFilename(":/common/icons/tool-roi.png");
109 SetToolTip("Display ROI from a binary image or a RT-struct file.");
110 SetToolExperimental(false);
112 //------------------------------------------------------------------------------
116 //------------------------------------------------------------------------------
117 void vvToolROIManager::InitializeNewTool(bool ReadStateFlag)
118 { //out << __func__ << endl;
119 // Check if we need to start a new tool or read in the state file to load
120 if (ReadStateFlag == false) {
121 // Select the current image as the target
122 int i = mMainWindow->GetSlicerManagerCurrentIndex();
123 mCurrentSlicerManager = mMainWindow->GetSlicerManagers()[i];
124 // Set it as current (only if not ReadStateFlag)
125 mMainWindow->GetTab()->setCurrentIndex(mIndexFirstTab);
128 // Set the first tab in front to avoid displaying two roimanager
129 // in the same tab. Because toolcreatorBase do show() and I am too
130 // lazy to find another solution now.
131 mMainWindow->GetTab()->setCurrentIndex(0);
133 // Read all information in the XML
134 ReadXMLInformation();
136 // Check that a ROI is not already present
137 mInitialImageIndex += mImageIndex;
138 if (mInitialImageIndex >= mMainWindow->GetSlicerManagers().size()) {
139 QMessageBox::warning(this, "ROIManager tool", QString("Image index %1 not found, abort.").arg(mInitialImageIndex));
144 // Set the attached image
145 mCurrentSlicerManager = mMainWindow->GetSlicerManagers()[mInitialImageIndex];
148 // Tab insertion, check that another tool does not already exist for this image
149 std::vector<vvToolBaseBase*> & tools =
150 vvToolManager::GetInstance()->GetToolCreatorFromName(GetToolName())->GetListOfTool();
151 if (tools.size() > 0) {
152 for(uint i=0; i<tools.size()-1; i++) { // current tool is last
153 vvToolROIManager * t = dynamic_cast<vvToolROIManager*>(tools[i]);
154 if (mCurrentSlicerManager == t->GetCurrentSlicerManager()) {
155 QMessageBox::warning(this, "ROIManager tool", "Already a ROI for this image, abort.");
162 // Display tool in the correct tab
163 QWidget * tab = mMainWindow->GetTab()->findChild<QWidget*>("ROItab");
164 tab->layout()->addWidget(this);
166 // If not read in a file we start automatically the browser to load
167 // a roi file (binary image)
169 mOpenFileBrowserFlag = false;
170 InputIsSelected(mCurrentSlicerManager);
171 mOpenFileBrowserFlag = true;
173 else InputIsSelected(mCurrentSlicerManager);
175 // Load ROI (if read in the XML files, empty otherwise)
176 OpenBinaryImage(mROIFilenames);
178 // Set the options to the open roi
179 for(uint i=0; i<mROIActorsParamList.size(); i++) {
180 QSharedPointer<vvROIActor> roi = mROIActorsList[i];
181 QSharedPointer<vvROIActor> roi_param = mROIActorsParamList[i];
182 roi->CopyParameters(roi_param);
185 QTreeWidgetItem * w = mMapROIToTreeWidget[roi->GetROI()];
186 QBrush brush(QColor(roi->GetROI()->GetDisplayColor()[0]*255,
187 roi->GetROI()->GetDisplayColor()[1]*255,
188 roi->GetROI()->GetDisplayColor()[2]*255));
189 brush.setStyle(Qt::SolidPattern);
190 w->setBackground(2, brush);
191 w->setText(3, QString("%1").arg(roi->GetDepth()));
197 UpdateAllROIStatus();
199 // Connect event from mainwindow to this widget
200 connect(mMainWindow, SIGNAL(AnImageIsBeingClosed(vvSlicerManager *)),
201 this, SLOT(AnImageIsBeingClosed(vvSlicerManager *)));
202 connect(mMainWindow, SIGNAL(SelectedImageHasChanged(vvSlicerManager *)),
203 this, SLOT(SelectedImageHasChanged(vvSlicerManager *)));
204 connect(mOpenBinaryButton, SIGNAL(clicked()), this, SLOT(Open()));
205 // connect(mOpenDicomButton, SIGNAL(clicked()), this, SLOT(OpenDicomImage()));
206 connect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedItemChangedInTree()));
207 connect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleROIToggled(bool)));
208 connect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityChanged(int)));
209 connect(mChangeColorButton, SIGNAL(clicked()), this, SLOT(ChangeColor()));
210 connect(mContourCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleContourROIToggled(bool)));
211 connect(mChangeContourColorButton, SIGNAL(clicked()), this, SLOT(ChangeContourColor()));
212 connect(mContourWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeContourWidth(int)));
213 connect(mDepthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeDepth(int)));
214 connect(mReloadButton, SIGNAL(clicked()), this, SLOT(ReloadCurrentROI()));
215 connect(mCheckBoxShowAll, SIGNAL(stateChanged(int)), this, SLOT(AllVisibleROIToggled(int)));
216 connect(mContourCheckBoxShowAll, SIGNAL(toggled(bool)), this, SLOT(AllVisibleContourROIToggled(bool)));
217 connect(mCloseButton, SIGNAL(clicked()), this, SLOT(close()));
219 //------------------------------------------------------------------------------
222 //------------------------------------------------------------------------------
223 void vvToolROIManager::InputIsSelected(vvSlicerManager *m)
224 { //out << __func__ << endl;
226 mCurrentSlicerManager = m;
227 mCurrentImage = mCurrentSlicerManager->GetImage();
229 // Refuse if non 3D image
230 if (mCurrentImage->GetNumberOfDimensions() != 3) {
231 QMessageBox::information(this,tr("Warning"), tr("Warning 3D ROI on a 4D image will results in some display bugs"));
237 mLabelInputInfo->setText(QString("%1").arg(m->GetFileName().c_str()));
239 // Auto display browser to select new contours
240 if (mOpenFileBrowserFlag) Open();
242 //------------------------------------------------------------------------------
245 //------------------------------------------------------------------------------
246 void vvToolROIManager::AnImageIsBeingClosed(vvSlicerManager * m)
247 { //out << __func__ << endl;
248 if (m == mCurrentSlicerManager) {
253 //------------------------------------------------------------------------------
256 //------------------------------------------------------------------------------
257 void vvToolROIManager::close()
258 { //out << __func__ << endl;
259 disconnect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedItemChangedInTree()));
260 disconnect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleROIToggled(bool)));
261 disconnect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityChanged(int)));
262 disconnect(mChangeColorButton, SIGNAL(clicked()), this, SLOT(ChangeColor()));
263 disconnect(mContourCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleContourROIToggled(bool)));
264 disconnect(mChangeContourColorButton, SIGNAL(clicked()), this, SLOT(ChangeContourColor()));
265 disconnect(mContourWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeContourWidth(int)));
266 disconnect(mDepthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeDepth(int)));
269 for (unsigned int i = 0; i < mROIActorsList.size(); i++) {
270 mROIActorsList[i]->RemoveActors();
272 mROIActorsList.clear();
275 for(int i=0; i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
276 mCurrentSlicerManager->GetSlicer(i)->Render();
279 //------------------------------------------------------------------------------
282 //------------------------------------------------------------------------------
283 void vvToolROIManager::SelectedImageHasChanged(vvSlicerManager * m)
284 { //out << __func__ << endl;
285 if (mCurrentSlicerManager == NULL) return;
286 if (m == NULL) return;
287 if (m != mCurrentSlicerManager) hide();
292 //------------------------------------------------------------------------------
295 //------------------------------------------------------------------------------
296 void vvToolROIManager::Open()
297 { //out << __func__ << endl;
299 QString Extensions = "Images or Dicom-Struct files ( *.mha *.mhd *.hdr *.his *.dcm RS*)";
300 Extensions += ";;All Files (*)";
301 QStringList filename =
302 QFileDialog::getOpenFileNames(this,tr("Open binary image or DICOM RT Struct"),
303 mMainWindowBase->GetInputPathName(),Extensions);
304 if (filename.size() == 0) return;
305 if (filename.size() > 1) { OpenBinaryImage(filename); return; }
307 // Try to read dicom rt ?
308 clitk::DicomRT_StructureSet::Pointer s = clitk::DicomRT_StructureSet::New();
309 if (s->IsDicomRTStruct(filename[0].toStdString())) OpenDicomImage(filename[0].toStdString());
310 else OpenBinaryImage(filename);
313 //------------------------------------------------------------------------------
316 //------------------------------------------------------------------------------
317 void vvToolROIManager::OpenBinaryImage(QStringList & filename)
318 { //out << __func__ << endl;
319 if (filename.size() == 0) return;
321 vvProgressDialog p("Reading ROI ...", true);
322 p.SetCancelButtonEnabled(false);
323 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
325 // For each selected file, open the image
326 for(int i=0; i<filename.size(); i++) {
327 p.SetProgress(i, filename.size());
330 vvImageReader::Pointer reader = vvImageReader::New();
331 std::vector<std::string> filenames;
332 filenames.push_back(filename[i].toStdString());
333 reader->SetInputFilenames(filenames);
334 reader->Update(vvImageReader::IMAGE);
336 if (reader->GetLastError().size() != 0) {
337 std::cerr << "Error while reading " << filename[i].toStdString() << std::endl;
338 QString error = "Cannot open file \n";
339 error += reader->GetLastError().c_str();
340 QMessageBox::information(this,tr("Reading problem"),error);
343 vvImage::Pointer binaryImage = reader->GetOutput();
344 std::ostringstream oss;
345 oss << vtksys::SystemTools::
346 GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(filename[i].toStdString()));
347 std::string name = oss.str();
348 AddImage(binaryImage, name, filename[i].toStdString(), mBackgroundValueSpinBox->value(),
349 (!mBGModeCheckBox->isChecked()));
350 mOpenedBinaryImageFilenames.push_back(filename[i]);
352 QApplication::restoreOverrideCursor();
354 // Update the contours
357 //------------------------------------------------------------------------------
360 //------------------------------------------------------------------------------
361 void vvToolROIManager::OpenDicomImage(std::string filename)
362 { //out << __func__ << endl;
363 // GUI selector of roi
365 reader.SetFilename(filename);
367 vvStructSelector selector;
368 selector.SetStructures(reader.GetROINames());
369 selector.SetPropagationCheckBoxFlag(false);
371 if (selector.exec()) {
372 vvProgressDialog p("Reading ROI...", true);
373 p.SetCancelButtonEnabled(false);
374 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
377 clitk::DicomRT_StructureSet::Pointer s = clitk::DicomRT_StructureSet::New();
380 // Loop on selected struct
381 std::vector<int> list = selector.getSelectedItems();
382 for (uint i=0; i<list.size(); i++) {
383 p.SetProgress(i, list.size());
385 clitk::DicomRTStruct2ImageFilter filter;
386 filter.SetCropMaskEnabled(true);
387 filter.SetImage(mCurrentImage);
388 filter.SetROI(s->GetROIFromROINumber(list[i]));
389 filter.SetWriteOutputFlag(false);
393 vvImage::Pointer binaryImage = vvImage::New();
394 binaryImage->AddVtkImage(filter.GetOutput());
397 AddImage(binaryImage, s->GetROIFromROINumber(list[i])->GetName(), "", 0, true); // "" = no filename
398 mOpenedBinaryImageFilenames.push_back(filename.c_str());
401 QApplication::restoreOverrideCursor();
403 // Update the contours
406 //------------------------------------------------------------------------------
409 //------------------------------------------------------------------------------
410 void vvToolROIManager::AddImage(vvImage * binaryImage,
412 std::string filename,
413 double BG, bool modeBG)
414 { //out << __func__ << endl;
416 int dim = mCurrentImage->GetNumberOfDimensions();
417 int bin_dim = binaryImage->GetNumberOfDimensions();
419 std::ostringstream os;
420 os << "Error. Loaded binary image is " << bin_dim
421 << "D while selected image is " << dim << "D" << std::endl;
422 QMessageBox::information(this,tr("Reading problem"),os.str().c_str());
427 int n = mROIList.size();
429 // Compute the name of the new ROI
430 // std::ostringstream oss;
431 // oss << vtksys::SystemTools::GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(filename));
432 // std::string name = oss.str();
435 std::vector<double> color;
441 clitk::DicomRT_ROI::Pointer roi = clitk::DicomRT_ROI::New();
442 roi->SetFromBinaryImage(binaryImage, n, name, color, filename);
444 // Add a new roi to the list
445 mROIList.push_back(roi);
449 roi->SetBackgroundValueLabelImage(BG);
451 roi->SetForegroundValueLabelImage(BG);
454 if (n<mDefaultLUTColor->GetNumberOfTableValues ()) {
455 double * color = mDefaultLUTColor->GetTableValue(n % mDefaultLUTColor->GetNumberOfTableValues ());
456 roi->SetDisplayColor(color[0], color[1], color[2]);
459 // Add a new roi actor
460 QSharedPointer<vvROIActor> actor = QSharedPointer<vvROIActor>(new vvROIActor);
461 actor->SetBGMode(modeBG);
463 actor->SetSlicerManager(mCurrentSlicerManager);
464 actor->Initialize(n+1); // depth is n+1 to start at 1
465 mROIActorsList.push_back(actor);
467 // CheckBox for "All"
468 if (actor->IsVisible()) mNumberOfVisibleROI++;
469 if (actor->IsContourVisible()) mNumberOfVisibleContourROI++;
470 AllVisibleContourROIToggled(true);
473 mTreeWidgetList.push_back(QSharedPointer<QTreeWidgetItem>(new QTreeWidgetItem(mTree)));
474 QTreeWidgetItem * w = mTreeWidgetList.back().data();
475 w->setText(0, QString("%1").arg(roi->GetROINumber()));
476 w->setText(1, QString("%1").arg(roi->GetName().c_str()));
477 w->setText(3, QString("%1").arg(actor->GetDepth()));
478 QBrush brush(QColor(roi->GetDisplayColor()[0]*255,
479 roi->GetDisplayColor()[1]*255,
480 roi->GetDisplayColor()[2]*255));
481 brush.setStyle(Qt::SolidPattern);
482 w->setBackground(2, brush);
483 mMapROIToTreeWidget[roi] = w;
484 mMapTreeWidgetToROI[w] = roi;
485 mTree->resizeColumnToContents(0);
486 mTree->resizeColumnToContents(1);
489 UpdateAllROIStatus();
491 //------------------------------------------------------------------------------
494 //------------------------------------------------------------------------------
495 void vvToolROIManager::UpdateAllContours()
496 { //out << __func__ << endl;
497 if (mCurrentSlicerManager == NULL) return;
498 // Render loaded ROIs (the first is sufficient)
499 for(unsigned int i=0; i<mROIList.size(); i++) {
500 mROIActorsList[i]->Update();
502 mCurrentSlicerManager->Render();
504 //------------------------------------------------------------------------------
507 //------------------------------------------------------------------------------
508 void vvToolROIManager::UpdateAllROIStatus()
509 { //out << __func__ << endl;
511 int nb = mROIList.size();
512 for(int i=0; i<nb; i++) {
513 if (mROIActorsList[i]->IsVisible()) {
519 disconnect(mCheckBoxShowAll, SIGNAL(stateChanged(int)), this, SLOT(AllVisibleROIToggled(int)));
520 disconnect(mContourCheckBoxShowAll, SIGNAL(toggled(bool)), this, SLOT(AllVisibleContourROIToggled(bool)));
521 if (nbVisible == nb) mCheckBoxShowAll->setCheckState(Qt::Checked);
523 if (nbVisible == 0) mCheckBoxShowAll->setCheckState(Qt::Unchecked);
524 else mCheckBoxShowAll->setCheckState(Qt::PartiallyChecked);
526 connect(mContourCheckBoxShowAll, SIGNAL(toggled(bool)), this, SLOT(AllVisibleContourROIToggled(bool)));
527 connect(mCheckBoxShowAll, SIGNAL(stateChanged(int)), this, SLOT(AllVisibleROIToggled(int)));
529 //------------------------------------------------------------------------------
532 //------------------------------------------------------------------------------
533 void vvToolROIManager::SelectedItemChangedInTree()
534 { //out << __func__ << endl;
535 // Search which roi is selected
536 QList<QTreeWidgetItem *> l = mTree->selectedItems();
538 // mCurrentROIActor = 0;
540 mGroupBoxROI->setEnabled(false);
543 QTreeWidgetItem * w = l[0];
544 if (w == NULL) return;
546 if (mMapTreeWidgetToROI.find(w) == mMapTreeWidgetToROI.end()) {
547 // mCurrentROIActor = 0;
549 mGroupBoxROI->setEnabled(false);
552 if (w == NULL) return;
553 clitk::DicomRT_ROI * roi = mMapTreeWidgetToROI[w];
554 if (roi == NULL) return; // sometimes it is called while there is no roi anymore
556 // Get selected roi actor
557 int n = roi->GetROINumber();
558 QSharedPointer<vvROIActor> actor = mROIActorsList[n];
560 mCurrentROIActor = actor;
562 // Warning -> avoid unuseful Render here by disconnect slider
564 disconnect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedItemChangedInTree()));
565 disconnect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleROIToggled(bool)));
566 disconnect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityChanged(int)));
567 disconnect(mChangeColorButton, SIGNAL(clicked()), this, SLOT(ChangeColor()));
568 disconnect(mContourCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleContourROIToggled(bool)));
569 disconnect(mChangeContourColorButton, SIGNAL(clicked()), this, SLOT(ChangeContourColor()));
570 disconnect(mContourWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeContourWidth(int)));
571 disconnect(mDepthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeDepth(int)));
573 mROInameLabel->setText(roi->GetName().c_str());
574 mCheckBoxShow->setChecked(actor->IsVisible());
575 mContourCheckBoxShow->setChecked(actor->IsContourVisible());
576 mContourWidthSpinBox->setValue(actor->GetContourWidth());
577 mDepthSpinBox->setValue(actor->GetDepth());
578 w->setText(3, QString("%1").arg(actor->GetDepth()));
579 mOpacitySlider->setValue((int)lrint(actor->GetOpacity()*100));
580 mOpacitySpinBox->setValue((int)lrint(actor->GetOpacity()*100));
582 connect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedItemChangedInTree()));
583 connect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleROIToggled(bool)));
584 connect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityChanged(int)));
585 connect(mChangeColorButton, SIGNAL(clicked()), this, SLOT(ChangeColor()));
586 connect(mContourCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleContourROIToggled(bool)));
587 connect(mChangeContourColorButton, SIGNAL(clicked()), this, SLOT(ChangeContourColor()));
588 connect(mContourWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeContourWidth(int)));
589 connect(mDepthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeDepth(int)));
592 // Set the current color to the selected ROI name
593 mROInameLabel->setAutoFillBackground(true);// # This is important!!
594 // mROInameLabel->setStyleSheet("QLabel { background-color : red; color : blue; }");
595 QColor color = QColor(mCurrentROI->GetDisplayColor()[0]*255,
596 mCurrentROI->GetDisplayColor()[1]*255,
597 mCurrentROI->GetDisplayColor()[2]*255);
598 // QString values = QString("%1, %2, %3").arg(color.red()).arg(color.green()).arg(color.blue());
599 // mROInameLabel->setStyleSheet("QLabel { background-color: rgb("+values+"); }");
601 QPalette* palette = new QPalette();
602 QColor colorFG = QColor((1-mCurrentROI->GetDisplayColor()[0])*255,
603 (1-mCurrentROI->GetDisplayColor()[1])*255,
604 (1-mCurrentROI->GetDisplayColor()[2])*255);
605 palette->setColor(QPalette::WindowText,colorFG);
606 palette->setColor(QPalette::Background, color);
607 mROInameLabel->setPalette(*palette);
609 // Enable the group box (in case no selection before)
610 mGroupBoxROI->setEnabled(true);
612 //------------------------------------------------------------------------------
615 //------------------------------------------------------------------------------
616 void vvToolROIManager::VisibleROIToggled(bool b)
617 { //out << __func__ << endl;
618 if (mCurrentROIActor == NULL) return;
619 if (b == mCurrentROIActor->IsVisible()) return; // nothing to do
620 mCurrentROIActor->SetVisible(b);
621 UpdateAllROIStatus();
622 mCurrentSlicerManager->Render();
624 //------------------------------------------------------------------------------
627 //------------------------------------------------------------------------------
628 void vvToolROIManager::VisibleContourROIToggled(bool b)
629 { //out << __func__ << endl;
630 if (mCurrentROIActor == NULL) return;
631 if (mCurrentROIActor->IsContourVisible() == b) return; // nothing to do
632 mCurrentROIActor->SetContourVisible(b);
633 mCurrentROIActor->UpdateColor();
634 mCurrentSlicerManager->Render();
636 //------------------------------------------------------------------------------
639 //------------------------------------------------------------------------------
640 void vvToolROIManager::OpacityChanged(int v)
641 { //out << __func__ << endl;
642 if (mCurrentROIActor == NULL) return;
643 mCurrentROIActor->SetOpacity((double)v/100.0);
644 mCurrentROIActor->UpdateColor();
645 mCurrentSlicerManager->Render();
647 //------------------------------------------------------------------------------
650 //------------------------------------------------------------------------------
651 void vvToolROIManager::AllVisibleROIToggled(int b)
652 { //out << __func__ << endl;
654 if ((mCheckBoxShowAll->checkState() == Qt::Checked) ||
655 (mCheckBoxShowAll->checkState() == Qt::PartiallyChecked)) status = true;
657 for(uint i=0; i<mROIList.size(); i++) {
658 mROIActorsList[i]->SetVisible(status);
660 if (status) mCheckBoxShowAll->setCheckState(Qt::Checked);
661 else mCheckBoxShowAll->setCheckState(Qt::Unchecked);
662 mCheckBoxShow->setChecked(status);
663 mCurrentSlicerManager->Render();
665 //------------------------------------------------------------------------------
668 //------------------------------------------------------------------------------
669 void vvToolROIManager::AllVisibleContourROIToggled(bool b)
670 { //out << __func__ << endl;
672 if ((mContourCheckBoxShowAll->checkState() == Qt::Checked) ||
673 (mContourCheckBoxShowAll->checkState() == Qt::PartiallyChecked)) status = true;
675 for(uint i=0; i<mROIActorsList.size(); i++) {
676 mROIActorsList[i]->SetContourVisible(status);
678 // Update current selection
679 if (status) mContourCheckBoxShowAll->setCheckState(Qt::Checked);
680 else mContourCheckBoxShowAll->setCheckState(Qt::Unchecked);
681 mContourCheckBoxShow->setChecked(status);
682 mCurrentSlicerManager->Render();
684 //------------------------------------------------------------------------------
687 //------------------------------------------------------------------------------
688 void vvToolROIManager::ChangeColor()
689 { //out << __func__ << endl;
690 if (mCurrentROIActor == NULL) return;
692 color.setRgbF(mCurrentROIActor->GetROI()->GetDisplayColor()[0],
693 mCurrentROIActor->GetROI()->GetDisplayColor()[1],
694 mCurrentROIActor->GetROI()->GetDisplayColor()[2]);
695 QColor c = QColorDialog::getColor(color, this, "Choose the ROI color");
696 if (!c.isValid()) return;// User cancel
698 mCurrentROIActor->GetROI()->SetDisplayColor(c.redF(), c.greenF(), c.blueF());
699 mCurrentROIActor->UpdateColor();
701 QTreeWidgetItem * w = mMapROIToTreeWidget[mCurrentROI];
702 QBrush brush(QColor(mCurrentROI->GetDisplayColor()[0]*255,
703 mCurrentROI->GetDisplayColor()[1]*255,
704 mCurrentROI->GetDisplayColor()[2]*255));
705 brush.setStyle(Qt::SolidPattern);
706 w->setBackground(2, brush);
708 mCurrentSlicerManager->Render();
710 //------------------------------------------------------------------------------
713 //------------------------------------------------------------------------------
714 void vvToolROIManager::ChangeContourColor()
715 { //out << __func__ << endl;
716 if (mCurrentROIActor == NULL) return;
718 color.setRgbF(mCurrentROIActor->GetContourColor()[0],
719 mCurrentROIActor->GetContourColor()[1],
720 mCurrentROIActor->GetContourColor()[2]);
721 // QColorDialog d(color);
722 QColor c = QColorDialog::getColor(color, this, "Choose the contour color");
723 if (!c.isValid()) return; // User cancel
724 mCurrentROIActor->SetContourColor(c.redF(), c.greenF(), c.blueF());
725 mCurrentROIActor->UpdateColor();
726 mCurrentSlicerManager->Render();
728 //------------------------------------------------------------------------------
731 //------------------------------------------------------------------------------
732 void vvToolROIManager::ChangeContourWidth(int n)
733 { //out << __func__ << endl;
734 if (mCurrentROIActor == NULL) return;
735 mCurrentROIActor->SetContourWidth(n);
736 mCurrentROIActor->UpdateColor();
737 mCurrentSlicerManager->Render();
739 //------------------------------------------------------------------------------
742 //------------------------------------------------------------------------------
743 void vvToolROIManager::ChangeDepth(int n)
744 { //out << __func__ << endl;
745 if (mCurrentROIActor == NULL) return;
746 mCurrentROIActor->SetDepth(n);
747 // mCurrentROIActor->UpdateImage(); // FIXME
748 mCurrentSlicerManager->Render();
749 QList<QTreeWidgetItem *> l = mTree->selectedItems();
750 QTreeWidgetItem * w = l[0];
751 w->setText(3, QString("%1").arg(mCurrentROIActor->GetDepth()));
753 //------------------------------------------------------------------------------
756 //------------------------------------------------------------------------------
757 void vvToolROIManager::ReloadCurrentROI()
758 { //out << __func__ << endl;
759 if (mCurrentROI->GetFilename() == "") {
760 return; // do nothing (contour from rt struct do not reload)
763 // Remove all contours/overlay first
764 bool visible = mCurrentROIActor->IsVisible();
765 bool cvisible = mCurrentROIActor->IsContourVisible();
766 mCurrentROIActor->SetVisible(false);
767 mCurrentROIActor->SetContourVisible(false);
768 mCurrentSlicerManager->Render();
771 vvImageReader::Pointer reader = vvImageReader::New();
772 reader->SetInputFilename(mCurrentROI->GetFilename());
773 reader->Update(vvImageReader::IMAGE);
774 if (reader->GetLastError() != "") {
775 // No message just ignore (because can be from dicom)
776 // QMessageBox::information(mMainWindowBase, tr("Sorry, error. Could not reload"),
777 // reader->GetLastError().c_str());
781 // Free the previous image
782 mCurrentROI->GetImage()->GetFirstVTKImageData()->ReleaseData(); // Needed to free
783 mCurrentROI->GetImage()->Reset();
784 mCurrentROI->SetImage(reader->GetOutput());
786 mCurrentROIActor->RemoveActors();
789 mCurrentROIActor->UpdateImage();
790 mCurrentROIActor->SetVisible(visible);
791 mCurrentROIActor->SetContourVisible(cvisible);
792 mCurrentSlicerManager->Render();
794 //------------------------------------------------------------------------------
797 //------------------------------------------------------------------------------
798 void vvToolROIManager::SaveState(std::auto_ptr<QXmlStreamWriter> & m_XmlWriter)
799 { //out << __func__ << endl;
800 // Get index of the image
801 int n = mMainWindow->GetSlicerManagers().size();
803 for(int i=0; i<n; i++) {
804 if (mCurrentSlicerManager == mMainWindow->GetSlicerManagers()[i]) index = i;
807 std::cerr << "Error while writing state for ROIManager tool no currentimage founded." << std::endl;
810 m_XmlWriter->writeTextElement("Image_Index", QString::number(index));
814 for(uint i=0; i<mROIActorsList.size(); i++) {
815 QSharedPointer<vvROIActor> roi = mROIActorsList[i];
817 m_XmlWriter->writeStartElement("ROI");
818 m_XmlWriter->writeTextElement("Image", mOpenedBinaryImageFilenames[i]);
820 m_XmlWriter->writeStartElement("Overlay");
821 m_XmlWriter->writeAttribute("Red", QString("%1").arg(roi->GetOverlayColor()[0]));
822 m_XmlWriter->writeAttribute("Green",QString("%1").arg(roi->GetOverlayColor()[1]));
823 m_XmlWriter->writeAttribute("Blue", QString("%1").arg(roi->GetOverlayColor()[2]));
824 m_XmlWriter->writeAttribute("Visible", QString("%1").arg(roi->IsVisible()));
825 m_XmlWriter->writeAttribute("Opacity", QString("%1").arg(roi->GetOpacity()));
826 m_XmlWriter->writeAttribute("Depth", QString("%1").arg(roi->GetDepth()));
827 m_XmlWriter->writeEndElement();
829 m_XmlWriter->writeStartElement("Contour");
830 m_XmlWriter->writeAttribute("Red", QString("%1").arg(roi->GetContourColor()[0]));
831 m_XmlWriter->writeAttribute("Green",QString("%1").arg(roi->GetContourColor()[1]));
832 m_XmlWriter->writeAttribute("Blue", QString("%1").arg(roi->GetContourColor()[2]));
833 m_XmlWriter->writeAttribute("Visible", QString("%1").arg(roi->IsContourVisible()));
834 m_XmlWriter->writeAttribute("Width", QString("%1").arg(roi->GetContourWidth()));
835 m_XmlWriter->writeEndElement();
837 m_XmlWriter->writeEndElement();
840 //------------------------------------------------------------------------------
843 //------------------------------------------------------------------------------
844 void vvToolROIManager::ReadXMLInformation()
845 { //out << __func__ << endl;
846 std::string value="";
847 mInitialImageIndex = -1;
848 while (!(m_XmlReader->isEndElement() && value == GetToolName().toStdString())) {
849 m_XmlReader->readNext();
850 value = m_XmlReader->qualifiedName().toString().toStdString();
852 if (value == "Image_Index")
853 mInitialImageIndex = m_XmlReader->readElementText().toInt();
855 if (m_XmlReader->isStartElement()) {
856 if (value == "ROI") {
857 ReadXMLInformation_ROI();
862 //------------------------------------------------------------------------------
865 //------------------------------------------------------------------------------
866 void vvToolROIManager::ReadXMLInformation_ROI()
867 { //out << __func__ << endl;
869 std::string value="";
870 QSharedPointer<vvROIActor> param = QSharedPointer<vvROIActor>(new vvROIActor);
871 param->SetVisible(true);
872 clitk::DicomRT_ROI::Pointer roi = clitk::DicomRT_ROI::New();
873 // r->SetDisplayColor(1,1,1);
876 float r=1.0,g=1.0,b=1.0;
877 float cr=1.0,cg=1.0,cb=1.0;
880 bool cvisible = true;
884 while (!(m_XmlReader->isEndElement() && value == "ROI")) {
885 m_XmlReader->readNext();
886 value = m_XmlReader->qualifiedName().toString().toStdString();
887 if (value == "Image") {
888 s = m_XmlReader->readElementText();
891 if (value == "Overlay" && m_XmlReader->isStartElement()) {
892 QXmlStreamAttributes attributes = m_XmlReader->attributes();
893 if (!m_XmlReader->hasError())
894 r = attributes.value("Red").toString().toFloat();
895 if (!m_XmlReader->hasError())
896 g = attributes.value("Green").toString().toFloat();
897 if (!m_XmlReader->hasError())
898 b = attributes.value("Blue").toString().toFloat();
899 if (!m_XmlReader->hasError())
900 visible = attributes.value("Visible").toString().toInt();
901 if (!m_XmlReader->hasError())
902 opacity = attributes.value("Opacity").toString().toFloat();
903 if (!m_XmlReader->hasError())
904 depth = attributes.value("Depth").toString().toFloat();
908 if (value == "Contour" && m_XmlReader->isStartElement()) {
909 QXmlStreamAttributes attributes = m_XmlReader->attributes();
910 if (!m_XmlReader->hasError())
911 cr = attributes.value("Red").toString().toFloat();
912 if (!m_XmlReader->hasError())
913 cg = attributes.value("Green").toString().toFloat();
914 if (!m_XmlReader->hasError())
915 cb = attributes.value("Blue").toString().toFloat();
916 if (!m_XmlReader->hasError())
917 cvisible = attributes.value("Visible").toString().toInt();
918 if (!m_XmlReader->hasError())
919 width = attributes.value("Width").toString().toFloat();
921 param->SetOverlayColor(r,g,b);
922 param->SetVisible(visible);
923 param->SetOpacity(opacity);
924 param->SetDepth(depth);
926 param->SetContourColor(cr,cg,cb);
927 param->SetContourVisible(cvisible);
928 param->SetContourWidth(width);
930 mROIFilenames.push_back(s);
931 mROIActorsParamList.push_back(param);
933 //------------------------------------------------------------------------------