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 "vvROIActor.h"
26 #include "vvMeshReader.h"
27 #include "vvStructSelector.h"
28 #include "vvToolManager.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()
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 // Temporary disable "Load dicom" button
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()
97 mROIActorsList.clear();
99 //------------------------------------------------------------------------------
102 //------------------------------------------------------------------------------
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(false);
111 //------------------------------------------------------------------------------
115 //------------------------------------------------------------------------------
116 void vvToolROIManager::InitializeNewTool(bool ReadStateFlag)
118 // Check if we need to start a new tool or read in the state file to load
119 if (ReadStateFlag == false) {
120 // Select the current image as the target
121 int i = mMainWindow->GetSlicerManagerCurrentIndex();
122 mCurrentSlicerManager = mMainWindow->GetSlicerManagers()[i];
123 // Set it as current (only if not ReadStateFlag)
124 mMainWindow->GetTab()->setCurrentIndex(mIndexFirstTab);
127 // Set the first tab in front to avoid displaying two roimanager
128 // in the same tab. Because toolcreatorBase do show() and I am too
129 // lazy to find another solution now.
130 mMainWindow->GetTab()->setCurrentIndex(0);
132 // Read all information in the XML
133 ReadXMLInformation();
135 // Check that a ROI is not already present
136 mInitialImageIndex += mImageIndex;
137 if (mInitialImageIndex >= mMainWindow->GetSlicerManagers().size()) {
138 QMessageBox::warning(this, "ROIManager tool", QString("Image index %1 not found, abort.").arg(mInitialImageIndex));
143 // Set the attached image
144 mCurrentSlicerManager = mMainWindow->GetSlicerManagers()[mInitialImageIndex];
147 // Tab insertion, check that another tool does not already exist for this image
148 std::vector<vvToolBaseBase*> & tools =
149 vvToolManager::GetInstance()->GetToolCreatorFromName(GetToolName())->GetListOfTool();
150 if (tools.size() > 0) {
151 for(uint i=0; i<tools.size()-1; i++) { // current tool is last
152 vvToolROIManager * t = dynamic_cast<vvToolROIManager*>(tools[i]);
153 if (mCurrentSlicerManager == t->GetCurrentSlicerManager()) {
154 QMessageBox::warning(this, "ROIManager tool", "Already a ROI for this image, abort.");
161 // Display tool in the correct tab
162 QWidget * tab = qFindChild<QWidget*>(mMainWindow->GetTab(), "ROItab");
163 tab->layout()->addWidget(this);
165 // If not read in a file we start automatically the browser to load
166 // a roi file (binary image)
168 mOpenFileBrowserFlag = false;
169 InputIsSelected(mCurrentSlicerManager);
170 mOpenFileBrowserFlag = true;
172 else InputIsSelected(mCurrentSlicerManager);
174 // Load ROI (if read in the XML files, empty otherwise)
175 OpenBinaryImage(mROIFilenames);
177 // Set the options to the open roi
178 for(uint i=0; i<mROIActorsParamList.size(); i++) {
179 QSharedPointer<vvROIActor> roi = mROIActorsList[i];
180 QSharedPointer<vvROIActor> roi_param = mROIActorsParamList[i];
181 roi->CopyParameters(roi_param);
184 QTreeWidgetItem * w = mMapROIToTreeWidget[roi->GetROI()];
185 QBrush brush(QColor(roi->GetROI()->GetDisplayColor()[0]*255,
186 roi->GetROI()->GetDisplayColor()[1]*255,
187 roi->GetROI()->GetDisplayColor()[2]*255));
188 brush.setStyle(Qt::SolidPattern);
189 w->setBackground(2, brush);
190 w->setText(3, QString("%1").arg(roi->GetDepth()));
196 UpdateAllROIStatus();
198 // Connect event from mainwindow to this widget
199 connect(mMainWindow, SIGNAL(AnImageIsBeingClosed(vvSlicerManager *)),
200 this, SLOT(AnImageIsBeingClosed(vvSlicerManager *)));
201 connect(mMainWindow, SIGNAL(SelectedImageHasChanged(vvSlicerManager *)),
202 this, SLOT(SelectedImageHasChanged(vvSlicerManager *)));
203 connect(mOpenBinaryButton, SIGNAL(clicked()), this, SLOT(OpenBinaryImage()));
204 connect(mOpenDicomButton, SIGNAL(clicked()), this, SLOT(OpenDicomImage()));
205 connect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedItemChangedInTree()));
206 connect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleROIToggled(bool)));
207 connect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityChanged(int)));
208 connect(mChangeColorButton, SIGNAL(clicked()), this, SLOT(ChangeColor()));
209 connect(mContourCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleContourROIToggled(bool)));
210 connect(mChangeContourColorButton, SIGNAL(clicked()), this, SLOT(ChangeContourColor()));
211 connect(mContourWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeContourWidth(int)));
212 connect(mDepthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeDepth(int)));
213 connect(mReloadButton, SIGNAL(clicked()), this, SLOT(ReloadCurrentROI()));
214 connect(mCheckBoxShowAll, SIGNAL(stateChanged(int)), this, SLOT(AllVisibleROIToggled(int)));
215 connect(mContourCheckBoxShowAll, SIGNAL(toggled(bool)), this, SLOT(AllVisibleContourROIToggled(bool)));
216 connect(mCloseButton, SIGNAL(clicked()), this, SLOT(close()));
218 //------------------------------------------------------------------------------
221 //------------------------------------------------------------------------------
222 void vvToolROIManager::InputIsSelected(vvSlicerManager *m)
225 mCurrentSlicerManager = m;
226 mCurrentImage = mCurrentSlicerManager->GetImage();
228 // Refuse if non 3D image
229 if (mCurrentImage->GetNumberOfDimensions() != 3) {
230 QMessageBox::information(this,tr("Sorry only 3D yet"), tr("Sorry only 3D yet"));
236 mLabelInputInfo->setText(QString("%1").arg(m->GetFileName().c_str()));
238 // Auto display browser to select new contours
239 if (mOpenFileBrowserFlag) OpenBinaryImage();
241 //------------------------------------------------------------------------------
244 //------------------------------------------------------------------------------
245 void vvToolROIManager::AnImageIsBeingClosed(vvSlicerManager * m)
247 if (m == mCurrentSlicerManager) {
252 //------------------------------------------------------------------------------
255 //------------------------------------------------------------------------------
256 void vvToolROIManager::close()
258 disconnect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedItemChangedInTree()));
259 disconnect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleROIToggled(bool)));
260 disconnect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityChanged(int)));
261 disconnect(mChangeColorButton, SIGNAL(clicked()), this, SLOT(ChangeColor()));
262 disconnect(mContourCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleContourROIToggled(bool)));
263 disconnect(mChangeContourColorButton, SIGNAL(clicked()), this, SLOT(ChangeContourColor()));
264 disconnect(mContourWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeContourWidth(int)));
265 disconnect(mDepthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeDepth(int)));
268 for (unsigned int i = 0; i < mROIActorsList.size(); i++) {
269 mROIActorsList[i]->RemoveActors();
271 mROIActorsList.clear();
274 for(int i=0; i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
275 mCurrentSlicerManager->GetSlicer(i)->Render();
278 //------------------------------------------------------------------------------
281 //------------------------------------------------------------------------------
282 void vvToolROIManager::SelectedImageHasChanged(vvSlicerManager * m) {
284 if (mCurrentSlicerManager == NULL) return;
285 if (m == NULL) return;
286 if (m != mCurrentSlicerManager) hide();
291 //------------------------------------------------------------------------------
294 //------------------------------------------------------------------------------
295 void vvToolROIManager::OpenBinaryImage()
298 QString Extensions = "Images or Dicom-Struct files ( *.mha *.mhd *.hdr *.his *.dcm RS*)";
299 Extensions += ";;All Files (*)";
300 QStringList filename =
301 QFileDialog::getOpenFileNames(this,tr("Open binary image"),
302 mMainWindowBase->GetInputPathName(),Extensions);
303 if (filename.size() > 1) OpenBinaryImage(filename);
304 if (filename.size() == 0) return;
307 //------------------------------------------------------------------------------
310 //------------------------------------------------------------------------------
311 void vvToolROIManager::OpenBinaryImage(QStringList & filename)
313 if (filename.size() == 0) return;
315 // For each selected file, open the image
316 for(int i=0; i<filename.size(); i++) {
318 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
319 vvImageReader::Pointer reader = vvImageReader::New();
320 std::vector<std::string> filenames;
321 filenames.push_back(filename[i].toStdString());
322 reader->SetInputFilenames(filenames);
323 reader->Update(vvImageReader::IMAGE);
324 QApplication::restoreOverrideCursor();
326 if (reader->GetLastError().size() != 0) {
327 std::cerr << "Error while reading " << filename[i].toStdString() << std::endl;
328 QString error = "Cannot open file \n";
329 error += reader->GetLastError().c_str();
330 QMessageBox::information(this,tr("Reading problem"),error);
333 vvImage::Pointer binaryImage = reader->GetOutput();
334 AddImage(binaryImage, filename[i].toStdString(), mBackgroundValueSpinBox->value(),
335 (!mBGModeCheckBox->isChecked()));
336 // mOpenedBinaryImage.push_back(binaryImage);
337 mOpenedBinaryImageFilenames.push_back(filename[i]);
338 //mMapImageToIndex[binaryImage]=mOpenedBinaryImageFilenames.size()-1;
341 // Update the contours
344 //------------------------------------------------------------------------------
347 //------------------------------------------------------------------------------
348 void vvToolROIManager::OpenDicomImage()
350 DD("OpenDicomImage");
351 QString Extensions = "Dicom Files ( *.dcm RS*)";
352 Extensions += ";;All Files (*)";
353 QString file = QFileDialog::getOpenFileName(this,tr("Merge Images"),
354 mMainWindow->GetInputPathName(),
356 if (file.isNull()) return;
358 // AddDCStructContour(index, file);
360 reader.SetFilename(file.toStdString());
361 vvStructSelector selector;
362 selector.SetStructures(reader.GetROINames());
363 // selector.EnablePropagationCheckBox(); FIXME Disable
365 // FIXME : change text -> allow to save binary image
367 if (selector.exec()) {
368 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
369 reader.SetSelectedItems(selector.getSelectedItems());
370 reader.SetImage(mCurrentSlicerManager->GetImage());
373 // Read and display information
374 clitk::DicomRT_StructureSet::Pointer s = clitk::DicomRT_StructureSet::New();
375 s->Read(file.toStdString());
378 // FIXME -> selection
381 clitk::DicomRTStruct2ImageFilter filter;
382 filter.SetCropMaskEnabled(true); // FIXME
383 filter.SetImage(mCurrentImage); // Used FIXME -> change to set IMAGE
384 filter.SetROI(s->GetROIFromROINumber(1)); // FIXME selection
385 filter.SetWriteOutputFlag(false);
389 typedef itk::Image<unsigned char, 3> ImageType;
390 typedef itk::VTKImageToImageFilter<ImageType> ConnectorType;
391 ConnectorType::Pointer connector = ConnectorType::New();
392 connector->SetInput(filter.GetOutput());
394 clitk::writeImage<ImageType>(connector->GetOutput(), "toto.mha");
398 vvImage::Pointer binaryImage = vvImage::New();
399 binaryImage->AddVtkImage(filter.GetOutput());
403 vvImageWriter::Pointer writer = vvImageWriter::New();
404 writer->SetOutputFileName("bidon.mha");
405 writer->SetInput(binaryImage);
410 AddImage(binaryImage, file.toStdString(), mBackgroundValueSpinBox->value(),
411 (!mBGModeCheckBox->isChecked()));
412 mOpenedBinaryImageFilenames.push_back(file);
414 // std::vector<vvMesh::Pointer> contours=reader.GetOutput();
415 // for (std::vector<vvMesh::Pointer>::iterator i=contours.begin();
416 // i!=contours.end(); i++)
417 // AddContour(index,*i,selector.PropagationEnabled());
418 QApplication::restoreOverrideCursor();
424 //------------------------------------------------------------------------------
427 //------------------------------------------------------------------------------
428 void vvToolROIManager::AddImage(vvImage * binaryImage, std::string filename,
429 double BG, bool modeBG)
432 int dim = mCurrentImage->GetNumberOfDimensions();
433 int bin_dim = binaryImage->GetNumberOfDimensions();
435 std::ostringstream os;
436 os << "Error. Loaded binary image is " << bin_dim
437 << "D while selected image is " << dim << "D" << std::endl;
438 QMessageBox::information(this,tr("Reading problem"),os.str().c_str());
443 int n = mROIList.size();
445 // Compute the name of the new ROI
446 std::ostringstream oss;
447 oss << vtksys::SystemTools::GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(filename));
448 std::string name = oss.str();
451 std::vector<double> color;
457 clitk::DicomRT_ROI::Pointer roi = clitk::DicomRT_ROI::New();
458 roi->SetFromBinaryImage(binaryImage, n, name, color, filename);
460 // Add a new roi to the list
461 mROIList.push_back(roi);
465 roi->SetBackgroundValueLabelImage(BG);
467 roi->SetForegroundValueLabelImage(BG);
470 if (n<mDefaultLUTColor->GetNumberOfTableValues ()) {
471 double * color = mDefaultLUTColor->GetTableValue(n % mDefaultLUTColor->GetNumberOfTableValues ());
472 roi->SetDisplayColor(color[0], color[1], color[2]);
475 // Add a new roi actor
476 QSharedPointer<vvROIActor> actor = QSharedPointer<vvROIActor>(new vvROIActor);
477 actor->SetBGMode(modeBG);
479 actor->SetSlicerManager(mCurrentSlicerManager);
480 actor->Initialize(n+1); // depth is n+1 to start at 1
481 mROIActorsList.push_back(actor);
483 // CheckBox for "All"
484 if (actor->IsVisible()) mNumberOfVisibleROI++;
485 if (actor->IsContourVisible()) mNumberOfVisibleContourROI++;
488 mTreeWidgetList.push_back(QSharedPointer<QTreeWidgetItem>(new QTreeWidgetItem(mTree)));
489 QTreeWidgetItem * w = mTreeWidgetList.back().data();
490 w->setText(0, QString("%1").arg(roi->GetROINumber()));
491 w->setText(1, QString("%1").arg(roi->GetName().c_str()));
492 w->setText(3, QString("%1").arg(actor->GetDepth()));
493 QBrush brush(QColor(roi->GetDisplayColor()[0]*255,
494 roi->GetDisplayColor()[1]*255,
495 roi->GetDisplayColor()[2]*255));
496 brush.setStyle(Qt::SolidPattern);
497 w->setBackground(2, brush);
498 mMapROIToTreeWidget[roi] = w;
499 mMapTreeWidgetToROI[w] = roi;
500 mTree->resizeColumnToContents(0);
501 mTree->resizeColumnToContents(1);
504 UpdateAllROIStatus();
506 //------------------------------------------------------------------------------
509 //------------------------------------------------------------------------------
510 void vvToolROIManager::UpdateAllContours()
512 if (mCurrentSlicerManager == NULL) return;
513 // Render loaded ROIs (the first is sufficient)
514 for(unsigned int i=0; i<mROIList.size(); i++) {
515 mROIActorsList[i]->Update();
517 for(int i=0; i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
518 mCurrentSlicerManager->GetSlicer(i)->Render();
521 //------------------------------------------------------------------------------
524 //------------------------------------------------------------------------------
525 void vvToolROIManager::UpdateAllROIStatus() {
527 int nb = mROIList.size();
528 for(int i=0; i<nb; i++) {
529 if (mROIActorsList[i]->IsVisible()) {
535 disconnect(mCheckBoxShowAll, SIGNAL(stateChanged(int)), this, SLOT(AllVisibleROIToggled(int)));
536 disconnect(mContourCheckBoxShowAll, SIGNAL(toggled(bool)), this, SLOT(AllVisibleContourROIToggled(bool)));
537 if (nbVisible == nb) mCheckBoxShowAll->setCheckState(Qt::Checked);
539 if (nbVisible == 0) mCheckBoxShowAll->setCheckState(Qt::Unchecked);
540 else mCheckBoxShowAll->setCheckState(Qt::PartiallyChecked);
542 connect(mContourCheckBoxShowAll, SIGNAL(toggled(bool)), this, SLOT(AllVisibleContourROIToggled(bool)));
543 connect(mCheckBoxShowAll, SIGNAL(stateChanged(int)), this, SLOT(AllVisibleROIToggled(int)));
545 //------------------------------------------------------------------------------
548 //------------------------------------------------------------------------------
549 void vvToolROIManager::SelectedItemChangedInTree() {
550 // Search which roi is selected
551 QList<QTreeWidgetItem *> l = mTree->selectedItems();
553 // mCurrentROIActor = 0;
555 mGroupBoxROI->setEnabled(false);
558 QTreeWidgetItem * w = l[0];
559 if (w == NULL) return;
561 if (mMapTreeWidgetToROI.find(w) == mMapTreeWidgetToROI.end()) {
562 // mCurrentROIActor = 0;
564 mGroupBoxROI->setEnabled(false);
567 if (w == NULL) return;
568 clitk::DicomRT_ROI * roi = mMapTreeWidgetToROI[w];
569 if (roi == NULL) return; // sometimes it is called while there is no roi anymore
571 // Get selected roi actor
572 int n = roi->GetROINumber();
573 QSharedPointer<vvROIActor> actor = mROIActorsList[n];
575 mCurrentROIActor = actor;
577 // Warning -> avoid unuseful Render here by disconnect slider
579 disconnect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedItemChangedInTree()));
580 disconnect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleROIToggled(bool)));
581 disconnect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityChanged(int)));
582 disconnect(mChangeColorButton, SIGNAL(clicked()), this, SLOT(ChangeColor()));
583 disconnect(mContourCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleContourROIToggled(bool)));
584 disconnect(mChangeContourColorButton, SIGNAL(clicked()), this, SLOT(ChangeContourColor()));
585 disconnect(mContourWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeContourWidth(int)));
586 disconnect(mDepthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeDepth(int)));
588 mROInameLabel->setText(roi->GetName().c_str());
589 mCheckBoxShow->setChecked(actor->IsVisible());
590 mContourCheckBoxShow->setChecked(actor->IsContourVisible());
591 mContourWidthSpinBox->setValue(actor->GetContourWidth());
592 mDepthSpinBox->setValue(actor->GetDepth());
593 w->setText(3, QString("%1").arg(actor->GetDepth()));
594 mOpacitySlider->setValue((int)lrint(actor->GetOpacity()*100));
595 mOpacitySpinBox->setValue((int)lrint(actor->GetOpacity()*100));
597 connect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedItemChangedInTree()));
598 connect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleROIToggled(bool)));
599 connect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityChanged(int)));
600 connect(mChangeColorButton, SIGNAL(clicked()), this, SLOT(ChangeColor()));
601 connect(mContourCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleContourROIToggled(bool)));
602 connect(mChangeContourColorButton, SIGNAL(clicked()), this, SLOT(ChangeContourColor()));
603 connect(mContourWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeContourWidth(int)));
604 connect(mDepthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeDepth(int)));
607 // Set the current color to the selected ROI name
608 mROInameLabel->setAutoFillBackground(true);// # This is important!!
609 // mROInameLabel->setStyleSheet("QLabel { background-color : red; color : blue; }");
610 QColor color = QColor(mCurrentROI->GetDisplayColor()[0]*255,
611 mCurrentROI->GetDisplayColor()[1]*255,
612 mCurrentROI->GetDisplayColor()[2]*255);
613 // QString values = QString("%1, %2, %3").arg(color.red()).arg(color.green()).arg(color.blue());
614 // mROInameLabel->setStyleSheet("QLabel { background-color: rgb("+values+"); }");
616 QPalette* palette = new QPalette();
617 QColor colorFG = QColor((1-mCurrentROI->GetDisplayColor()[0])*255,
618 (1-mCurrentROI->GetDisplayColor()[1])*255,
619 (1-mCurrentROI->GetDisplayColor()[2])*255);
620 palette->setColor(QPalette::WindowText,colorFG);
621 palette->setColor(QPalette::Background, color);
622 mROInameLabel->setPalette(*palette);
624 // Enable the group box (in case no selection before)
625 mGroupBoxROI->setEnabled(true);
627 //------------------------------------------------------------------------------
630 //------------------------------------------------------------------------------
631 void vvToolROIManager::VisibleROIToggled(bool b) {
632 if (mCurrentROIActor == NULL) return;
633 if (b == mCurrentROIActor->IsVisible()) return; // nothing to do
634 mCurrentROIActor->SetVisible(b);
635 UpdateAllROIStatus();
636 mCurrentSlicerManager->Render();
638 //------------------------------------------------------------------------------
641 //------------------------------------------------------------------------------
642 void vvToolROIManager::VisibleContourROIToggled(bool b) {
643 if (mCurrentROIActor == NULL) return;
644 if (mCurrentROIActor->IsContourVisible() == b) return; // nothing to do
645 mCurrentROIActor->SetContourVisible(b);
646 mCurrentROIActor->UpdateColor();
647 mCurrentSlicerManager->Render();
649 //------------------------------------------------------------------------------
652 //------------------------------------------------------------------------------
653 void vvToolROIManager::OpacityChanged(int v) {
654 if (mCurrentROIActor == NULL) return;
655 mCurrentROIActor->SetOpacity((double)v/100.0);
656 mCurrentROIActor->UpdateColor();
657 mCurrentSlicerManager->Render();
659 //------------------------------------------------------------------------------
662 //------------------------------------------------------------------------------
663 void vvToolROIManager::AllVisibleROIToggled(int b) {
665 if ((mCheckBoxShowAll->checkState() == Qt::Checked) ||
666 (mCheckBoxShowAll->checkState() == Qt::PartiallyChecked)) status = true;
668 for(uint i=0; i<mROIList.size(); i++) {
669 mROIActorsList[i]->SetVisible(status);
671 if (status) mCheckBoxShowAll->setCheckState(Qt::Checked);
672 else mCheckBoxShowAll->setCheckState(Qt::Unchecked);
673 mCheckBoxShow->setChecked(status);
674 mCurrentSlicerManager->Render();
676 //------------------------------------------------------------------------------
679 //------------------------------------------------------------------------------
680 void vvToolROIManager::AllVisibleContourROIToggled(bool b) {
682 if ((mContourCheckBoxShowAll->checkState() == Qt::Checked) ||
683 (mContourCheckBoxShowAll->checkState() == Qt::PartiallyChecked)) status = true;
685 for(uint i=0; i<mROIActorsList.size(); i++) {
686 mROIActorsList[i]->SetContourVisible(status);
688 // Update current selection
689 if (status) mContourCheckBoxShowAll->setCheckState(Qt::Checked);
690 else mContourCheckBoxShowAll->setCheckState(Qt::Unchecked);
691 mContourCheckBoxShow->setChecked(status);
692 mCurrentSlicerManager->Render();
694 //------------------------------------------------------------------------------
697 //------------------------------------------------------------------------------
698 void vvToolROIManager::ChangeColor() {
699 if (mCurrentROIActor == NULL) return;
701 color.setRgbF(mCurrentROIActor->GetROI()->GetDisplayColor()[0],
702 mCurrentROIActor->GetROI()->GetDisplayColor()[1],
703 mCurrentROIActor->GetROI()->GetDisplayColor()[2]);
704 QColor c = QColorDialog::getColor(color, this, "Choose the ROI color");
705 mCurrentROIActor->GetROI()->SetDisplayColor(c.redF(), c.greenF(), c.blueF());
706 mCurrentROIActor->UpdateColor();
708 QTreeWidgetItem * w = mMapROIToTreeWidget[mCurrentROI];
709 QBrush brush(QColor(mCurrentROI->GetDisplayColor()[0]*255,
710 mCurrentROI->GetDisplayColor()[1]*255,
711 mCurrentROI->GetDisplayColor()[2]*255));
712 brush.setStyle(Qt::SolidPattern);
713 w->setBackground(2, brush);
715 mCurrentSlicerManager->Render();
717 //------------------------------------------------------------------------------
720 //------------------------------------------------------------------------------
721 void vvToolROIManager::ChangeContourColor() {
722 if (mCurrentROIActor == NULL) return;
724 color.setRgbF(mCurrentROIActor->GetContourColor()[0],
725 mCurrentROIActor->GetContourColor()[1],
726 mCurrentROIActor->GetContourColor()[2]);
727 // QColorDialog d(color);
728 QColor c = QColorDialog::getColor(color, this, "Choose the contour color");
729 if (!c.isValid()) return; // User cancel
730 mCurrentROIActor->SetContourColor(c.redF(), c.greenF(), c.blueF());
731 mCurrentROIActor->UpdateColor();
732 mCurrentSlicerManager->Render();
734 //------------------------------------------------------------------------------
737 //------------------------------------------------------------------------------
738 void vvToolROIManager::ChangeContourWidth(int n) {
739 if (mCurrentROIActor == NULL) return;
740 mCurrentROIActor->SetContourWidth(n);
741 mCurrentROIActor->UpdateColor();
742 mCurrentSlicerManager->Render();
744 //------------------------------------------------------------------------------
747 //------------------------------------------------------------------------------
748 void vvToolROIManager::ChangeDepth(int n) {
749 if (mCurrentROIActor == NULL) return;
750 mCurrentROIActor->SetDepth(n);
751 // mCurrentROIActor->UpdateImage(); // FIXME
752 mCurrentSlicerManager->Render();
753 QList<QTreeWidgetItem *> l = mTree->selectedItems();
754 QTreeWidgetItem * w = l[0];
755 w->setText(3, QString("%1").arg(mCurrentROIActor->GetDepth()));
757 //------------------------------------------------------------------------------
760 //------------------------------------------------------------------------------
761 void vvToolROIManager::ReloadCurrentROI() {
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 QMessageBox::information(mMainWindowBase, tr("Sorry, error. Could not reload"),
776 reader->GetLastError().c_str());
780 // Free the previous image
781 mCurrentROI->GetImage()->GetFirstVTKImageData()->ReleaseData(); // Needed to free
782 mCurrentROI->GetImage()->Reset();
783 mCurrentROI->SetImage(reader->GetOutput());
785 mCurrentROIActor->RemoveActors();
788 mCurrentROIActor->UpdateImage();
789 mCurrentROIActor->SetVisible(visible);
790 mCurrentROIActor->SetContourVisible(cvisible);
791 mCurrentSlicerManager->Render();
793 //------------------------------------------------------------------------------
796 //------------------------------------------------------------------------------
797 void vvToolROIManager::SaveState(std::auto_ptr<QXmlStreamWriter> & m_XmlWriter)
799 // Get index of the image
800 int n = mMainWindow->GetSlicerManagers().size();
802 for(int i=0; i<n; i++) {
803 if (mCurrentSlicerManager == mMainWindow->GetSlicerManagers()[i]) index = i;
806 std::cerr << "Error while writing state for ROIManager tool no currentimage founded." << std::endl;
809 m_XmlWriter->writeTextElement("Image_Index", QString::number(index));
813 for(uint i=0; i<mROIActorsList.size(); i++) {
814 QSharedPointer<vvROIActor> roi = mROIActorsList[i];
816 m_XmlWriter->writeStartElement("ROI");
817 m_XmlWriter->writeTextElement("Image", mOpenedBinaryImageFilenames[i]);
819 m_XmlWriter->writeStartElement("Overlay");
820 m_XmlWriter->writeAttribute("Red", QString("%1").arg(roi->GetOverlayColor()[0]));
821 m_XmlWriter->writeAttribute("Green",QString("%1").arg(roi->GetOverlayColor()[1]));
822 m_XmlWriter->writeAttribute("Blue", QString("%1").arg(roi->GetOverlayColor()[2]));
823 m_XmlWriter->writeAttribute("Visible", QString("%1").arg(roi->IsVisible()));
824 m_XmlWriter->writeAttribute("Opacity", QString("%1").arg(roi->GetOpacity()));
825 m_XmlWriter->writeAttribute("Depth", QString("%1").arg(roi->GetDepth()));
826 m_XmlWriter->writeEndElement();
828 m_XmlWriter->writeStartElement("Contour");
829 m_XmlWriter->writeAttribute("Red", QString("%1").arg(roi->GetContourColor()[0]));
830 m_XmlWriter->writeAttribute("Green",QString("%1").arg(roi->GetContourColor()[1]));
831 m_XmlWriter->writeAttribute("Blue", QString("%1").arg(roi->GetContourColor()[2]));
832 m_XmlWriter->writeAttribute("Visible", QString("%1").arg(roi->IsContourVisible()));
833 m_XmlWriter->writeAttribute("Width", QString("%1").arg(roi->GetContourWidth()));
834 m_XmlWriter->writeEndElement();
836 m_XmlWriter->writeEndElement();
839 //------------------------------------------------------------------------------
842 //------------------------------------------------------------------------------
843 void vvToolROIManager::ReadXMLInformation()
845 std::string value="";
846 mInitialImageIndex = -1;
847 while (!(m_XmlReader->isEndElement() && value == GetToolName().toStdString())) {
848 m_XmlReader->readNext();
849 value = m_XmlReader->qualifiedName().toString().toStdString();
851 if (value == "Image_Index")
852 mInitialImageIndex = m_XmlReader->readElementText().toInt();
854 if (m_XmlReader->isStartElement()) {
855 if (value == "ROI") {
856 ReadXMLInformation_ROI();
861 //------------------------------------------------------------------------------
864 //------------------------------------------------------------------------------
865 void vvToolROIManager::ReadXMLInformation_ROI()
868 std::string value="";
869 QSharedPointer<vvROIActor> param = QSharedPointer<vvROIActor>(new vvROIActor);
870 param->SetVisible(true);
871 clitk::DicomRT_ROI::Pointer roi = clitk::DicomRT_ROI::New();
872 // r->SetDisplayColor(1,1,1);
875 float r=1.0,g=1.0,b=1.0;
876 float cr=1.0,cg=1.0,cb=1.0;
879 bool cvisible = true;
883 while (!(m_XmlReader->isEndElement() && value == "ROI")) {
884 m_XmlReader->readNext();
885 value = m_XmlReader->qualifiedName().toString().toStdString();
886 if (value == "Image") {
887 s = m_XmlReader->readElementText();
890 if (value == "Overlay" && m_XmlReader->isStartElement()) {
891 QXmlStreamAttributes attributes = m_XmlReader->attributes();
892 if (!m_XmlReader->hasError())
893 r = attributes.value("Red").toString().toFloat();
894 if (!m_XmlReader->hasError())
895 g = attributes.value("Green").toString().toFloat();
896 if (!m_XmlReader->hasError())
897 b = attributes.value("Blue").toString().toFloat();
898 if (!m_XmlReader->hasError())
899 visible = attributes.value("Visible").toString().toInt();
900 if (!m_XmlReader->hasError())
901 opacity = attributes.value("Opacity").toString().toFloat();
902 if (!m_XmlReader->hasError())
903 depth = attributes.value("Depth").toString().toFloat();
907 if (value == "Contour" && m_XmlReader->isStartElement()) {
908 QXmlStreamAttributes attributes = m_XmlReader->attributes();
909 if (!m_XmlReader->hasError())
910 cr = attributes.value("Red").toString().toFloat();
911 if (!m_XmlReader->hasError())
912 cg = attributes.value("Green").toString().toFloat();
913 if (!m_XmlReader->hasError())
914 cb = attributes.value("Blue").toString().toFloat();
915 if (!m_XmlReader->hasError())
916 cvisible = attributes.value("Visible").toString().toInt();
917 if (!m_XmlReader->hasError())
918 width = attributes.value("Width").toString().toFloat();
920 param->SetOverlayColor(r,g,b);
921 param->SetVisible(visible);
922 param->SetOpacity(opacity);
923 param->SetDepth(depth);
925 param->SetContourColor(cr,cg,cb);
926 param->SetContourVisible(cvisible);
927 param->SetContourWidth(width);
929 mROIFilenames.push_back(s);
930 mROIActorsParamList.push_back(param);
932 //------------------------------------------------------------------------------