X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=vv%2FvvMainWindow.cxx;h=1bc0759e8ee14671f60a29dcc493623f2f0293b0;hb=a7326d6b2149dc084a7101ff8063fb38fe22aa8e;hp=75b5cb44e68bd797e71dc4689b303e3c407d2d43;hpb=4f8838cea53d81913d650cc90c15cf1c2f04eacd;p=clitk.git diff --git a/vv/vvMainWindow.cxx b/vv/vvMainWindow.cxx index 75b5cb4..1bc0759 100644 --- a/vv/vvMainWindow.cxx +++ b/vv/vvMainWindow.cxx @@ -1,19 +1,19 @@ /*========================================================================= - Program: vv http://www.creatis.insa-lyon.fr/rio/vv +Program: vv http://www.creatis.insa-lyon.fr/rio/vv - Authors belong to: - - University of LYON http://www.universite-lyon.fr/ - - Léon Bérard cancer center http://www.centreleonberard.fr - - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr +Authors belong to: +- University of LYON http://www.universite-lyon.fr/ +- Léon Bérard cancer center http://www.centreleonberard.fr +- CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr - This software is distributed WITHOUT ANY WARRANTY; without even - the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. See the copyright notices for more information. +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the copyright notices for more information. - It is distributed under dual licence +It is distributed under dual licence - - BSD See included LICENSE.txt file - - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html +- BSD See included LICENSE.txt file +- CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html ===========================================================================**/ #include @@ -23,6 +23,7 @@ #include "QTreePushButton.h" #include #include +#include // VV include #include "vvMainWindow.h" @@ -48,6 +49,10 @@ #include "vvSaveState.h" #include "vvReadState.h" #include "clitkConfiguration.h" +#include "clitkMatrix.h" +#ifdef Q_OS_OSX +# include "vvOSXHelper.h" +#endif // ITK include #include @@ -57,6 +62,9 @@ #include // VTK include +#include +#include +#include #include #include #include @@ -88,6 +96,7 @@ // Standard includes #include +#include #include #include @@ -100,27 +109,31 @@ #define COLUMN_RELOAD_IMAGE 6 #define COLUMN_IMAGE_NAME 7 -#if CLITK_PRIVATE_FEATURES - #define EXTENSIONS "Images ( *.bmp *.png *.jpeg *.jpg *.tif *.mhd *.mha *.hdr *.vox *.his *.xdr *.SCAN *.nii *.nrrd *.nhdr *.nii.gz *.usf)" +#ifdef CLITK_PRIVATE_FEATURES +#define EXTENSIONS "Images ( *.bmp *.dcm *.png *.jpeg *.jpg *.tif *.mhd *.mha *.hdr *.vox *.his *.xdr *.SCAN *.nii *.nrrd *.nhdr *.refscan *.nii.gz *.usf *.svl)" #else - #define EXTENSIONS "Images ( *.bmp *.png *.jpeg *.jpg *.tif *.mhd *.mha *.hdr *.vox *.his *.xdr *.SCAN *.nii *.nrrd *.nhdr *.nii.gz)" +#define EXTENSIONS "Images ( *.bmp *.dcm *.png *.jpeg *.jpg *.tif *.mhd *.mha *.hdr *.vox *.his *.xdr *.SCAN *.nii *.nrrd *.nhdr *.refscan *.nii.gz)" #endif + /*Data Tree values - 0,Qt::UserRole full filename - 1,Qt::CheckStateRole checkbutton UL View - 1,Qt::UserRole overlay, fusion or vector - 2,Qt::CheckStateRole checkbutton UR View - 3,Qt::CheckStateRole checkbutton DL View - 4,Qt::CheckStateRole checkbutton DR View - 5,0 short filename - 5,Qt::UserRole mSlicerManager id*/ +0,Qt::UserRole full filename +1,Qt::CheckStateRole checkbutton UL View +1,Qt::UserRole overlay, fusion or vector +2,Qt::CheckStateRole checkbutton UR View +3,Qt::CheckStateRole checkbutton DL View +4,Qt::CheckStateRole checkbutton DR View +5,0 short filename +5,Qt::UserRole mSlicerManager id*/ //------------------------------------------------------------------------------ vvMainWindow::vvMainWindow():vvMainWindowBase() -{ +{ setupUi(this); // this sets up the GUI + //Qt::WindowFlags flags = windowFlags(); + //setWindowFlags(flags | Qt::WindowStaysOnTopHint); + mInputPathName = ""; mMenuTools = menuTools; // mMenuSegmentation = menuSegmentation; @@ -136,34 +149,33 @@ vvMainWindow::vvMainWindow():vvMainWindowBase() this->setContextMenuPolicy(Qt::CustomContextMenu); contextActions.resize(0); QAction* actionOpen_new_image = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/fileopen.png")), - tr("O&pen new Image")); - actionOpen_new_image->setShortcut(QKeySequence(tr("Ctrl+O"))); + tr("O&pen new Image")); connect(actionOpen_new_image,SIGNAL(triggered()),this,SLOT(OpenImages())); contextActions.push_back(actionOpen_new_image); contextMenu.addSeparator(); QAction* actionClose_Image = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/exit.png")), - tr("Close Current Image")); + tr("Close Current Image")); connect(actionClose_Image,SIGNAL(triggered()),this,SLOT(CloseImage())); contextActions.push_back(actionClose_Image); QAction* actionReload_image = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/rotateright.png")), - tr("Reload Current Image")); + tr("Reload Current Image")); connect(actionReload_image,SIGNAL(triggered()),this,SLOT(ReloadImage())); contextActions.push_back(actionReload_image); QAction* actionSave_image = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/filesave.png")), - tr("Save Current Image")); + tr("Save Current Image")); connect(actionSave_image,SIGNAL(triggered()),this,SLOT(SaveAs())); contextActions.push_back(actionSave_image); QAction* actionSave_state = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/filesave.png")), - tr("Save Current State")); + tr("Save Current State")); connect(actionSave_state,SIGNAL(triggered()),this,SLOT(SaveCurrentState())); contextActions.push_back(actionSave_state); QAction* actionRead_state = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/filesave.png")), - tr("Read Saved State")); + tr("Read Saved State")); connect(actionRead_state,SIGNAL(triggered()),this,SLOT(ReadSavedState())); contextActions.push_back(actionRead_state); @@ -180,26 +192,17 @@ vvMainWindow::vvMainWindow():vvMainWindowBase() contextMenu.addAction(actionAdd_fusion_image); contextActions.push_back(actionAdd_fusion_image); +#ifdef CLITK_EXPERIMENTAL + contextMenu.addAction(actionAdd_USSequence_toCT); + contextActions.push_back(actionAdd_USSequence_toCT); +#endif + + contextMenu.addSeparator(); QAction* actionResetMatrix = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/identity.png")), - tr("Reset transformation to identity")); + tr("Reset transformation to identity")); connect(actionResetMatrix, SIGNAL(triggered()), this,SLOT(ResetTransformationToIdentity())); - // TRIAL DS - /* - QMenu * m = new QMenu(menubar); - m->setTitle("TOTO"); - // m->setObjectName(QString::fromUtf8("TOTOTO")); - contextMenu.addMenu(m); - QAction * a = m->addAction(QIcon(QString::fromUtf8(":/common/icons/GPSup.png")), - tr("BIDON")); - QAction * b = m->addAction(QIcon(QString::fromUtf8(":/common/icons/GPSup.png")), - tr("BIDON2")); - m->addAction(a); - m->addAction(b); - connect(a,SIGNAL(triggered()),this,SLOT(AddFusionImage())); - */ - //init the DataTree mSlicerManagers.resize(0); @@ -233,6 +236,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase() actionSave_As->setEnabled(0); actionAdd_VF_to_current_Image->setEnabled(0); actionAdd_fusion_image->setEnabled(0); + actionAdd_USSequence_toCT->setEnabled(0); //init the sliders verticalSliders.push_back(NOVerticalSlider); @@ -268,7 +272,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase() connect(actionWarp_image_with_vector_field,SIGNAL(triggered()),this,SLOT(WarpImage())); connect(actionLoad_images,SIGNAL(triggered()),this,SLOT(OpenImages())); connect(actionOpen_Dicom,SIGNAL(triggered()),this,SLOT(OpenDicom())); - connect(actionOpen_Dicom_Struct,SIGNAL(triggered()),this,SLOT(OpenDCStructContour())); + // connect(actionOpen_Dicom_Struct,SIGNAL(triggered()),this,SLOT(OpenDCStructContour())); connect(actionOpen_VTK_contour,SIGNAL(triggered()),this,SLOT(OpenVTKContour())); connect(actionOpen_Multiple_Images_As_One,SIGNAL(triggered()),this,SLOT(MergeImages())); connect(actionSlice_Image_As_Multiple_Images,SIGNAL(triggered()),this,SLOT(SliceImages())); @@ -280,10 +284,20 @@ vvMainWindow::vvMainWindow():vvMainWindowBase() connect(actionExit,SIGNAL(triggered()),this,SLOT(close())); connect(actionAdd_VF_to_current_Image,SIGNAL(triggered()),this,SLOT(OpenField())); connect(actionAdd_fusion_image,SIGNAL(triggered()),this,SLOT(SelectFusionImage())); - connect(actionAdd_overlay_image_to_current_image,SIGNAL(triggered()), this,SLOT(SelectOverlayImage())); connect(actionNavigation_Help,SIGNAL(triggered()),this,SLOT(ShowHelpDialog())); + connect(actionAdd_overlay_image_to_current_image,SIGNAL(triggered()), this,SLOT(SelectOverlayImage())); + connect(actionAdd_USSequence_toCT,SIGNAL(triggered()), this,SLOT(SelectFusionSequence())); + connect(actionNavigation_Help,SIGNAL(triggered()),this,SLOT(ShowHelpDialog())); + + QShortcut *shortcutHelp = new QShortcut(QKeySequence(QKeySequence::HelpContents),this); + shortcutHelp->setContext(Qt::ApplicationShortcut); + QObject::connect(shortcutHelp, SIGNAL(activated()), this, SLOT(ShowHelpDialog())); + connect(actionDocumentation,SIGNAL(triggered()),this,SLOT(ShowDocumentation())); connect(actionRegister_vv,SIGNAL(triggered()),this,SLOT(PopupRegisterForm())); + connect(overlayPanel, SIGNAL(FusionSequenceCorrespondancesButtonPressed()), this, SLOT(SelectFusionSequenceCorrespondances())); + + /////////////////////////////////////////////// connect(actionSegmentation,SIGNAL(triggered()),this,SLOT(SegmentationOnCurrentImage())); connect(actionSurface_Viewer,SIGNAL(triggered()),this,SLOT(SurfaceViewerLaunch())); @@ -302,7 +316,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase() connect(DataTree,SIGNAL(itemSelectionChanged()),this,SLOT(ImageInfoChanged())); connect(DataTree,SIGNAL(itemClicked(QTreeWidgetItem*, int)),this, - SLOT(DisplayChanged(QTreeWidgetItem*, int))); + SLOT(DisplayChanged(QTreeWidgetItem*, int))); connect(viewButton,SIGNAL(clicked()),this, SLOT(ChangeViewMode()) ); connect(windowSpinBox,SIGNAL(editingFinished()),this,SLOT(WindowLevelEdited())); @@ -319,10 +333,15 @@ vvMainWindow::vvMainWindow():vvMainWindowBase() connect(linkPanel,SIGNAL(removeLink(QString,QString)),this,SLOT(RemoveLink(QString,QString))); connect(overlayPanel,SIGNAL(VFPropertyUpdated(int,int,int,int,double,double,double)),this,SLOT(SetVFProperty(int,int,int,int,double,double,double))); connect(overlayPanel,SIGNAL(OverlayPropertyUpdated(int,int,double,double)), - this,SLOT(SetOverlayProperty(int,int,double,double))); + this,SLOT(SetOverlayProperty(int,int,double,double))); connect(overlayPanel,SIGNAL(FusionPropertyUpdated(int,int,int,double,double, bool)), - this,SLOT(SetFusionProperty(int,int,int,double,double, bool))); + this,SLOT(SetFusionProperty(int,int,int,double,double, bool))); connect(landmarksPanel,SIGNAL(UpdateRenderWindows()),this,SLOT(UpdateRenderWindows())); + connect(landmarksPanel,SIGNAL(SelectedPointChanged()),this,SLOT(GoToLandmark())); + + connect(overlayPanel,SIGNAL(FusionSequencePropertyUpdated(int, bool, unsigned int, bool)), + this,SLOT(SetFusionSequenceProperty(int, bool,unsigned int, bool))); + playMode = 0;//pause mFrameRate = 10; @@ -340,6 +359,13 @@ vvMainWindow::vvMainWindow():vvMainWindowBase() SOViewWidget->hide(); SEViewWidget->hide(); +#ifdef Q_OS_OSX + disableGLHiDPI(NOViewWidget->winId()); + disableGLHiDPI(NEViewWidget->winId()); + disableGLHiDPI(SOViewWidget->winId()); + disableGLHiDPI(SEViewWidget->winId()); +#endif + //Recently opened files std::list recent_files = GetRecentlyOpenedImages(); recentlyOpenedFilesMenu=NULL; @@ -352,24 +378,29 @@ vvMainWindow::vvMainWindow():vvMainWindowBase() vvToolManager::GetInstance()->InsertToolsInMenu(this); vvToolManager::GetInstance()->EnableToolsInMenu(this, false); +//#ifndef CLITK_EXPERIMENTAL +//#define CLITK_EXPERIMENTAL 0 +//#endif +#ifdef CLITK_EXPERIMENTAL if (!CLITK_EXPERIMENTAL) menuExperimental->menuAction()->setVisible(false); - +#endif QTimer * timerMemory = new QTimer(this); //timerMemory->setInterval(5); connect(timerMemory, SIGNAL(timeout()), this, SLOT(UpdateMemoryUsage())); timerMemory->start(2000); } + //------------------------------------------------------------------------------ void vvMainWindow::show() -{ +{ vvMainWindowBase::show(); PopupRegisterForm(true); } //------------------------------------------------------------------------------ void vvMainWindow::UpdateMemoryUsage() -{ +{ // clitk::PrintMemory(true); if (clitk::GetMemoryUsageInMb() == 0) infoPanel->setMemoryInMb("NA"); else infoPanel->setMemoryInMb(QString::number(clitk::GetMemoryUsageInMb())+" MiB"); @@ -379,7 +410,7 @@ void vvMainWindow::UpdateMemoryUsage() //------------------------------------------------------------------------------ void vvMainWindow::createRecentlyOpenedFilesMenu() -{ +{ recentlyOpenedFilesMenu = new QMenu("Recently opened files..."); recentlyOpenedFilesMenu->setIcon(QIcon(QString::fromUtf8(":/common/icons/open.png"))); menuFile->insertMenu(actionOpen_Image_With_Time,recentlyOpenedFilesMenu); @@ -391,7 +422,7 @@ void vvMainWindow::createRecentlyOpenedFilesMenu() //------------------------------------------------------------------------------ void vvMainWindow::updateRecentlyOpenedFilesMenu(const std::list &recent_files) -{ +{ if(recentlyOpenedFilesMenu==NULL) { createRecentlyOpenedFilesMenu(); } else { @@ -408,11 +439,11 @@ void vvMainWindow::updateRecentlyOpenedFilesMenu(const std::list &r //------------------------------------------------------------------------------ void vvMainWindow::ComputeMidPosition() -{ +{ bool ok; int index=GetSlicerIndexFromItem(DataTree->selectedItems()[0]); - int ref = QInputDialog::getInteger(this,"Chose reference phase","Reference phase",0,0,\ - mSlicerManagers[index]->GetImage()->GetVTKImages().size()-1,1,&ok); + int ref = QInputDialog::getInt(this,"Chose reference phase","Reference phase",0,0,\ +mSlicerManagers[index]->GetImage()->GetVTKImages().size()-1,1,&ok); if (ok) { vvMidPosition midp; midp.slicer_manager = mSlicerManagers[index]; @@ -433,7 +464,7 @@ void vvMainWindow::ComputeMidPosition() //------------------------------------------------------------------------------ void vvMainWindow::AddContour(int image_index, vvMesh::Pointer contour, bool propagation) -{ +{ QTreeWidgetItem *item = new QTreeWidgetItem(); item->setData(0,Qt::UserRole,"filename.vtk"); item->setData(1,Qt::UserRole,tr("contour")); @@ -452,7 +483,7 @@ void vvMainWindow::AddContour(int image_index, vvMesh::Pointer contour, bool pro cButton->setToolTip(tr("close image")); cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png"))); connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)), - this,SLOT(CloseImage(QTreeWidgetItem*, int))); + this,SLOT(CloseImage(QTreeWidgetItem*, int))); QTreePushButton* rButton = new QTreePushButton; rButton->setItem(item); @@ -480,7 +511,7 @@ void vvMainWindow::AddContour(int image_index, vvMesh::Pointer contour, bool pro //------------------------------------------------------------------------------ void vvMainWindow::OpenVTKContour() -{ +{ if (mSlicerManagers.size() > 0) { QString Extensions = "Images ( *.vtk *.obj)"; Extensions += ";;All Files (*)"; @@ -503,31 +534,31 @@ void vvMainWindow::OpenVTKContour() //------------------------------------------------------------------------------ void vvMainWindow::AddDCStructContour(int index, QString file) -{ - vvMeshReader reader; - reader.SetFilename(file.toStdString()); - vvStructSelector selector; - selector.SetStructures(reader.GetROINames()); - if (!mSlicerManagers[index]->GetVF().IsNull()) - selector.EnablePropagationCheckBox(); - if (selector.exec()) { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - reader.SetSelectedItems(selector.getSelectedItems()); - reader.SetImage(mSlicerManagers[index]->GetImage()); - if (selector.PropagationEnabled()) - reader.SetPropagationVF(mSlicerManagers[index]->GetVF()); - reader.Update(); - std::vector contours=reader.GetOutput(); - for (std::vector::iterator i=contours.begin(); - i!=contours.end(); i++) - AddContour(index,*i,selector.PropagationEnabled()); - QApplication::restoreOverrideCursor(); - } +{ + vvMeshReader reader; + reader.SetFilename(file.toStdString()); + vvStructSelector selector; + selector.SetStructures(reader.GetROINames()); + if (!mSlicerManagers[index]->GetVF().IsNull()) + selector.EnablePropagationCheckBox(); + if (selector.exec()) { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + reader.SetSelectedItems(selector.getSelectedItems()); + reader.SetImage(mSlicerManagers[index]->GetImage()); + if (selector.PropagationEnabled()) + reader.SetPropagationVF(mSlicerManagers[index]->GetVF()); + reader.Update(); + std::vector contours=reader.GetOutput(); + for (std::vector::iterator i=contours.begin(); + i!=contours.end(); i++) + AddContour(index,*i,selector.PropagationEnabled()); + QApplication::restoreOverrideCursor(); + } } //------------------------------------------------------------------------------ void vvMainWindow::OpenDCStructContour() -{ +{ if (mSlicerManagers.size() > 0) { QString Extensions = "Dicom Files ( *.dcm RS*)"; Extensions += ";;All Files (*)"; @@ -543,7 +574,7 @@ void vvMainWindow::OpenDCStructContour() //------------------------------------------------------------------------------ void vvMainWindow::ComputeDeformableRegistration() -{ +{ if (mSlicerManagers.size() > 0) { int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); vvDeformationDialog dialog(index,mSlicerManagers); @@ -560,12 +591,12 @@ void vvMainWindow::ComputeDeformableRegistration() //------------------------------------------------------------------------------ void vvMainWindow::WarpImage() -{ +{ int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); if (!mSlicerManagers[index]->GetVF().IsNull()) { bool ok; - int ref = QInputDialog::getInteger(this,"Chose reference phase","Reference phase",0,0,\ - mSlicerManagers[index]->GetImage()->GetVTKImages().size()-1,1,&ok); + int ref = QInputDialog::getInt(this,"Chose reference phase","Reference phase",0,0,\ + mSlicerManagers[index]->GetImage()->GetVTKImages().size()-1,1,&ok); if (ok) { WarpImage(mSlicerManagers[index],ref); } @@ -577,12 +608,12 @@ void vvMainWindow::WarpImage() //------------------------------------------------------------------------------ void vvMainWindow::WarpImage(vvSlicerManager* selected_slicer,int reference_phase) -{ +{ if (!selected_slicer->GetVF().IsNull()) { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); QFileInfo info(selected_slicer->GetFileName().c_str()); vvImageWarp warp(selected_slicer->GetImage(),selected_slicer->GetVF(), - reference_phase,this); + reference_phase,this); if (warp.ComputeWarpedImage()) { AddImage(warp.GetWarpedImage(),info.path().toStdString()+"/"+info.completeBaseName().toStdString()+"_warped.mhd"); AddImage(warp.GetDiffImage() ,info.path().toStdString()+"/"+info.completeBaseName().toStdString()+"_diff.mhd"); @@ -600,17 +631,20 @@ void vvMainWindow::WarpImage(vvSlicerManager* selected_slicer,int reference_phas //------------------------------------------------------------------------------ vvMainWindow::~vvMainWindow() -{ +{ for (unsigned int i = 0; i < mSlicerManagers.size(); i++) { if (mSlicerManagers[i] != NULL) delete mSlicerManagers[i]; } + delete documentation; + delete help_dialog; + delete dicomSeriesSelector; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ QTabWidget * vvMainWindow::GetTab() -{ +{ return tabWidget; } //------------------------------------------------------------------------------ @@ -618,7 +652,7 @@ QTabWidget * vvMainWindow::GetTab() //------------------------------------------------------------------------------ void vvMainWindow::MergeImages() -{ +{ QString Extensions = EXTENSIONS; Extensions += ";;All Files (*)"; QStringList files = QFileDialog::getOpenFileNames(this,tr("Merge Images"),mInputPathName,Extensions); @@ -634,7 +668,7 @@ void vvMainWindow::MergeImages() for (int i = 0; i < files.size(); i++) { itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO( - files[i].toStdString().c_str(), itk::ImageIOFactory::ReadMode); + files[i].toStdString().c_str(), itk::ImageIOFactory::ReadMode); reader->SetFileName(files[i].toStdString().c_str()); reader->ReadImageInformation(); if (reader) { @@ -656,14 +690,14 @@ void vvMainWindow::MergeImages() currentSpacing[j] = reader->GetSpacing(j); currentSize[j] = reader->GetDimensions(j); } else if (currentDim != reader->GetNumberOfDimensions() - || currentSpacing[j] != reader->GetSpacing(j) - || currentSize[j] != (int)reader->GetDimensions(j) - || currentOrigin[j] != reader->GetOrigin(j)) { - QString error = "Cannot read file (too different from others "; - error += files[i].toStdString().c_str(); - QMessageBox::information(this,tr("Reading problem"),error); - IsOk = false; - break; + || currentSpacing[j] != reader->GetSpacing(j) + || currentSize[j] != (int)reader->GetDimensions(j) + || currentOrigin[j] != reader->GetOrigin(j)) { + QString error = "Cannot read file (too different from others "; + error += files[i].toStdString().c_str(); + QMessageBox::information(this,tr("Reading problem"),error); + IsOk = false; + break; } } if (IsOk) @@ -677,7 +711,7 @@ void vvMainWindow::MergeImages() //------------------------------------------------------------------------------ void vvMainWindow::SliceImages() -{ +{ QString Extensions = EXTENSIONS; Extensions += ";;All Files (*)"; @@ -694,7 +728,7 @@ void vvMainWindow::SliceImages() //------------------------------------------------------------------------------ void vvMainWindow::MergeImagesWithTime() -{ +{ QString Extensions = EXTENSIONS; Extensions += ";;All Files (*)"; QStringList files = QFileDialog::getOpenFileNames(this,tr("Merge Images With Time"),mInputPathName,Extensions); @@ -703,51 +737,8 @@ void vvMainWindow::MergeImagesWithTime() mInputPathName = itksys::SystemTools::GetFilenamePath(files[0].toStdString()).c_str(); std::vector vector; - unsigned int currentDim = 0; - std::vector currentSpacing; - std::vector currentSize; - std::vector currentOrigin; - - for (int i = 0; i < files.size(); i++) { - itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO( - files[i].toStdString().c_str(), itk::ImageIOFactory::ReadMode); - if (reader) { - reader->SetFileName(files[i].toStdString().c_str()); - reader->ReadImageInformation(); - if (i == 0) - currentDim = reader->GetNumberOfDimensions(); - bool IsOk = true; - for (unsigned int j = 0; j < currentDim; j++) { - if (i == 0) { - if (j == 0) { - currentSpacing.resize(currentDim); - currentSize.resize(currentDim); - currentOrigin.resize(currentDim); - } - currentOrigin[j] = reader->GetOrigin(j); - currentSpacing[j] = reader->GetSpacing(j); - currentSize[j] = reader->GetDimensions(j); - } else if (currentDim != reader->GetNumberOfDimensions() - || currentSpacing[j] != reader->GetSpacing(j) - || currentSize[j] != (int)reader->GetDimensions(j) - || currentOrigin[j] != reader->GetOrigin(j)) { - QString error = "Cannot read file (too different from others "; - error += files[i].toStdString().c_str(); - QMessageBox::information(this,tr("Reading problem"),error); - IsOk = false; - break; - } - } - if (IsOk) - vector.push_back(files[i].toStdString()); - } else { - QString error = "Cannot read file info for "; - error += files[i].toStdString().c_str(); - error += "\n"; - error += "Maybe you're trying to open an image in an unsupported format?\n"; - QMessageBox::information(this,tr("Reading problem"),error); - } - } + for (int i = 0; i < files.size(); i++) + vector.push_back(files[i].toStdString()); sort(vector.begin(),vector.end()); if (vector.size() > 1) LoadImages(vector, vvImageReader::MERGEDWITHTIME); @@ -759,10 +750,10 @@ void vvMainWindow::MergeImagesWithTime() //------------------------------------------------------------------------------ void vvMainWindow::OpenDicom() -{ +{ std::vector files; - std::cout << "dicomSeriesSelector " << std::endl; + //std::cout << "dicomSeriesSelector " << std::endl; if (dicomSeriesSelector->exec() == QDialog::Accepted) { files = *(dicomSeriesSelector->GetFilenames()); LoadImages(files, vvImageReader::DICOM); @@ -772,7 +763,7 @@ void vvMainWindow::OpenDicom() //------------------------------------------------------------------------------ void vvMainWindow::OpenImages() -{ +{ QString Extensions = EXTENSIONS; Extensions += ";;All Files (*)"; @@ -787,7 +778,7 @@ void vvMainWindow::OpenImages() } //------------------------------------------------------------------------------ void vvMainWindow::OpenRecentImage() -{ +{ QAction * caller = qobject_cast(sender()); std::vector images; images.push_back(caller->text().toStdString()); @@ -799,7 +790,7 @@ void vvMainWindow::OpenRecentImage() //------------------------------------------------------------------------------ void vvMainWindow::OpenImageWithTime() -{ +{ QString Extensions = EXTENSIONS; Extensions += ";;All Files (*)"; @@ -818,7 +809,7 @@ void vvMainWindow::OpenImageWithTime() //------------------------------------------------------------------------------ void vvMainWindow::LoadImages(std::vector files, vvImageReader::LoadedImageType filetype) -{ +{ //Separate the way to open images and dicoms int fileSize; if (filetype == vvImageReader::IMAGE || filetype == vvImageReader::IMAGEWITHTIME) @@ -867,7 +858,6 @@ void vvMainWindow::LoadImages(std::vector files, vvImageReader::Loa int numberofsuccesulreads=0; //open images as 1 or multiples for (int i = 0; i < fileSize; i++) { - progress.SetText("Opening " + files[i]); progress.SetProgress(i,fileSize); qApp->processEvents(); @@ -882,9 +872,9 @@ void vvMainWindow::LoadImages(std::vector files, vvImageReader::Loa // Change filename if an image with the same already exist int number = GetImageDuplicateFilenameNumber(files[i] + std::string("_slice")); - if (filetype == vvImageReader::IMAGE || filetype == vvImageReader::IMAGEWITHTIME || filetype == vvImageReader::SLICED) + if (filetype == vvImageReader::IMAGE || filetype == vvImageReader::IMAGEWITHTIME || filetype == vvImageReader::SLICED) { SetImageSucceed = imageManager->SetImage(files[i],filetype, number, j); - else { + } else { SetImageSucceed = imageManager->SetImages(files,filetype, number); } if (!SetImageSucceed) { @@ -894,6 +884,7 @@ void vvMainWindow::LoadImages(std::vector files, vvImageReader::Loa QMessageBox::information(this,tr("Reading problem"),error); delete imageManager; } else { + mSlicerManagers.push_back(imageManager); //create an item in the tree with good settings @@ -913,7 +904,7 @@ void vvMainWindow::LoadImages(std::vector files, vvImageReader::Loa cButton->setToolTip(tr("close image")); cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png"))); connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)), - this,SLOT(CloseImage(QTreeWidgetItem*, int))); + this,SLOT(CloseImage(QTreeWidgetItem*, int))); QTreePushButton* rButton = new QTreePushButton; rButton->setItem(item); @@ -921,7 +912,7 @@ void vvMainWindow::LoadImages(std::vector files, vvImageReader::Loa rButton->setToolTip(tr("reload image")); rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png"))); connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)), - this,SLOT(ReloadImage(QTreeWidgetItem*, int))); + this,SLOT(ReloadImage(QTreeWidgetItem*, int))); DataTree->addTopLevelItem(item); DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton); @@ -935,39 +926,40 @@ void vvMainWindow::LoadImages(std::vector files, vvImageReader::Loa linkPanel->addImage(imageManager->GetFileName(), id.toStdString()); connect(mSlicerManagers.back(), SIGNAL(currentImageChanged(std::string)), - this,SLOT(CurrentImageChanged(std::string))); + this,SLOT(CurrentImageChanged(std::string))); connect(mSlicerManagers.back(), SIGNAL(currentPickedImageChanged(std::string)), - this, SLOT(CurrentPickedImageChanged(std::string))); + this, SLOT(CurrentPickedImageChanged(std::string))); connect(mSlicerManagers.back(), SIGNAL(UpdatePosition(int, double, double, double, double, double, double, double)), - this,SLOT(MousePositionChanged(int,double, double, double, double, double, double, double))); + this,SLOT(MousePositionChanged(int,double, double, double, double, double, double, double))); connect(mSlicerManagers.back(), SIGNAL(UpdateVector(int, double, double, double, double)), - this, SLOT(VectorChanged(int,double,double,double, double))); + this, SLOT(VectorChanged(int,double,double,double, double))); connect(mSlicerManagers.back(), SIGNAL(UpdateOverlay(int, double, double)), - this, SLOT(OverlayChanged(int,double,double))); + this, SLOT(OverlayChanged(int,double,double))); connect(mSlicerManagers.back(), SIGNAL(UpdateFusion(int, double)), - this, SLOT(FusionChanged(int,double))); + this, SLOT(FusionChanged(int,double))); connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged()), - this,SLOT(WindowLevelChanged())); + this,SLOT(WindowLevelChanged())); connect(mSlicerManagers.back(), SIGNAL(UpdateSlice(int,int)), - this,SLOT(UpdateSlice(int,int))); - connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)), - this,SLOT(UpdateTSlice(int, int))); - connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)), - this,SLOT(ImageInfoChanged())); + this,SLOT(UpdateSlice(int,int))); + connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int, int)), + this,SLOT(UpdateTSlice(int, int, int))); + connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int, int)), + this,SLOT(ImageInfoChanged())); connect(mSlicerManagers.back(), SIGNAL(UpdateSliceRange(int,int,int,int,int)), - this,SLOT(UpdateSliceRange(int,int,int,int,int))); + this,SLOT(UpdateSliceRange(int,int,int,int,int))); connect(mSlicerManagers.back(), SIGNAL(UpdateLinkManager(std::string,int,double,double,double,int)), - this,SLOT(UpdateLinkManager(std::string,int,double,double,double,int))); + this,SLOT(UpdateLinkManager(std::string,int,double,double,double,int))); connect(mSlicerManagers.back(), SIGNAL(UpdateLinkedNavigation(std::string,vvSlicerManager*,vvSlicer*)), - this,SLOT(UpdateLinkedNavigation(std::string,vvSlicerManager*,vvSlicer*))); + this,SLOT(UpdateLinkedNavigation(std::string,vvSlicerManager*,vvSlicer*))); connect(mSlicerManagers.back(), SIGNAL(ChangeImageWithIndexOffset(vvSlicerManager*,int,int)), - this,SLOT(ChangeImageWithIndexOffset(vvSlicerManager*,int,int))); + this,SLOT(ChangeImageWithIndexOffset(vvSlicerManager*,int,int))); connect(mSlicerManagers.back(),SIGNAL(LandmarkAdded()),landmarksPanel,SLOT(AddPoint())); InitSlicers(); numberofsuccesulreads++; } } } + if (numberofsuccesulreads) { NOViewWidget->show(); NEViewWidget->show(); @@ -981,7 +973,7 @@ void vvMainWindow::LoadImages(std::vector files, vvImageReader::Loa double range[2]; mSlicerManagers.back()->GetImage()->GetFirstVTKImageData()->GetScalarRange(range); if ((range[0] == 0) && (range[1] == 1)) { - presetComboBox->setCurrentIndex(5);// binary + presetComboBox->setCurrentIndex(WL_BINARY);// binary } else { // TODO } @@ -992,7 +984,7 @@ void vvMainWindow::LoadImages(std::vector files, vvImageReader::Loa //------------------------------------------------------------------------------ void vvMainWindow::UpdateTree() -{ +{ DataTree->resizeColumnToContents(COLUMN_TREE); DataTree->resizeColumnToContents(COLUMN_UL_VIEW); DataTree->resizeColumnToContents(COLUMN_UR_VIEW); @@ -1006,7 +998,7 @@ void vvMainWindow::UpdateTree() //------------------------------------------------------------------------------ void vvMainWindow::CurrentImageChanged(std::string id) -{ +{ if (id == mCurrentSelectedImageId) return; // Do nothing int selected = 0; for (int i = 0; i < DataTree->topLevelItemCount(); i++) { @@ -1021,13 +1013,19 @@ void vvMainWindow::CurrentImageChanged(std::string id) } DataTree->topLevelItem(selected)->setSelected(1); mCurrentSelectedImageId = id; + + landmarksPanel->SetCurrentLandmarks(mSlicerManagers[selected]->GetLandmarks(), + mSlicerManagers[selected]->GetTSlice()); + landmarksPanel->SetCurrentPath(mInputPathName.toStdString()); + landmarksPanel->SetCurrentImage(mSlicerManagers[selected]->GetFileName().c_str()); + emit SelectedImageHasChanged(mSlicerManagers[selected]); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void vvMainWindow::CurrentPickedImageChanged(std::string id) -{ +{ if (id == mCurrentPickedImageId) return; // Do nothing int selected = 0; for (int i = 0; i < DataTree->topLevelItemCount(); i++) { @@ -1048,13 +1046,14 @@ void vvMainWindow::CurrentPickedImageChanged(std::string id) //------------------------------------------------------------------------------ void vvMainWindow::ImageInfoChanged() -{ +{ contextActions[6]->setEnabled(1); contextActions[5]->setEnabled(1); actionSave_As->setEnabled(1); actionAdd_VF_to_current_Image->setEnabled(1); actionAdd_fusion_image->setEnabled(1); actionAdd_overlay_image_to_current_image->setEnabled(1); + actionAdd_USSequence_toCT->setEnabled(1); actionNorth_East_Window->setEnabled(1); actionNorth_West_Window->setEnabled(1); actionSouth_East_Window->setEnabled(1); @@ -1070,9 +1069,10 @@ void vvMainWindow::ImageInfoChanged() colorMapComboBox->setEnabled(1); for (int i = 0; i < DataTree->topLevelItem(index)->childCount(); i++) { if (DataTree->topLevelItem(index)->child(i)->data(1,Qt::UserRole).toString() == "overlay" || - DataTree->topLevelItem(index)->child(i)->data(1,Qt::UserRole).toString() == "fusion") { - colorMapComboBox->setEnabled(0); - break; + DataTree->topLevelItem(index)->child(i)->data(1,Qt::UserRole).toString() == "fusion" || + DataTree->topLevelItem(index)->child(i)->data(1,Qt::UserRole).toString() == "fusionSequence") { + colorMapComboBox->setEnabled(0); + break; } } @@ -1087,6 +1087,7 @@ void vvMainWindow::ImageInfoChanged() QString image = DataTree->selectedItems()[0]->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString(); int nframes = mSlicerManagers[index]->GetSlicer(0)->GetTMax(); + if (nframes > 1 || playMode == 1) { playButton->setEnabled(1); frameRateLabel->setEnabled(1); @@ -1115,6 +1116,10 @@ void vvMainWindow::ImageInfoChanged() imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetFusion(); tSlice = mSlicerManagers[index]->GetSlicer(0)->GetFusionTSlice(); } + else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "fusionSequence") { + imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetFusion(); + tSlice = mSlicerManagers[index]->GetSlicer(0)->GetFusionTSlice(); + } else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "contour") { imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage(); tSlice = mSlicerManagers[index]->GetSlicer(0)->GetTSlice(); @@ -1138,22 +1143,26 @@ void vvMainWindow::ImageInfoChanged() NPixel *= inputSize[i]; } inputSizeInBytes = GetSizeInBytes(imageSelected->GetActualMemorySize()*1000); - + QString dim = QString::number(dimension) + " ("; dim += pixelType + ")"; infoPanel->setFileName(image); + std::string creationImageTimeValue("No creation time"); + itk::ExposeMetaData< std::string > (*imageSelected->GetFirstMetaDataDictionary(), "creationImageTime", creationImageTimeValue); + infoPanel->setImageCreationTime(QString(creationImageTimeValue.c_str())); infoPanel->setDimension(dim); infoPanel->setSizePixel(GetVectorIntAsString(inputSize)); infoPanel->setSizeMM(GetVectorDoubleAsString(sizeMM)); infoPanel->setOrigin(GetVectorDoubleAsString(origin)); infoPanel->setSpacing(GetVectorDoubleAsString(inputSpacing)); infoPanel->setNPixel(QString::number(NPixel)+" ("+inputSizeInBytes+")"); + transformation = imageSelected->GetTransform()[tSlice]->GetMatrix(); - infoPanel->setTransformation(Get4x4MatrixDoubleAsString(transformation)); + infoPanel->setTransformation(clitk::Get4x4MatrixDoubleAsString(transformation).c_str()); landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(), - mSlicerManagers[index]->GetSlicer(0)->GetImage()->GetVTKImages().size()); + mSlicerManagers[index]->GetTSlice()); landmarksPanel->SetCurrentPath(mInputPathName.toStdString()); landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str()); @@ -1165,34 +1174,35 @@ void vvMainWindow::ImageInfoChanged() } } - infoPanel->setFileName(image); - infoPanel->setDimension(dim); - infoPanel->setSizePixel(GetVectorIntAsString(inputSize)); - infoPanel->setSizeMM(GetVectorDoubleAsString(sizeMM)); - infoPanel->setOrigin(GetVectorDoubleAsString(origin)); - infoPanel->setSpacing(GetVectorDoubleAsString(inputSpacing)); - infoPanel->setNPixel(QString::number(NPixel)+" ("+inputSizeInBytes+")"); - - landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(), - mSlicerManagers[index]->GetSlicer(0)->GetImage()->GetVTKImages().size()); - landmarksPanel->SetCurrentPath(mInputPathName.toStdString()); - landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str()); - - overlayPanel->getCurrentImageName(mSlicerManagers[index]->GetFileName().c_str()); - for (int i = 0; i < 4; i++) { - if (DataTree->selectedItems()[0]->data(i+1,Qt::CheckStateRole).toInt() > 0 || i == 3) { - mSlicerManagers[index]->UpdateInfoOnCursorPosition(i); - break; - } - } +// infoPanel->setFileName(image); +// infoPanel->setDimension(dim); +// infoPanel->setSizePixel(GetVectorIntAsString(inputSize)); +// infoPanel->setSizeMM(GetVectorDoubleAsString(sizeMM)); +// infoPanel->setOrigin(GetVectorDoubleAsString(origin)); +// infoPanel->setSpacing(GetVectorDoubleAsString(inputSpacing)); +// infoPanel->setNPixel(QString::number(NPixel)+" ("+inputSizeInBytes+")"); +// +// landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(), +// mSlicerManagers[index]->GetTSlice()); +// landmarksPanel->SetCurrentPath(mInputPathName.toStdString()); +// landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str()); +// +// overlayPanel->getCurrentImageName(mSlicerManagers[index]->GetFileName().c_str()); +// for (int i = 0; i < 4; i++) { +// if (DataTree->selectedItems()[0]->data(i+1,Qt::CheckStateRole).toInt() > 0 || i == 3) { +// mSlicerManagers[index]->UpdateInfoOnCursorPosition(i); +// break; +// } +// } WindowLevelChanged(); + slicingPresetComboBox->setCurrentIndex(mSlicerManagers[index]->GetSlicingPreset()); if (mSlicerManagers[index]->GetSlicer(0)->GetVF()) { overlayPanel->getVFName(mSlicerManagers[index]->GetVFName().c_str()); overlayPanel->getVFProperty(mSlicerManagers[index]->GetSlicer(0)->GetVFSubSampling(), - mSlicerManagers[index]->GetSlicer(0)->GetVFScale(), - mSlicerManagers[index]->GetSlicer(0)->GetVFLog()); + mSlicerManagers[index]->GetSlicer(0)->GetVFScale(), + mSlicerManagers[index]->GetSlicer(0)->GetVFLog()); } else { overlayPanel->getVFName(mSlicerManagers[index]->GetVFName().c_str()); overlayPanel->getVFProperty(-1,-1,-1); @@ -1202,7 +1212,7 @@ void vvMainWindow::ImageInfoChanged() } else { overlayPanel->getOverlayName(mSlicerManagers[index]->GetOverlayName().c_str()); } - + if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) { overlayPanel->getFusionName(mSlicerManagers[index]->GetFusionName().c_str()); } else { @@ -1214,14 +1224,14 @@ void vvMainWindow::ImageInfoChanged() //------------------------------------------------------------------------------ void vvMainWindow::ShowDocumentation() -{ +{ documentation->show(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void vvMainWindow::PopupRegisterForm(bool checkCanPush) -{ +{ vvRegisterForm* registerForm = new vvRegisterForm(QUrl("http://www.creatis.insa-lyon.fr/~dsarrut/vvregister/write.php"), getVVSettingsPath(), getSettingsOptionFormat()); if(!checkCanPush) { registerForm->show(); @@ -1236,14 +1246,14 @@ void vvMainWindow::PopupRegisterForm(bool checkCanPush) //------------------------------------------------------------------------------ void vvMainWindow::ShowHelpDialog() -{ +{ help_dialog->show(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void vvMainWindow::ChangeViewMode() -{ +{ typedef struct _SIZE{ QSplitter* splitter; QList size1, size2; @@ -1285,7 +1295,7 @@ void vvMainWindow::ChangeViewMode() sizes[3].cols[0] = 1; sizes[3].cols[1] = 2; sizes[3].cols[2] = 3; - + int slicer = mSlicerManagers[mCurrentPickedImageIndex]->GetSelectedSlicer(); if (viewMode == 1) { if (slicer >= 0) { @@ -1315,19 +1325,19 @@ void vvMainWindow::ChangeViewMode() ** the associated Slicer to redraw crosses. */ for (unsigned int i = 0; i < mSlicerManagers.size(); i++) { -// if (DataTree->topLevelItem(i)->data(COLUMN_UL_VIEW,Qt::CheckStateRole).toInt() > 1) - mSlicerManagers[i]->GetSlicer(0)->Render(); - mSlicerManagers[i]->GetSlicer(1)->Render(); -// if (DataTree->topLevelItem(i)->data(COLUMN_DL_VIEW,Qt::CheckStateRole).toInt() > 1) - mSlicerManagers[i]->GetSlicer(2)->Render(); - mSlicerManagers[i]->GetSlicer(3)->Render(); + // if (DataTree->topLevelItem(i)->data(COLUMN_UL_VIEW,Qt::CheckStateRole).toInt() > 1) + mSlicerManagers[i]->GetSlicer(0)->Render(); + mSlicerManagers[i]->GetSlicer(1)->Render(); + // if (DataTree->topLevelItem(i)->data(COLUMN_DL_VIEW,Qt::CheckStateRole).toInt() > 1) + mSlicerManagers[i]->GetSlicer(2)->Render(); + mSlicerManagers[i]->GetSlicer(3)->Render(); } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ QString vvMainWindow::GetSizeInBytes(unsigned long size) -{ +{ QString result = "";// QString::number(size); //result += " bytes ("; if (size > 1000000000) { @@ -1347,41 +1357,9 @@ QString vvMainWindow::GetSizeInBytes(unsigned long size) } //------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -QString vvMainWindow::Get4x4MatrixDoubleAsString(vtkSmartPointer matrix, const int precision) -{ - std::ostringstream strmatrix; - - // Figure out the number of digits of the integer part of the largest absolute value - // for each column - unsigned width[4]; - for (unsigned int j = 0; j < 4; j++){ - double absmax = 0.; - for (unsigned int i = 0; i < 4; i++) - absmax = std::max(absmax, vnl_math_abs(matrix->GetElement(i, j))); - unsigned ndigits = (unsigned)std::max(0.,std::log10(absmax))+1; - width[j] = precision+ndigits+3; - } - - // Output with correct width, aligned to the right - for (unsigned int i = 0; i < 4; i++) { - for (unsigned int j = 0; j < 4; j++) { - strmatrix.setf(ios::fixed,ios::floatfield); - strmatrix.precision(precision); - strmatrix.fill(' '); - strmatrix.width(width[j]); - strmatrix << std::right << matrix->GetElement(i, j); - } - strmatrix << std::endl; - } - QString result = strmatrix.str().c_str(); - return result; -} -//------------------------------------------------------------------------------ - //------------------------------------------------------------------------------ QString vvMainWindow::GetVectorDoubleAsString(std::vector vectorDouble) -{ +{ QString result; for (unsigned int i= 0; i < vectorDouble.size(); i++) { if (i != 0) @@ -1394,7 +1372,7 @@ QString vvMainWindow::GetVectorDoubleAsString(std::vector vectorDouble) //------------------------------------------------------------------------------ QString vvMainWindow::GetVectorIntAsString(std::vector vectorInt) -{ +{ QString result; for (unsigned int i= 0; i < vectorInt.size(); i++) { if (i != 0) @@ -1406,8 +1384,9 @@ QString vvMainWindow::GetVectorIntAsString(std::vector vectorInt) //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ +//this actually returns the SlicerManager index! int vvMainWindow::GetSlicerIndexFromItem(QTreeWidgetItem* item) -{ +{ QString id = item->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString(); for (int i = 0; i < DataTree->topLevelItemCount(); i++) { if (DataTree->topLevelItem(i)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString() == id) @@ -1419,7 +1398,7 @@ int vvMainWindow::GetSlicerIndexFromItem(QTreeWidgetItem* item) //------------------------------------------------------------------------------ QTreeWidgetItem* vvMainWindow::GetItemFromSlicerManager(vvSlicerManager* sm) -{ +{ QString id = sm->GetId().c_str(); for (int i = 0; i < DataTree->topLevelItemCount(); i++) { if (DataTree->topLevelItem(i)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString() == id) @@ -1431,7 +1410,7 @@ QTreeWidgetItem* vvMainWindow::GetItemFromSlicerManager(vvSlicerManager* sm) //------------------------------------------------------------------------------ void vvMainWindow::DisplayChanged(QTreeWidgetItem *clickedItem, int column) -{ +{ if ( column >= COLUMN_CLOSE_IMAGE || column <= 0) return; @@ -1478,7 +1457,7 @@ void vvMainWindow::DisplayChanged(QTreeWidgetItem *clickedItem, int column) clickedParentItem->setData(column, Qt::CheckStateRole, vis?2:0); // Children - std::map actorTypeCounts; + std::map actorTypeCounts; for (int iChild = 0; iChild < clickedParentItem->childCount(); iChild++) { QTreeWidgetItem* currentChildItem = clickedParentItem->child(iChild); std::string actorType = currentChildItem->data(1,Qt::UserRole).toString().toStdString(); @@ -1499,20 +1478,22 @@ void vvMainWindow::DisplayChanged(QTreeWidgetItem *clickedItem, int column) //------------------------------------------------------------------------------ void vvMainWindow::InitSlicers() -{ +{ if (mSlicerManagers.size()) { mSlicerManagers.back()->GenerateDefaultLookupTable(); - mSlicerManagers.back()->SetSlicerWindow(0,NOViewWidget->GetRenderWindow()); mSlicerManagers.back()->SetSlicerWindow(1,NEViewWidget->GetRenderWindow()); mSlicerManagers.back()->SetSlicerWindow(2,SOViewWidget->GetRenderWindow()); mSlicerManagers.back()->SetSlicerWindow(3,SEViewWidget->GetRenderWindow()); +#if VTK_MAJOR_VERSION <= 5 + mSlicerManagers.back()->Render(); // SR: displayed #slice is wrong without this / TB: With VTK6 and multiple images, all slicers are updated, not only the first +#endif } } //------------------------------------------------------------------------------ void vvMainWindow::InitDisplay() -{ +{ if (mSlicerManagers.size()) { //BE CAREFUL : this is absolutely necessary to set the interactor style //in order to have the same style instanciation for all SlicerManagers in @@ -1523,14 +1504,14 @@ void vvMainWindow::InitDisplay() bool AlreadySelected = false; for (int i = 0; i < DataTree->topLevelItemCount(); i++) { mSlicerManagers[i]->SetInteractorStyleNavigator(j,style); - //select the image only if previous are not selected if (DataTree->topLevelItem(i)->data(j+1,Qt::CheckStateRole).toInt() > 1) { mSlicerManagers[i]->UpdateSlicer(j,1); AlreadySelected = true; } else if (i == DataTree->topLevelItemCount()-1 && !AlreadySelected) { - if (DataTree->selectedItems().size() == 0) + if (DataTree->selectedItems().size() == 0) { DataTree->topLevelItem(i)->setSelected(1); + } DataTree->topLevelItem(i)->setData(j+1,Qt::CheckStateRole,2); mSlicerManagers[i]->UpdateSlicer(j,1); DisplaySliders(i,j); @@ -1547,7 +1528,7 @@ void vvMainWindow::InitDisplay() //------------------------------------------------------------------------------ void vvMainWindow::DisplaySliders(int slicer, int window) -{ +{ if(!mSlicerManagers[slicer]->GetSlicer(window)->GetRenderer()->GetDraw()) return; @@ -1576,14 +1557,14 @@ void vvMainWindow::DisplaySliders(int slicer, int window) //------------------------------------------------------------------------------ void vvMainWindow::CloseImage(QTreeWidgetItem* item, int column) -{ +{ int index = GetSlicerIndexFromItem(item); if (DataTree->topLevelItem(index) != item) { QString warning = "Do you really want to close the overlay : "; warning += item->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString(); QMessageBox msgBox(QMessageBox::Warning, tr("Close Overlay"), - warning, 0, this); + warning, 0, this); msgBox.addButton(tr("Close"), QMessageBox::AcceptRole); msgBox.addButton(tr("Cancel"), QMessageBox::RejectRole); if (msgBox.exec() == QMessageBox::AcceptRole) { @@ -1591,10 +1572,25 @@ void vvMainWindow::CloseImage(QTreeWidgetItem* item, int column) int overlay_index=0; for (int child = 0; child < DataTree->topLevelItem(index)->childCount(); child++) { if (DataTree->topLevelItem(index)->\ - child(child)->data(1,Qt::UserRole).toString().toStdString() == overlay_type) + child(child)->data(1,Qt::UserRole).toString().toStdString() == overlay_type) overlay_index++; if (DataTree->topLevelItem(index)->child(child) == item) break; } + if (overlay_type=="fusionSequence") { + //removing the overlay sequence in a fusion sequence visualization mode + //reset the transforms + overlayPanel->getFusionSequenceProperty(-1, false, 0, false); + + //unlink and untie the slicer managers + RemoveLink(mSlicerManagers[index]->GetId().c_str(), mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()]->GetId().c_str()); + mSlicerManagers[index]->SetFusionSequenceInvolvmentCode(-1); + mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()]->SetFusionSequenceInvolvmentCode(-1); + for (unsigned i=0 ; i<4 ; i++) { + mSlicerManagers[index]->GetSlicer(i)->SetFusionSequenceCode(-1); + mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()]->GetSlicer(i)->SetFusionSequenceCode(-1); + } + + } mSlicerManagers[index]->RemoveActor(overlay_type, overlay_index-1); mSlicerManagers[index]->SetColorMap(0); DataTree->topLevelItem(index)->takeChild(DataTree->topLevelItem(index)->indexOfChild(item)); @@ -1605,7 +1601,7 @@ void vvMainWindow::CloseImage(QTreeWidgetItem* item, int column) warning += item->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString(); warning += "\nThis is the last image, you're about to close vv !!!"; QMessageBox msgBox(QMessageBox::Warning, tr("Close Image"), - warning, 0, this); + warning, 0, this); msgBox.addButton(tr("Close vv"), QMessageBox::AcceptRole); msgBox.addButton(tr("Cancel"), QMessageBox::RejectRole); if (msgBox.exec() == QMessageBox::AcceptRole) { @@ -1615,7 +1611,7 @@ void vvMainWindow::CloseImage(QTreeWidgetItem* item, int column) QString warning = "Do you really want to close the image : "; warning += item->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString(); QMessageBox msgBox(QMessageBox::Warning, tr("Close Image"), - warning, 0, this); + warning, 0, this); msgBox.addButton(tr("Close"), QMessageBox::AcceptRole); msgBox.addButton(tr("Cancel"), QMessageBox::RejectRole); if (msgBox.exec() == QMessageBox::AcceptRole) { @@ -1628,8 +1624,44 @@ void vvMainWindow::CloseImage(QTreeWidgetItem* item, int column) for (int i = 0; i < index; i++) { Manageriter++; } + //if the slicer manager was involved in a fusion sequence visualization... + if ( mSlicerManagers[index]->IsInvolvedInFusionSequence() ) { + //in both cases, close the overlay: find it... and close it + //ideally, I should duplicate the code, and avoid calling CloseImage, since this pops up another interactive box + QTreeWidgetItem* overlayItem; + if (mSlicerManagers[index]->IsMainSequenceOfFusionSequence()) { + for (unsigned i=0 ; ichildCount() ; i++) { + overlayItem = item->child(i); + this->CloseImage( overlayItem, 0 ); + } + } + else { + QTreeWidgetItem* linkedItem = this->GetItemFromSlicerManager( mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()] ); + for (unsigned i=0 ; ichildCount() ; i++) { + overlayItem = linkedItem->child(i); + this->CloseImage( overlayItem, 0 ); + } + } + + /* -- this is normally already done when closing the overlay. + //reset the transforms + overlayPanel->getFusionSequenceProperty(-1, false, 0, false); + + //unlink and untie the slicer managers + RemoveLink(mSlicerManagers[index]->GetId().c_str(), mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()]->GetId().c_str()); + mSlicerManagers[index]->SetFusionSequenceInvolvmentCode(-1); + mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()]->SetFusionSequenceInvolvmentCode(-1); + for (unsigned i=0 ; i<4 ; i++) { + mSlicerManagers[index]->GetSlicer(i)->SetFusionSequenceCode(-1); + mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()]->GetSlicer(i)->SetFusionSequenceCode(-1); + } + */ + } + linkPanel->removeImage(index); mSlicerManagers[index]->RemoveActors(); + + //remove the slicer manager delete mSlicerManagers[index]; mSlicerManagers.erase(Manageriter); @@ -1643,7 +1675,7 @@ void vvMainWindow::CloseImage(QTreeWidgetItem* item, int column) //------------------------------------------------------------------------------ void vvMainWindow::ReloadImage(QTreeWidgetItem* item, int column) -{ +{ // int index = GetSlicerIndexFromItem(item); // QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); // if (item->data(1,Qt::UserRole).toString() == "vector") @@ -1655,17 +1687,24 @@ void vvMainWindow::ReloadImage(QTreeWidgetItem* item, int column) int index = GetSlicerIndexFromItem(item); QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); QString role=item->data(1,Qt::UserRole).toString(); - if ( role == "vector"){ + if ( role == "vector") { mSlicerManagers[index]->ReloadVF(); } - else if (role == "overlay"){ + else if (role == "overlay") { mSlicerManagers[index]->ReloadOverlay(); } - else if (role == "fusion"){ + else if (role == "fusion") { mSlicerManagers[index]->ReloadFusion(); } - else{ + else if (role == "fusionSequence") { + //both versions of the secondary sequence must be updated. + mSlicerManagers[index]->ReloadFusionSequence(); + mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()]->Reload(); + } + else { mSlicerManagers[index]->Reload(); + //if we update the secondary sequence, then the overlay of the main sequence should also be updated + if (mSlicerManagers[index]->IsSecondarySequenceOfFusionSequence()) mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()]->ReloadFusionSequence(); } // Update view and info ImageInfoChanged(); @@ -1676,35 +1715,38 @@ void vvMainWindow::ReloadImage(QTreeWidgetItem* item, int column) //------------------------------------------------------------------------------ void vvMainWindow::MousePositionChanged(int visibility,double x, double y, double z, double X, double Y, double Z , double value) -{ +{ infoPanel->setCurrentInfo(visibility,x,y,z,X,Y,Z,value); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void vvMainWindow::VectorChanged(int visibility,double x, double y, double z, double value) -{ +{ overlayPanel->getCurrentVectorInfo(visibility,x,y,z,value); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void vvMainWindow::OverlayChanged(int visibility, double valueOver, double valueRef) -{ +{ overlayPanel->getCurrentOverlayInfo(visibility,valueOver, valueRef); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void vvMainWindow::FusionChanged(int visibility, double value) -{ +{ overlayPanel->getCurrentFusionInfo(visibility,value); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ +//called when AddOverlayImage, AddFusionSequence +//or when UpdateWindowLevel() is called ; when slicerManager emits WindowLevelChanged +//when ImageInfoChanged() is called void vvMainWindow::WindowLevelChanged() -{ +{ // Base image int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); if(index==-1) return; @@ -1716,38 +1758,61 @@ void vvMainWindow::WindowLevelChanged() // Overlay image if (mSlicerManagers[index]->GetSlicer(0)->GetOverlay()) overlayPanel->getOverlayProperty(mSlicerManagers[index]->GetOverlayColor(), - mSlicerManagers[index]->GetLinkOverlayWindowLevel(), - mSlicerManagers[index]->GetOverlayColorWindow(), - mSlicerManagers[index]->GetOverlayColorLevel()); + mSlicerManagers[index]->GetLinkOverlayWindowLevel(), + mSlicerManagers[index]->GetOverlayColorWindow(), + mSlicerManagers[index]->GetOverlayColorLevel()); else overlayPanel->getOverlayProperty(-1,0,0.,0.); - // Fusion image - if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) + // Fusion & SequenceFusion image + if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) { overlayPanel->getFusionProperty(mSlicerManagers[index]->GetFusionOpacity(), - mSlicerManagers[index]->GetFusionThresholdOpacity(), - mSlicerManagers[index]->GetFusionColorMap(), - mSlicerManagers[index]->GetFusionWindow(), - mSlicerManagers[index]->GetFusionLevel()); + mSlicerManagers[index]->GetFusionThresholdOpacity(), + mSlicerManagers[index]->GetFusionColorMap(), + mSlicerManagers[index]->GetFusionWindow(), + mSlicerManagers[index]->GetFusionLevel()); + if (mSlicerManagers[index]->IsMainSequenceOfFusionSequence()) { + overlayPanel->getFusionSequenceProperty(mSlicerManagers[index]->GetFusionSequenceFrameIndex(), + mSlicerManagers[index]->GetFusionSequenceSpatialSyncFlag(), + mSlicerManagers[index]->GetFusionSequenceNbFrames(), + mSlicerManagers[index]->GetFusionSequenceTemporalSyncFlag()); + } + } + else if ( mSlicerManagers[index]->IsSecondarySequenceOfFusionSequence() ) { + //if the image is involved in a fusion sequence, preserve the overlay panel! + int ind = mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager(); + overlayPanel->getFusionProperty(mSlicerManagers[ind]->GetFusionOpacity(), + mSlicerManagers[ind]->GetFusionThresholdOpacity(), + mSlicerManagers[ind]->GetFusionColorMap(), + mSlicerManagers[ind]->GetFusionWindow(), + mSlicerManagers[ind]->GetFusionLevel()); + overlayPanel->getFusionSequenceProperty(mSlicerManagers[ind]->GetFusionSequenceFrameIndex(), + mSlicerManagers[ind]->GetFusionSequenceSpatialSyncFlag(), + mSlicerManagers[ind]->GetFusionSequenceNbFrames(), + mSlicerManagers[ind]->GetFusionSequenceTemporalSyncFlag()); + } else + { overlayPanel->getFusionProperty(-1, -1, -1, -1, -1); + overlayPanel->getFusionSequenceProperty(-1, false, 0, false); + } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void vvMainWindow::WindowLevelEdited() -{ - presetComboBox->setCurrentIndex(6); +{ + presetComboBox->setCurrentIndex(WL_USER); UpdateWindowLevel(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void vvMainWindow::SetWindowLevel(double w, double l) -{ +{ windowSpinBox->setValue(w); levelSpinBox->setValue(l); - presetComboBox->setCurrentIndex(6); + presetComboBox->setCurrentIndex(WL_USER); colorMapComboBox->setCurrentIndex(0); UpdateWindowLevel(); } @@ -1755,9 +1820,9 @@ void vvMainWindow::SetWindowLevel(double w, double l) //------------------------------------------------------------------------------ void vvMainWindow::UpdateWindowLevel() -{ +{ if (DataTree->selectedItems().size()) { - if (presetComboBox->currentIndex() == 7) //For ventilation + if (presetComboBox->currentIndex() == WL_VENTILATION) //For ventilation colorMapComboBox->setCurrentIndex(5); int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); mSlicerManagers[index]->SetColorWindow(windowSpinBox->value()); @@ -1771,7 +1836,7 @@ void vvMainWindow::UpdateWindowLevel() //------------------------------------------------------------------------------ void vvMainWindow::UpdateSlicingPreset() -{ +{ if (DataTree->selectedItems().size()) { int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); mSlicerManagers[index]->SetSlicingPreset(vvSlicerManager::SlicingPresetType(slicingPresetComboBox->currentIndex())); @@ -1781,7 +1846,7 @@ void vvMainWindow::UpdateSlicingPreset() //------------------------------------------------------------------------------ void vvMainWindow::UpdateColorMap() -{ +{ if (DataTree->selectedItems().size()) { int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); mSlicerManagers[index]->SetColorMap(colorMapComboBox->currentIndex()); @@ -1790,10 +1855,10 @@ void vvMainWindow::UpdateColorMap() } //------------------------------------------------------------------------------ void vvMainWindow::SwitchWindowLevel() -{ +{ int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); int window = mSlicerManagers[index]->GetColorWindow(); - presetComboBox->setCurrentIndex(6); + presetComboBox->setCurrentIndex(WL_USER); windowSpinBox->setValue(-window); UpdateWindowLevel(); } @@ -1801,18 +1866,28 @@ void vvMainWindow::SwitchWindowLevel() //------------------------------------------------------------------------------ void vvMainWindow::ApplyWindowLevelToAllImages() -{ +{ int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); if(index==-1) return; double window = mSlicerManagers[index]->GetColorWindow(); double level = mSlicerManagers[index]->GetColorLevel(); + double fusWindow = mSlicerManagers[index]->GetFusionWindow(); + double fusLevel = mSlicerManagers[index]->GetFusionLevel(); + + double overWindow = mSlicerManagers[index]->GetOverlayColorWindow(); + double overLevel = mSlicerManagers[index]->GetOverlayColorLevel(); + for (unsigned int i = 0; i < mSlicerManagers.size(); i++) { if (mSlicerManagers[i] == NULL) continue; mSlicerManagers[i]->SetColorWindow(window); mSlicerManagers[i]->SetColorLevel(level); - mSlicerManagers[i]->SetPreset(6); + mSlicerManagers[i]->SetPreset(WL_USER); + mSlicerManagers[i]->SetFusionWindow(fusWindow); + mSlicerManagers[i]->SetFusionLevel(fusLevel); + mSlicerManagers[i]->SetOverlayColorWindow(overWindow); + mSlicerManagers[i]->SetOverlayColorLevel(overLevel); mSlicerManagers[i]->Render(); } } @@ -1820,12 +1895,13 @@ void vvMainWindow::ApplyWindowLevelToAllImages() //------------------------------------------------------------------------------ void vvMainWindow::ApplyWindowToSetOfImages(double window, unsigned int indexMin, unsigned int indexMax) -{ +{ for (unsigned int i = indexMin; i <= indexMax && i < mSlicerManagers.size(); i++) { if (mSlicerManagers[i] == NULL) continue; + SetWindowLevel(window, mSlicerManagers[i]->GetColorLevel()); mSlicerManagers[i]->SetColorWindow(window); - mSlicerManagers[i]->SetPreset(6); + mSlicerManagers[i]->SetPreset(WL_USER); mSlicerManagers[i]->Render(); } } @@ -1833,12 +1909,13 @@ void vvMainWindow::ApplyWindowToSetOfImages(double window, unsigned int indexMin //------------------------------------------------------------------------------ void vvMainWindow::ApplyLevelToSetOfImages(double level, unsigned int indexMin, unsigned int indexMax) -{ +{ for (unsigned int i = indexMin; i <= indexMax && i < mSlicerManagers.size(); i++) { if (mSlicerManagers[i] == NULL) continue; + SetWindowLevel(mSlicerManagers[i]->GetColorWindow(), level); mSlicerManagers[i]->SetColorLevel(level); - mSlicerManagers[i]->SetPreset(6); + mSlicerManagers[i]->SetPreset(WL_USER); mSlicerManagers[i]->Render(); } } @@ -1846,10 +1923,9 @@ void vvMainWindow::ApplyLevelToSetOfImages(double level, unsigned int indexMin, //------------------------------------------------------------------------------ void vvMainWindow::UpdateLinkManager(std::string id, int slicer, double x, double y, double z, int temps) -{ +{ for (unsigned int i = 0; i < mSlicerManagers.size(); i++) { if (mSlicerManagers[i]->GetId() == id) { - //mSlicerManagers[i]->SetTSlice(temps); mSlicerManagers[i]->GetSlicer(slicer)->SetCurrentPosition(x,y,z,temps); mSlicerManagers[i]->UpdateViews(0,slicer); break; @@ -1860,7 +1936,7 @@ void vvMainWindow::UpdateLinkManager(std::string id, int slicer, double x, doubl //------------------------------------------------------------------------------ void vvMainWindow::UpdateLinkedNavigation(std::string id, vvSlicerManager * sm, vvSlicer* refSlicer) -{ +{ for (unsigned int i = 0; i < mSlicerManagers.size(); i++) { if (id == mSlicerManagers[i]->GetId()) { mSlicerManagers[i]->UpdateLinkedNavigation(refSlicer); @@ -1871,7 +1947,7 @@ void vvMainWindow::UpdateLinkedNavigation(std::string id, vvSlicerManager * sm, //------------------------------------------------------------------------------ void vvMainWindow::ShowContextMenu(QPoint point) -{ +{ if (!DataTree->selectedItems().size()) { contextActions[1]->setEnabled(0); contextActions[2]->setEnabled(0); @@ -1884,7 +1960,7 @@ void vvMainWindow::ShowContextMenu(QPoint point) contextActions[1]->setEnabled(1); contextActions[2]->setEnabled( DataTree->itemWidget(DataTree->selectedItems()[0], - COLUMN_RELOAD_IMAGE)->isEnabled()); + COLUMN_RELOAD_IMAGE)->isEnabled()); contextActions[3]->setEnabled(1); contextActions[5]->setEnabled(1); contextActions[6]->setEnabled(1); @@ -1900,32 +1976,25 @@ void vvMainWindow::ShowContextMenu(QPoint point) //------------------------------------------------------------------------------ void vvMainWindow::CloseImage() -{ +{ CloseImage(DataTree->selectedItems()[0],0); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void vvMainWindow::ReloadImage() -{ +{ ReloadImage(DataTree->selectedItems()[0],0); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void vvMainWindow::SelectOverlayImage() -{ +{ int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); - //check if one overlay image is added - for (int child = 0; child < DataTree->topLevelItem(index)->childCount(); child++) - if (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "overlay") { - QString error = "Cannot add more than one compared image\n"; - error += "Please remove first "; - error += DataTree->topLevelItem(index)->child(child)->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString(); - QMessageBox::information(this,tr("Problem adding compared image !"),error); - return; - } + if (!(CheckAddedImage(index, "overlay"))) + return; QString Extensions = EXTENSIONS; Extensions += ";;All Files (*)"; @@ -1937,19 +2006,36 @@ void vvMainWindow::SelectOverlayImage() for (int i = 0; i < files.size(); i++) { vecFileNames.push_back(files[i].toStdString()); } + AddOverlayImage(index,vecFileNames,vvImageReader::IMAGE); } //------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +bool vvMainWindow::CheckAddedImage(int index, QString imageType) +{ + //check if one overlay image is added + for (int child = 0; child < DataTree->topLevelItem(index)->childCount(); child++) + if (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString().compare(imageType) == 0) { + QString error = "Cannot add more than one compared image\n"; + error += "Please remove first "; + error += DataTree->topLevelItem(index)->child(child)->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString(); + QMessageBox::information(this,tr("Problem adding compared image !"),error); + return false; + } + return true; +} +//------------------------------------------------------------------------------ + //------------------------------------------------------------------------------ void vvMainWindow::AddOverlayImage(int index, std::vector fileNames, vvImageReader::LoadedImageType type) -{ +{ QString file(fileNames[0].c_str()); if (QFile::exists(file)) { mInputPathName = itksys::SystemTools::GetFilenamePath(file.toStdString()).c_str(); itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO( - file.toStdString().c_str(), itk::ImageIOFactory::ReadMode); + file.toStdString().c_str(), itk::ImageIOFactory::ReadMode); reader->SetFileName(fileNames[0].c_str()); reader->ReadImageInformation(); std::string component = reader->GetComponentTypeAsString(reader->GetComponentType()); @@ -1968,6 +2054,10 @@ void vvMainWindow::AddOverlayImage(int index, std::vector fileNames item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName()); item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("overlay").c_str()); qApp->processEvents(); +#if VTK_MAJOR_VERSION > 5 + for ( unsigned int i = 0; i < mSlicerManagers[index]->GetNumberOfSlicers(); i++) + mSlicerManagers[index]->GetSlicer(i)->ForceUpdateDisplayExtent(); +#endif for (int j = 1; j <= 4; j++) { item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole)); @@ -1981,7 +2071,7 @@ void vvMainWindow::AddOverlayImage(int index, std::vector fileNames cButton->setToolTip(tr("close image")); cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png"))); connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)), - this,SLOT(CloseImage(QTreeWidgetItem*, int))); + this,SLOT(CloseImage(QTreeWidgetItem*, int))); QTreePushButton* rButton = new QTreePushButton; rButton->setItem(item); @@ -1989,7 +2079,7 @@ void vvMainWindow::AddOverlayImage(int index, std::vector fileNames rButton->setToolTip(tr("reload image")); rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png"))); connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)), - this,SLOT(ReloadImage(QTreeWidgetItem*, int))); + this,SLOT(ReloadImage(QTreeWidgetItem*, int))); DataTree->topLevelItem(index)->setExpanded(1); DataTree->topLevelItem(index)->addChild(item); @@ -2023,7 +2113,7 @@ void vvMainWindow::AddOverlayImage(int index, std::vector fileNames //------------------------------------------------------------------------------ void vvMainWindow::AddROI(int index, QString file) -{ +{ /* // Get slice manager @@ -2033,12 +2123,12 @@ void vvMainWindow::AddROI(int index, QString file) mReader->SetInputFilename(filename.toStdString()); mReader->Update(IMAGE); if (mReader->GetLastError().size() != 0) { - std::cerr << "Error while reading " << filename.toStdString() << std::endl; - QString error = "Cannot open file \n"; - error += mReader->GetLastError().c_str(); - QMessageBox::information(this,tr("Reading problem"),error); - delete mReader; - return; + std::cerr << "Error while reading " << filename.toStdString() << std::endl; + QString error = "Cannot open file \n"; + error += mReader->GetLastError().c_str(); + QMessageBox::information(this,tr("Reading problem"),error); + delete mReader; + return; } vvImage::Pointer roi = mReader->GetOutput(); @@ -2050,30 +2140,29 @@ void vvMainWindow::AddROI(int index, QString file) //------------------------------------------------------------------------------ void vvMainWindow::SelectFusionImage() -{ +{ int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); - //check if one fusion image is added - for (int child = 0; child < DataTree->topLevelItem(index)->childCount(); child++) - if (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "fusion") { - QString error = "Cannot add more than one fusion image\n"; - error += "Please remove first "; - error += DataTree->topLevelItem(index)->child(child)->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString(); - QMessageBox::information(this,tr("Problem adding fusion image !"),error); - return; - } + if (!(CheckAddedImage(index, "fusion")) || !(CheckAddedImage(index, "fusionSequence"))) + return; QString Extensions = EXTENSIONS; Extensions += ";;All Files (*)"; - QString file = QFileDialog::getOpenFileName(this,tr("Load Fusion image"),mInputPathName,Extensions); - if (!file.isEmpty()) - AddFusionImage(index,file); + QStringList files = QFileDialog::getOpenFileNames(this,tr("Load Fusion image"),mInputPathName,Extensions); + if (files.isEmpty()) + return; + + std::vector vecFileNames; + for (int i = 0; i < files.size(); i++) { + vecFileNames.push_back(files[i].toStdString()); + } + AddFusionImage(index,vecFileNames,vvImageReader::IMAGE); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void vvMainWindow::ResetTransformationToIdentity() -{ +{ std::string actorType = DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString().toStdString(); int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); mSlicerManagers[index]->ResetTransformationToIdentity(actorType); @@ -2082,101 +2171,111 @@ void vvMainWindow::ResetTransformationToIdentity() //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -void vvMainWindow::AddFusionImage(int index, QString file) -{ +void vvMainWindow::AddFusionImage(int index, std::vector fileNames, vvImageReader::LoadedImageType type) +{ + QString file(fileNames[0].c_str()); if (QFile::exists(file)) { mInputPathName = itksys::SystemTools::GetFilenamePath(file.toStdString()).c_str(); itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO( - file.toStdString().c_str(), itk::ImageIOFactory::ReadMode); - reader->SetFileName(file.toStdString().c_str()); + file.toStdString().c_str(), itk::ImageIOFactory::ReadMode); + reader->SetFileName(fileNames[0].c_str()); reader->ReadImageInformation(); std::string component = reader->GetComponentTypeAsString(reader->GetComponentType()); - if (reader) { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - vvProgressDialog progress("Opening fusion"); - qApp->processEvents(); + int dimension = reader->GetNumberOfDimensions(); + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + vvProgressDialog progress("Opening fusion"); + qApp->processEvents(); - std::string filename = itksys::SystemTools::GetFilenameWithoutExtension(file.toStdString()).c_str(); - if (mSlicerManagers[index]->SetFusion(file.toStdString(), - reader->GetNumberOfDimensions(), component)) { - //create an item in the tree with good settings - QTreeWidgetItem *item = new QTreeWidgetItem(); - item->setData(0,Qt::UserRole,file.toStdString().c_str()); - item->setData(1,Qt::UserRole,tr("fusion")); - QFileInfo fileinfo(filename.c_str()); //Do not show the path - item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName()); - item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("fusion").c_str()); - qApp->processEvents(); + std::string filename = itksys::SystemTools::GetFilenameWithoutExtension(file.toStdString()).c_str(); + if (mSlicerManagers[index]->SetFusion(fileNames,dimension, component,type)) { + //create an item in the tree with good settings + QTreeWidgetItem *item = new QTreeWidgetItem(); + item->setData(0,Qt::UserRole,file.toStdString().c_str()); + item->setData(1,Qt::UserRole,tr("fusion")); + QFileInfo fileinfo(file); //Do not show the path + item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName()); + item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("fusion").c_str()); + qApp->processEvents(); +#if VTK_MAJOR_VERSION > 5 + for ( unsigned int i = 0; i < mSlicerManagers[index]->GetNumberOfSlicers(); i++) + mSlicerManagers[index]->GetSlicer(i)->ForceUpdateDisplayExtent(); +#endif + for (int j = 1; j <= 4; j++) { + item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole)); + } - for (int j = 1; j <= 4; j++) { - item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole)); - } + //Create the buttons for reload and close + qApp->processEvents(); + QTreePushButton* cButton = new QTreePushButton; + cButton->setItem(item); + cButton->setColumn(COLUMN_CLOSE_IMAGE); + cButton->setToolTip(tr("close image")); + cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png"))); + connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)), + this,SLOT(CloseImage(QTreeWidgetItem*, int))); - //Create the buttons for reload and close - qApp->processEvents(); - QTreePushButton* cButton = new QTreePushButton; - cButton->setItem(item); - cButton->setColumn(COLUMN_CLOSE_IMAGE); - cButton->setToolTip(tr("close image")); - cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png"))); - connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)), - this,SLOT(CloseImage(QTreeWidgetItem*, int))); + QTreePushButton* rButton = new QTreePushButton; + rButton->setItem(item); + rButton->setColumn(COLUMN_RELOAD_IMAGE); + rButton->setToolTip(tr("reload image")); + rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png"))); + connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)), + this,SLOT(ReloadImage(QTreeWidgetItem*, int))); - QTreePushButton* rButton = new QTreePushButton; - rButton->setItem(item); - rButton->setColumn(COLUMN_RELOAD_IMAGE); - rButton->setToolTip(tr("reload image")); - rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png"))); - connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)), - this,SLOT(ReloadImage(QTreeWidgetItem*, int))); + DataTree->topLevelItem(index)->setExpanded(1); + DataTree->topLevelItem(index)->addChild(item); + DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton); + DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton); - DataTree->topLevelItem(index)->setExpanded(1); - DataTree->topLevelItem(index)->addChild(item); - DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton); - DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton); + //set the id of the image + QString id = DataTree->topLevelItem(index)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString(); + item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str()); + UpdateTree(); + qApp->processEvents(); + ImageInfoChanged(); + QApplication::restoreOverrideCursor(); - //set the id of the image - QString id = DataTree->topLevelItem(index)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString(); - item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str()); - UpdateTree(); - qApp->processEvents(); - ImageInfoChanged(); - QApplication::restoreOverrideCursor(); - } else { - QApplication::restoreOverrideCursor(); - QString error = "Cannot import the new image.\n"; - error += mSlicerManagers[index]->GetLastError().c_str(); - QMessageBox::information(this,tr("Problem reading image !"),error); - } + // Update the display to update, e.g., the sliders + for(int i=0; i<4; i++) + DisplaySliders(index, i); } else { + QApplication::restoreOverrideCursor(); QString error = "Cannot import the new image.\n"; + error += mSlicerManagers[index]->GetLastError().c_str(); QMessageBox::information(this,tr("Problem reading image !"),error); } + WindowLevelChanged(); } else QMessageBox::information(this,tr("Problem reading Fusion !"),"File doesn't exist!"); } //------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +void vvMainWindow::AddLandmarks(int index, std::vector files) +{ + if (!landmarksPanel->LoadFromFile(files)) + QMessageBox::information(this,tr("Problem reading Landmarks !"),"File doesn't exist!"); + landmarksPanel->SetCurrentPath(mInputPathName.toStdString()); + landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str()); +} //------------------------------------------------------------------------------ void vvMainWindow::OpenField() -{ +{ int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); - //check if a vector field has already been added - for (int child = 0; child < DataTree->topLevelItem(index)->childCount(); child++) - if (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "vector") { - QString error = "Cannot add more than one vector field\n"; - error += "Please remove first "; - error += DataTree->topLevelItem(index)->child(child)->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString(); - QMessageBox::information(this,tr("Problem adding vector field!"),error); - return; - } + + if (!(CheckAddedImage(index, "vector"))) + return; - QString Extensions = "Images ( *.mhd)"; - Extensions += ";;Images ( *.mha)"; - Extensions += ";;Images ( *.vf)"; + QString Extensions = "Images ( *.mhd *.mha *.vf *.nii *.nrrd *.nhdr)"; + // Extensions += ";;Images ( *.mha)"; + // Extensions += ";;VF Images ( *.vf)"; + // Extensions += ";;nii Images ( *.nii)"; + // Extensions += ";;nrrd Images ( *.nrrd)"; + // Extensions += ";;nhdr Images ( *.nhdr)"; + Extensions += ";;All Files (*)"; QString file = QFileDialog::getOpenFileName(this,tr("Load deformation field"),mInputPathName,Extensions); if (!file.isEmpty()) AddField(file,index); @@ -2186,7 +2285,7 @@ void vvMainWindow::OpenField() //------------------------------------------------------------------------------ void vvMainWindow::AddFieldEntry(QString filename,int index,bool from_disk) -{ +{ //create an item in the tree with good settings QTreeWidgetItem *item = new QTreeWidgetItem(); item->setData(0,Qt::UserRole,filename.toStdString().c_str()); @@ -2208,7 +2307,7 @@ void vvMainWindow::AddFieldEntry(QString filename,int index,bool from_disk) cButton->setToolTip(tr("close vector field")); cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png"))); connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)), - this,SLOT(CloseImage(QTreeWidgetItem*, int))); + this,SLOT(CloseImage(QTreeWidgetItem*, int))); QTreePushButton* rButton = new QTreePushButton; rButton->setItem(item); @@ -2217,7 +2316,7 @@ void vvMainWindow::AddFieldEntry(QString filename,int index,bool from_disk) rButton->setEnabled(from_disk); rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png"))); connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)), - this,SLOT(ReloadImage(QTreeWidgetItem*, int))); + this,SLOT(ReloadImage(QTreeWidgetItem*, int))); DataTree->topLevelItem(index)->setExpanded(1); DataTree->topLevelItem(index)->addChild(item); @@ -2237,11 +2336,15 @@ void vvMainWindow::AddFieldEntry(QString filename,int index,bool from_disk) //------------------------------------------------------------------------------ void vvMainWindow::AddField(vvImage::Pointer vf,QString file,int index) -{ +{ QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); vvSlicerManager* imageManager = mSlicerManagers[index]; if (imageManager->SetVF(vf,file.toStdString())) { AddFieldEntry(file,index,false); +#if VTK_MAJOR_VERSION > 5 + for ( unsigned int i = 0; i < mSlicerManagers[index]->GetNumberOfSlicers(); i++) + mSlicerManagers[index]->GetSlicer(i)->ForceUpdateDisplayExtent(); +#endif } else { QString error = "Cannot import the vector field for this image.\n"; error += imageManager->GetLastError().c_str(); @@ -2254,7 +2357,7 @@ void vvMainWindow::AddField(vvImage::Pointer vf,QString file,int index) //------------------------------------------------------------------------------ void vvMainWindow::AddField(QString file,int index) -{ +{ if (QFile::exists(file)) { mInputPathName = itksys::SystemTools::GetFilenamePath(file.toStdString()).c_str(); @@ -2286,7 +2389,7 @@ void vvMainWindow::AddField(QString file,int index) //------------------------------------------------------------------------------ void vvMainWindow::SetVFProperty(int subsampling, int scale, int log, int width, double r, double g, double b) -{ +{ int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); if (mSlicerManagers[index]->GetSlicer(0)->GetVF()) { for (int i = 0; i < 4; i++) { @@ -2306,7 +2409,7 @@ void vvMainWindow::SetVFProperty(int subsampling, int scale, int log, int width, //------------------------------------------------------------------------------ void vvMainWindow::SetOverlayProperty(int color, int linked, double window, double level) -{ +{ int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); if (mSlicerManagers[index]->GetSlicer(0)->GetOverlay()) { mSlicerManagers[index]->SetOverlayColor(color); @@ -2321,7 +2424,7 @@ void vvMainWindow::SetOverlayProperty(int color, int linked, double window, doub //------------------------------------------------------------------------------ void vvMainWindow::SetFusionProperty(int opacity, int thresOpacity, int colormap,double window, double level, bool showLegend) -{ +{ int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) { mSlicerManagers[index]->SetFusionColorMap(colormap); @@ -2336,9 +2439,305 @@ void vvMainWindow::SetFusionProperty(int opacity, int thresOpacity, int colormap } //------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +void vvMainWindow::SelectFusionSequence() +{ + //get the index of the slicer manager of the main sequence (CT) + int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); + + if (!(CheckAddedImage(index, "fusion")) || !(CheckAddedImage(index, "fusionSequence"))) + return; + + QString Extensions = EXTENSIONS; + Extensions += ";;All Files (*)"; + QStringList files = QFileDialog::getOpenFileNames(this,tr("Load Overlay image sequence"),mInputPathName,Extensions); + if (files.isEmpty()) + return; + + std::vector vecFileNames; + for (int i = 0; i < files.size(); i++) { + vecFileNames.push_back(files[i].toStdString()); + } + + //associate the secondary sequence (US) to the main one + AddFusionSequence(index,vecFileNames,vvImageReader::MERGEDWITHTIME); +} +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +void vvMainWindow::SelectFusionSequenceCorrespondances() +{ + //make sure the index is right? + //in the end, I should attach the temporal data to the right sequence! + int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); + //in case the other sequence got selected, make sure we select the primary sequence + if ( (!mSlicerManagers[index]->GetSlicer(0)->GetFusion()) && mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()>=0 ) { + index = mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager(); + } + + //open a dialog box to find a file + //QString Extensions = EXTENSIONS; + QString Extensions = ";;All Files (*)"; + QString fileName = QFileDialog::getOpenFileName(this,tr("Load respiratory signal for fused sequence"),mInputPathName,Extensions); + if (fileName.isNull()) + return; + + //read it as a vector of values + vnl_vector tmpVect; + + std::ifstream file; + file.open(fileName.toStdString().c_str()); + tmpVect.read_ascii(file); + file.close(); + + //if compatible with the fused image sequence (number of entries = nb of entries in main sequence + nb of entries in joint sequence), enable the temporalSync + bool signalOK = true; + unsigned nbFrameMain = mSlicerManagers[index]->GetImage()->GetTransform().size(); + unsigned nbFrameSecondary = mSlicerManagers[index]->GetFusionSequenceNbFrames(); + std::cout<<"nbFrameMain = "< temporalCorrespondances; + if ( tmpVect.size() == nbFrameMain + nbFrameSecondary ) { + for (unsigned i=0 ; i index in secondary seq. + if ( tmpVect(i) index in secondary seq. + if ( tmpVect(i)SetFusionSequenceCorrespondances(temporalCorrespondances); + mSlicerManagers[ mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager() ]->SetFusionSequenceCorrespondances(temporalCorrespondances); + overlayPanel->enableFusionSequenceTemporalSync(); + } + +} +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +//when this function is called index is the slicer manager index corresponding to the main sequence (CT) +//the files behind fileNames points to the data for the secondary sequence +void vvMainWindow::AddFusionSequence(int index, std::vector fileNames, vvImageReader::LoadedImageType type) +{ + QString file(fileNames[0].c_str()); + if (QFile::exists(file)) + { + mInputPathName = itksys::SystemTools::GetFilenamePath(file.toStdString()).c_str(); + itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO( + file.toStdString().c_str(), itk::ImageIOFactory::ReadMode); + std::sort (fileNames.begin(), fileNames.end());//make sure the files are sorted. + reader->SetFileName(fileNames[0].c_str()); + reader->ReadImageInformation(); + std::string component = reader->GetComponentTypeAsString(reader->GetComponentType()); + int dimension = reader->GetNumberOfDimensions(); + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + vvProgressDialog progress("Opening " + file.toStdString()); + qApp->processEvents(); + + std::string filename = itksys::SystemTools::GetFilenameWithoutExtension(file.toStdString()).c_str(); + + if (mSlicerManagers[index]->SetFusionSequence(fileNames,dimension, component,type)) { + //create an item in the tree with good settings + QTreeWidgetItem *item = new QTreeWidgetItem(); + item->setData(0,Qt::UserRole,file.toStdString().c_str()); + item->setData(1,Qt::UserRole,tr("fusionSequence")); + + QFileInfo fileinfo(file); //Do not show the path + item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName()); + item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("fusionSequence").c_str()); + qApp->processEvents(); +#if VTK_MAJOR_VERSION > 5 + for ( unsigned int i = 0; i < mSlicerManagers[index]->GetNumberOfSlicers(); i++) + mSlicerManagers[index]->GetSlicer(i)->ForceUpdateDisplayExtent(); +#endif + for (int j = 1; j <= 4; j++) { + item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole)); + } + + //Create the buttons for reload and close + qApp->processEvents(); + QTreePushButton* cButton = new QTreePushButton; + cButton->setItem(item); + cButton->setColumn(COLUMN_CLOSE_IMAGE); + cButton->setToolTip(tr("close image")); + cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png"))); + connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)), + this,SLOT(CloseImage(QTreeWidgetItem*, int))); + + QTreePushButton* rButton = new QTreePushButton; + rButton->setItem(item); + rButton->setColumn(COLUMN_RELOAD_IMAGE); + rButton->setToolTip(tr("reload image")); + rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png"))); + connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)), + this,SLOT(ReloadImage(QTreeWidgetItem*, int))); + + DataTree->topLevelItem(index)->setExpanded(1); + DataTree->topLevelItem(index)->addChild(item); + DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton); + DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton); + + //store the original transform matrix + int indexParent = GetSlicerIndexFromItem( DataTree->topLevelItem(index) ); + mSlicerManagers[indexParent]->SetFusionSequenceMainTransformMatrix( mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[0]->GetMatrix() ); + + //set the id of the image + QString id = DataTree->topLevelItem(index)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString(); + item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str()); + UpdateTree(); + qApp->processEvents(); + + //ImageInfoChanged(); + + QApplication::restoreOverrideCursor(); + // Update the display to update, e.g., the sliders + for(int i=0; i<4; i++) + DisplaySliders(index, i); + + + //This loads the secondary sequence (US) as an independent sequence + LoadImages(fileNames, type); + //reset the transforms to identity + //FIX -- and set the thickness of the US slices to a large value (necessary for visualization purposes...) + double sp_x, sp_y, sp_z; + mSlicerManagers[indexParent]->GetImage()->GetVTKImages()[0]->GetSpacing(sp_x, sp_y, sp_z); + sp_z = std::max(sp_x, std::max(sp_y, sp_z)) + 0.5; // + for (unsigned i=0 ; iGetImage()->GetTransform().size() ; i++) { + sp_x = mSlicerManagers.back()->GetImage()->GetVTKImages()[i]->GetSpacing()[0]; + sp_y = mSlicerManagers.back()->GetImage()->GetVTKImages()[i]->GetSpacing()[1]; + mSlicerManagers.back()->GetImage()->GetVTKImages()[i]->SetSpacing( sp_x, sp_y, sp_z); + mSlicerManagers.back()->GetImage()->GetTransform()[i]->Identity(); + mSlicerManagers.back()->GetImage()->GetTransform()[i]->Update(); + } + + //automatically link both images... + AddLink(mSlicerManagers[indexParent]->GetId().c_str(), mSlicerManagers.back()->GetId().c_str(), false); + + //tie the main and secondary sequences by raising flags and informing each another of their respective SlicerManager indices + mSlicerManagers[indexParent]->SetFusionSequenceIndexOfLinkedManager(mSlicerManagers.size()-1); + mSlicerManagers[indexParent]->SetFusionSequenceInvolvmentCode(0); //main sequence + mSlicerManagers.back()->SetFusionSequenceIndexOfLinkedManager(indexParent); + mSlicerManagers.back()->SetFusionSequenceInvolvmentCode(1); //secondary sequence + for (unsigned i=0 ; i<4 ; i++) { + mSlicerManagers.back()->GetSlicer(i)->SetFusionSequenceCode(1); //flag the slicers of the secondary sequence + } + + } else { + QApplication::restoreOverrideCursor(); + QString error = "Cannot import the new image.\n"; + error += mSlicerManagers[index]->GetLastError().c_str(); + QMessageBox::information(this,tr("Problem reading image !"),error); + } + WindowLevelChanged(); + ImageInfoChanged(); //this internally calls WindowLevelChanged... + } + else { + QMessageBox::information(this,tr("Problem reading fusion sequence !"),"File doesn't exist!"); + return; + } + +} +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +//fusionSequenceFrameIndex and fusionSequenceNbFrames are relative to the secondary sequence (US) +void vvMainWindow::SetFusionSequenceProperty(int fusionSequenceFrameIndex, bool spatialSyncFlag, unsigned int fusionSequenceNbFrames, bool temporalSyncFlag) +{ + int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); + + if (!mSlicerManagers[index]->IsInvolvedInFusionSequence()) return; + + //check if the focus moved to the linked sequence, and in this case, select the master sequence instead + if (!mSlicerManagers[index]->IsMainSequenceOfFusionSequence()) { + index = mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager(); + } + int secondaryIndex = mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager(); + if (secondaryIndex==-1) return; //this should never happen + if ( (!mSlicerManagers[index]->IsMainSequenceOfFusionSequence()) || + (!mSlicerManagers[secondaryIndex]->IsSecondarySequenceOfFusionSequence()) ) + {return;} //this should never happen, raise an exception? + + if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) { + + //First, if the spatialSync button is unchecked, then reposition the parent sequence (CT) in its original coordinate frame + if ( (!spatialSyncFlag) && (mSlicerManagers[index]->GetFusionSequenceSpatialSyncFlag()) ) { + for ( unsigned i=0 ; iGetSlicer(0)->GetImage()->GetTransform().size() ; i++ ) { + mSlicerManagers[index]->GetSlicer(0)->GetImage()->GetTransform()[i]->SetMatrix( mSlicerManagers[index]->GetFusionSequenceMainTransformMatrix() ); + mSlicerManagers[index]->GetSlicer(0)->GetImage()->GetTransform()[i]->Update(); + } + + for (int i=0; iGetNumberOfSlicers(); i++) { + mSlicerManagers[index]->GetSlicer(i)->ForceUpdateDisplayExtent(); + mSlicerManagers[index]->GetSlicer(i)->Render(); + } + } + + //then, update the property values in the slicer manager + mSlicerManagers[index]->SetFusionSequenceLength(fusionSequenceNbFrames); + mSlicerManagers[index]->SetFusionSequenceSpatialSyncFlag(spatialSyncFlag); + mSlicerManagers[index]->SetFusionSequenceTemporalSyncFlag(temporalSyncFlag); + mSlicerManagers[index]->SetFusionSequenceFrameIndex(fusionSequenceFrameIndex); + + //select the right frame of the US sequence + mSlicerManagers[index]->SetFusionSequenceTSlice(fusionSequenceFrameIndex); //here, I should only update the overlayed sequence + mSlicerManagers[secondaryIndex]->SetTSlice(fusionSequenceFrameIndex, false); //this should update the secondary sequence (individual version) + + //update the horizontal sliders of the main window + overlayPanel->updateFusionSequenceSliderValueFromWindow(fusionSequenceFrameIndex, false); + + if (spatialSyncFlag) { //reslice the CT + + if (temporalSyncFlag) { //do the temporal synchronisation + int mainSequenceFrameIndex=0; + //estimate the TSlice to set to the CT + unsigned nbFramesMain = mSlicerManagers[index]->GetImage()->GetTransform().size(); + mainSequenceFrameIndex = mSlicerManagers[index]->GetFusionSequenceCorrespondances()[ nbFramesMain + fusionSequenceFrameIndex]; + //and set it! + mSlicerManagers[index]->SetTSlice(mainSequenceFrameIndex, false); + //warning, there is a loopback, and modification of the TSlice in main sequence forces an update of the TSlice in secondary, etc... + } + + + //Set the transform matrix of the parent sequence (typically CT / 4DCT) + vtkSmartPointer tmpMat = vtkSmartPointer::New(); + vtkMatrix4x4::Invert( mSlicerManagers[index]->GetFusionSequenceInitialTransformMatrixAtFrame(fusionSequenceFrameIndex), tmpMat ); + for ( unsigned i=0 ; iGetSlicer(0)->GetImage()->GetTransform().size() ; i++ ) { + mSlicerManagers[index]->GetSlicer(0)->GetImage()->GetTransform()[i]->SetMatrix( mSlicerManagers[index]->GetFusionSequenceMainTransformMatrix() ); + mSlicerManagers[index]->GetSlicer(0)->GetImage()->GetTransform()[i]->PreMultiply(); + mSlicerManagers[index]->GetSlicer(0)->GetImage()->GetTransform()[i]->Concatenate( tmpMat ); + mSlicerManagers[index]->GetSlicer(0)->GetImage()->GetTransform()[i]->Update(); + } + + for (int i=0; iGetNumberOfSlicers(); i++) { + mSlicerManagers[index]->GetSlicer(i)->ForceUpdateDisplayExtent(); + mSlicerManagers[index]->GetSlicer(i)->Render(); + } + + } + + } +} +//------------------------------------------------------------------------------ + + //------------------------------------------------------------------------------ void vvMainWindow::SaveAs() -{ +{ if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "vector") { QMessageBox::warning(this,tr("Unsupported type"),tr("Sorry, saving a vector field is unsupported for the moment")); return; @@ -2383,50 +2782,50 @@ void vvMainWindow::SaveAs() Extensions += ")"; } QString fileName = QFileDialog::getSaveFileName(this, - tr("Save As"), - mSlicerManagers[index]->GetFileName().c_str(), - Extensions); + tr("Save As"), + mSlicerManagers[index]->GetFileName().c_str(), + Extensions); if (!fileName.isEmpty()) { std::string fileformat = itksys::SystemTools::GetFilenameLastExtension(fileName.toStdString()); if (OutputListeFormat.contains( - fileformat.c_str())) { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - std::string action = "Saving"; - vvProgressDialog progress("Saving "+fileName.toStdString()); - qApp->processEvents(); - vvImageWriter::Pointer writer = vvImageWriter::New(); - writer->SetOutputFileName(fileName.toStdString()); - writer->SetInput(mSlicerManagers[index]->GetImage()); - - // Check on transform and prompt user - writer->SetSaveTransform(false); - bool bId = true; - for(int i=0; i<4; i++) - for(int j=0; j<4; j++) { - // TODO SR and BP: check on the list of transforms and not the first only - double elt = mSlicerManagers[index]->GetImage()->GetTransform()[0]->GetMatrix()->GetElement(i,j); - if(i==j && elt!=1.) - bId = false; - if(i!=j && elt!=0.) - bId = false; - } - if( !bId ) { - QString warning = "The image has an associated linear transform. Do you want to save it along?"; - QMessageBox msgBox(QMessageBox::Warning, tr("Save transform"), warning, 0, this); - msgBox.addButton(tr("Yes"), QMessageBox::AcceptRole); - msgBox.addButton(tr("No"), QMessageBox::RejectRole); - if (msgBox.exec() == QMessageBox::AcceptRole) - writer->SetSaveTransform(true); - } + fileformat.c_str())) { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + std::string action = "Saving"; + vvProgressDialog progress("Saving "+fileName.toStdString()); + qApp->processEvents(); + vvImageWriter::Pointer writer = vvImageWriter::New(); + writer->SetOutputFileName(fileName.toStdString()); + writer->SetInput(mSlicerManagers[index]->GetImage()); + + // Check on transform and prompt user + writer->SetSaveTransform(false); + bool bId = true; + for(int i=0; i<4; i++) + for(int j=0; j<4; j++) { + // TODO SR and BP: check on the list of transforms and not the first only + double elt = mSlicerManagers[index]->GetImage()->GetTransform()[0]->GetMatrix()->GetElement(i,j); + if(i==j && elt!=1.) + bId = false; + if(i!=j && elt!=0.) + bId = false; + } + if( !bId ) { + QString warning = "The image has an associated linear transform. Do you want to save it along?"; + QMessageBox msgBox(QMessageBox::Warning, tr("Save transform"), warning, 0, this); + msgBox.addButton(tr("Yes"), QMessageBox::AcceptRole); + msgBox.addButton(tr("No"), QMessageBox::RejectRole); + if (msgBox.exec() == QMessageBox::AcceptRole) + writer->SetSaveTransform(true); + } - writer->Update(); - QApplication::restoreOverrideCursor(); - if (writer->GetLastError().size()) { - QString error = "Saving did not succeed\n"; - error += writer->GetLastError().c_str(); - QMessageBox::information(this,tr("Saving Problem"),error); - SaveAs(); - } + writer->Update(); + QApplication::restoreOverrideCursor(); + if (writer->GetLastError().size()) { + QString error = "Saving did not succeed\n"; + error += writer->GetLastError().c_str(); + QMessageBox::information(this,tr("Saving Problem"),error); + SaveAs(); + } } else { QString error = fileformat.c_str(); if (error.isEmpty()) @@ -2442,40 +2841,40 @@ void vvMainWindow::SaveAs() //------------------------------------------------------------------------------ void vvMainWindow::SaveCurrentState() -{ +{ QString Extensions = "XML Files(*.xml)"; QString fileName = QFileDialog::getSaveFileName(this, - tr("Save Current Window State"), - "", - Extensions); - + tr("Save Current Window State"), + "", + Extensions); + SaveCurrentStateAs(fileName.toStdString()); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void vvMainWindow::SaveCurrentStateAs(const std::string& stateFile) -{ +{ vvSaveState save_state; save_state.Run(this, stateFile); } //------------------------------------------------------------------------------ void vvMainWindow::ReadSavedState() -{ +{ QString Extensions = "XML Files(*.xml)"; QString fileName = QFileDialog::getOpenFileName(this, - tr("Load Window State"), - "", - Extensions); - + tr("Load Window State"), + "", + Extensions); + ReadSavedStateFile(fileName.toStdString()); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void vvMainWindow::ReadSavedStateFile(const std::string& stateFile) -{ +{ vvReadState read_state; read_state.Run(this, stateFile); } @@ -2483,19 +2882,19 @@ void vvMainWindow::ReadSavedStateFile(const std::string& stateFile) //------------------------------------------------------------------------------ void vvMainWindow::LinkAllImages() -{ - linkPanel->linkAll(); +{ + linkPanel->linkAll(); } //------------------------------------------------------------------------------ void vvMainWindow::AddLink(QString image1,QString image2,bool fromPanel) -{ +{ if (!fromPanel) { // delegate to linkPanel if call came from elsewhere... linkPanel->addLinkFromIds(image1, image2); return; } - + unsigned int sm1 = 0; unsigned int sm2 = 0; @@ -2523,7 +2922,7 @@ void vvMainWindow::AddLink(QString image1,QString image2,bool fromPanel) //------------------------------------------------------------------------------ void vvMainWindow::RemoveLink(QString image1,QString image2) -{ +{ for (unsigned int i = 0; i < mSlicerManagers.size(); i++) { if (image1.toStdString() == mSlicerManagers[i]->GetId()) { mSlicerManagers[i]->RemoveLink(image2.toStdString()); @@ -2537,7 +2936,7 @@ void vvMainWindow::RemoveLink(QString image1,QString image2) //------------------------------------------------------------------------------ void vvMainWindow::ChangeImageWithIndexOffset(vvSlicerManager *sm, int slicer, int offset) -{ +{ if(mSlicerManagers.size()==1) return; @@ -2552,15 +2951,33 @@ void vvMainWindow::ChangeImageWithIndexOffset(vvSlicerManager *sm, int slicer, i DisplayChanged(item,slicer+1); } //------------------------------------------------------------------------------ - void vvMainWindow::HorizontalSliderMoved(int value,int column, int slicer_index) -{ +{ for (unsigned int i = 0; i < mSlicerManagers.size(); i++) { if (DataTree->topLevelItem(i)->data(column,Qt::CheckStateRole).toInt() > 1) { + //i is the SlicerManager that is in charge of this slicer. + if (mSlicerManagers[i]->IsInvolvedInFusionSequence()) { + //if the slicerManager is involved in a fusionSequence as the secondary sequence, then update the slider position in the overlay panel and everything accordingly + if (mSlicerManagers[i]->IsSecondarySequenceOfFusionSequence()) { + overlayPanel->updateFusionSequenceSliderValueFromWindow(value, true); + } + else { //if this is the primary sequence that has been modified + if (mSlicerManagers[i]->GetFusionSequenceTemporalSyncFlag()) { + //WARNING: for some obscure reason, there are problems when accessing mSlicerManagers[mSlicerManagers[i]->GetFusionSequenceIndexOfLinkedManager()]->GetFusionSequenceFrameIndex(); + + int estimatedValue=0; + //estimate a corresponding time index for the secondary (US) sequence, and update it accordingly. + estimatedValue = mSlicerManagers[i]->GetFusionSequenceCorrespondances()[ value ]; + //TODO: at the moment, there is a loop in TSlice modifications + //modifying sequence 1 causes seq 2 to update, which in turns update seq1... + //I disable control on seq1 at the moment. + //overlayPanel->updateFusionSequenceSliderValueFromWindow(estimatedValue, true); + } + } + } + for (int j = 0; j < 4; j++) { mSlicerManagers[i]->SetTSliceInSlicer(value,j); - //if (mSlicerManagers[i]->GetSlicer(j)->GetImageActor()->GetVisibility()) - //UpdateTSlice(j,value); } mSlicerManagers[i]->GetSlicer(slicer_index)->Render(); break; @@ -2572,27 +2989,27 @@ void vvMainWindow::HorizontalSliderMoved(int value,int column, int slicer_index) //------------------------------------------------------------------------------ void vvMainWindow::NOHorizontalSliderMoved() -{ +{ // if (mCurrentTime == NOHorizontalSlider->value()) return; HorizontalSliderMoved(NOHorizontalSlider->value(),COLUMN_UL_VIEW,0); -// mCurrentTime = NOHorizontalSlider->value(); + // mCurrentTime = NOHorizontalSlider->value(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void vvMainWindow::NEHorizontalSliderMoved() -{ +{ // if (mCurrentTime == NEHorizontalSlider->value()) return; HorizontalSliderMoved(NEHorizontalSlider->value(),COLUMN_UR_VIEW,1); -// mCurrentTime = NEHorizontalSlider->value(); + // mCurrentTime = NEHorizontalSlider->value(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void vvMainWindow::SOHorizontalSliderMoved() -{ +{ // if (mCurrentTime == SOHorizontalSlider->value()) return; HorizontalSliderMoved(SOHorizontalSlider->value(),COLUMN_DL_VIEW,2); // mCurrentTime = SOHorizontalSlider->value(); @@ -2602,7 +3019,7 @@ void vvMainWindow::SOHorizontalSliderMoved() //------------------------------------------------------------------------------ void vvMainWindow::SEHorizontalSliderMoved() -{ +{ // if (mCurrentTime == SEHorizontalSlider->value()) return; HorizontalSliderMoved(SEHorizontalSlider->value(),COLUMN_DR_VIEW,3); // mCurrentTime = SEHorizontalSlider->value(); @@ -2611,7 +3028,7 @@ void vvMainWindow::SEHorizontalSliderMoved() //------------------------------------------------------------------------------ void vvMainWindow::NOVerticalSliderChanged() -{ +{ static int value=-1; if (value == NOVerticalSlider->value()) return; else value = NOVerticalSlider->value(); @@ -2637,7 +3054,7 @@ void vvMainWindow::NOVerticalSliderChanged() //------------------------------------------------------------------------------ void vvMainWindow::NEVerticalSliderChanged() -{ +{ static int value=-1; if (value == NEVerticalSlider->value()) return; else value = NEVerticalSlider->value(); @@ -2659,7 +3076,7 @@ void vvMainWindow::NEVerticalSliderChanged() //------------------------------------------------------------------------------ void vvMainWindow::SOVerticalSliderChanged() -{ +{ static int value=-1; if (value == SOVerticalSlider->value()) return; else value = SOVerticalSlider->value(); @@ -2682,7 +3099,7 @@ void vvMainWindow::SOVerticalSliderChanged() //------------------------------------------------------------------------------ void vvMainWindow::SEVerticalSliderChanged() -{ +{ static int value=-1; if (value == SEVerticalSlider->value()) return; else value = SEVerticalSlider->value(); @@ -2704,10 +3121,10 @@ void vvMainWindow::SEVerticalSliderChanged() //------------------------------------------------------------------------------ void vvMainWindow::UpdateSlice(int slicer, int slice) -{ +{ // DD("vvMainWindow::UpdateSlice"); -// DD(slicer); -// DD(slice); + // DD(slicer); + // DD(slice); if (slicer == 0) { // if (slice != NOVerticalSlider->value()) NOVerticalSlider->setValue(slice); @@ -2729,19 +3146,37 @@ void vvMainWindow::UpdateSlice(int slicer, int slice) //------------------------------------------------------------------------------ -void vvMainWindow::UpdateTSlice(int slicer, int slice) -{ +void vvMainWindow::UpdateTSlice(int slicer, int slice, int code) +{ + //FusionSequence: the slider value should be updated for slicers which show the same sequence as requested + bool doUpdate=false; + if (code==-1) doUpdate=true; + else { + for (unsigned int i = 0; i < mSlicerManagers.size(); i++) { + if (DataTree->topLevelItem(i)->data(slicer+1,Qt::CheckStateRole).toInt() > 1) { + //i is the active SlicerManager + if (mSlicerManagers[i]->GetFusionSequenceInvolvmentCode()==code) doUpdate=true; + break; + } + } + } + if (!doUpdate) return; + switch (slicer) { case 0: + if (NOHorizontalSlider->value()==slice) return; NOHorizontalSlider->setValue(slice); break; case 1: + if (NEHorizontalSlider->value()==slice) return; NEHorizontalSlider->setValue(slice); break; case 2: + if (SOHorizontalSlider->value()==slice) return; SOHorizontalSlider->setValue(slice); break; case 3: + if (SEHorizontalSlider->value()==slice) return; SEHorizontalSlider->setValue(slice); break; } @@ -2751,7 +3186,7 @@ void vvMainWindow::UpdateTSlice(int slicer, int slice) //------------------------------------------------------------------------------ void vvMainWindow::UpdateSliceRange(int slicer, int min, int max, int tmin, int tmax) -{ +{ //int position = int((min+max)/2); int position = mSlicerManagers[mCurrentPickedImageIndex]->GetSlicer(slicer)->GetSlice(); if (slicer == 0) { @@ -2777,7 +3212,7 @@ void vvMainWindow::UpdateSliceRange(int slicer, int min, int max, int tmin, int //------------------------------------------------------------------------------ void vvMainWindow::SaveNOScreenshot() -{ +{ SaveScreenshot(NOViewWidget); } //------------------------------------------------------------------------------ @@ -2785,7 +3220,7 @@ void vvMainWindow::SaveNOScreenshot() //------------------------------------------------------------------------------ void vvMainWindow::SaveNEScreenshot() -{ +{ SaveScreenshot(NEViewWidget); } //------------------------------------------------------------------------------ @@ -2793,7 +3228,7 @@ void vvMainWindow::SaveNEScreenshot() //------------------------------------------------------------------------------ void vvMainWindow::SaveSOScreenshot() -{ +{ SaveScreenshot(SOViewWidget); } //------------------------------------------------------------------------------ @@ -2801,7 +3236,7 @@ void vvMainWindow::SaveSOScreenshot() //------------------------------------------------------------------------------ void vvMainWindow::SaveSEScreenshot() -{ +{ SaveScreenshot(SEViewWidget); } //------------------------------------------------------------------------------ @@ -2809,7 +3244,7 @@ void vvMainWindow::SaveSEScreenshot() //------------------------------------------------------------------------------ void vvMainWindow::SaveScreenshotAllSlices() -{ +{ QVTKWidget *widget = NOViewWidget; int index = 0;// GetSlicerIndexFromItem(DataTree->selectedItems()[0]); @@ -2822,24 +3257,24 @@ void vvMainWindow::SaveScreenshotAllSlices() // Select filename base QString filename = QFileDialog::getSaveFileName(this, - tr("Save As (filename will be completed by slice number)"), - itksys::SystemTools::GetFilenamePath(mSlicerManagers[index]->GetFileName()).c_str(), - "Images( *.png);;Images( *.jpg)"); + tr("Save As (filename will be completed by slice number)"), + itksys::SystemTools::GetFilenamePath(mSlicerManagers[index]->GetFileName()).c_str(), + "Images( *.png);;Images( *.jpg)"); // Loop on slices for(int i=0; iSetSlice(i); // -> change the slice of the current slicer SM->UpdateSlice(0); // --> this one emit UpdateSlice - QCoreApplication::flush(); // -> needed to force display of contours + QCoreApplication::flush(); // -> needed to force display of contours - // Screenshot + // Screenshot vtkSmartPointer windowToImageFilter = vtkSmartPointer::New(); windowToImageFilter->SetInput(renderWindow); windowToImageFilter->SetMagnification(1); windowToImageFilter->SetInputBufferTypeToRGBA(); //also record the alpha (transparency) channel windowToImageFilter->Update(); - + vtkSmartPointer writer = vtkSmartPointer::New(); std::string fn = itksys::SystemTools::GetFilenameWithoutLastExtension(filename.toStdString()); std::string num = clitk::toString(i); @@ -2847,10 +3282,14 @@ void vvMainWindow::SaveScreenshotAllSlices() if (i<100) num = "0"+num; if (i<1000) num = "0"+num; - fn = itksys::SystemTools::GetFilenamePath(filename.toStdString()) + "/"+ fn + fn = itksys::SystemTools::GetFilenamePath(filename.toStdString()) + "/"+ fn + "_" + num + itksys::SystemTools::GetFilenameLastExtension(filename.toStdString()); writer->SetFileName(fn.c_str()); +#if VTK_MAJOR_VERSION <= 5 writer->SetInput(windowToImageFilter->GetOutput()); +#else + writer->SetInputConnection(windowToImageFilter->GetOutputPort()); +#endif writer->Write(); } } @@ -2859,7 +3298,7 @@ void vvMainWindow::SaveScreenshotAllSlices() //------------------------------------------------------------------------------ void vvMainWindow::SaveScreenshot(QVTKWidget *widget) -{ +{ QString Extensions = "Images( *.png);;"; Extensions += "Images( *.jpg);;"; Extensions += "Images( *.bmp);;"; @@ -2877,9 +3316,9 @@ void vvMainWindow::SaveScreenshot(QVTKWidget *widget) int smIndex=GetSlicerIndexFromItem(DataTree->selectedItems()[0]); QString fileName = QFileDialog::getSaveFileName(this, - tr("Save As"), - itksys::SystemTools::GetFilenamePath(mSlicerManagers[smIndex]->GetFileName()).c_str(), - Extensions); + tr("Save As"), + itksys::SystemTools::GetFilenamePath(mSlicerManagers[smIndex]->GetFileName()).c_str(), + Extensions); if (!fileName.isEmpty()) { vtkSmartPointer w2i = vtkSmartPointer::New(); @@ -2904,7 +3343,11 @@ void vvMainWindow::SaveScreenshot(QVTKWidget *widget) // Snapshot image if not null if(imgwriter!=NULL) { +#if VTK_MAJOR_VERSION <= 5 imgwriter->SetInput(image); +#else + imgwriter->SetInputConnection(w2i->GetOutputPort()); +#endif imgwriter->SetFileName(fileName.toStdString().c_str()); imgwriter->Write(); return; @@ -2919,14 +3362,14 @@ void vvMainWindow::SaveScreenshot(QVTKWidget *widget) // FPS bool ok; - int fps = QInputDialog::getInteger(this, tr("Number of frames per second"), - tr("FPS:"), 5, 0, 1000, 1, &ok); + int fps = QInputDialog::getInt(this, tr("Number of frames per second"), + tr("FPS:"), 5, 0, 1000, 1, &ok); if(ok) gif->SetRate(fps); // Loops - int loops = QInputDialog::getInteger(this, tr("Loops"), - tr("Number of loops (0 means infinite):"), 0, 0, 1000000000, 1, &ok); + int loops = QInputDialog::getInt(this, tr("Loops"), + tr("Number of loops (0 means infinite):"), 0, 0, 1000000000, 1, &ok); if(ok) gif->SetLoops(loops); @@ -2944,8 +3387,8 @@ void vvMainWindow::SaveScreenshot(QVTKWidget *widget) vidwriter = mpg; mpg->SetQuality(2); bool ok; - int fps = QInputDialog::getInteger(this, tr("Number of frames per second"), - tr("FPS:"), 5, 0, 1024, 1, &ok); + int fps = QInputDialog::getInt(this, tr("Number of frames per second"), + tr("FPS:"), 5, 0, 1024, 1, &ok); if(!ok) fps = 5; mpg->SetRate(fps); @@ -2957,8 +3400,8 @@ void vvMainWindow::SaveScreenshot(QVTKWidget *widget) vidwriter = mpg; mpg->SetQuality(2); bool ok; - int fps = QInputDialog::getInteger(this, tr("Number of frames per second"), - tr("FPS:"), 5, 0, 1024, 1, &ok); + int fps = QInputDialog::getInt(this, tr("Number of frames per second"), + tr("FPS:"), 5, 0, 1024, 1, &ok); if(!ok) fps = 5; mpg->SetRate(fps); @@ -2974,7 +3417,11 @@ void vvMainWindow::SaveScreenshot(QVTKWidget *widget) // Take video if not null if(vidwriter!=NULL){ +#if VTK_MAJOR_VERSION <= 5 vidwriter->SetInput(image); +#else + vidwriter->SetInputConnection(w2i->GetOutputPort()); +#endif vidwriter->SetFileName(fileName.toStdString().c_str()); vidwriter->Start(); int nSlice = mSlicerManagers[smIndex]->GetSlicer(0)->GetTMax(); @@ -2983,7 +3430,11 @@ void vvMainWindow::SaveScreenshot(QVTKWidget *widget) vtkSmartPointer w2i = vtkSmartPointer::New(); w2i->SetInput(widget->GetRenderWindow()); w2i->Update(); +#if VTK_MAJOR_VERSION <= 5 vidwriter->SetInput(w2i->GetOutput()); +#else + vidwriter->SetInputConnection(w2i->GetOutputPort()); +#endif vidwriter->Write(); } vidwriter->End(); @@ -2999,7 +3450,7 @@ void vvMainWindow::SaveScreenshot(QVTKWidget *widget) //------------------------------------------------------------------------------ void vvMainWindow::GoToCursor() -{ +{ int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); for (int column = 1; column < 5; column++) { if (DataTree->selectedItems()[0]->data(column,Qt::CheckStateRole).toInt() > 1) { @@ -3014,9 +3465,26 @@ void vvMainWindow::GoToCursor() } //------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +void vvMainWindow::GoToLandmark() +{ + int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); + for (int column = 1; column < 5; column++) { + if (DataTree->selectedItems()[0]->data(column,Qt::CheckStateRole).toInt() > 1) { + double* cursorPos = landmarksPanel->GetSelectedPoint(); + mSlicerManagers[index]->GetSlicer(column-1)->SetCurrentPosition( + cursorPos[0],cursorPos[1],cursorPos[2],cursorPos[3]); + mSlicerManagers[index]->UpdateViews(1,column-1); + mSlicerManagers[index]->UpdateLinked(column-1); + break; + } + } +} +//------------------------------------------------------------------------------ + //------------------------------------------------------------------------------ void vvMainWindow::PlayPause() -{ +{ if (playMode) { playMode = 0; playButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/player_play.png"))); @@ -3030,46 +3498,53 @@ void vvMainWindow::PlayPause() has_temporal=true; break; } - if (has_temporal) { - playMode = 1; - playButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/player_pause.png"))); - QTimer::singleShot(1000/mFrameRate, this, SLOT(PlayNext())); - } + if (has_temporal) { + playMode = 1; + playButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/player_pause.png"))); + QTimer::singleShot(1000/mFrameRate, this, SLOT(PlayNext())); + } } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void vvMainWindow::PlayNext() -{ +{ if (playMode && !this->isHidden()) { int image_number=DataTree->topLevelItemCount(); ///Only play one slicer per SM, and only if the SM is being displayed for (int i=0; iGetSlicer(0)->GetTMax() > 0 && - DataTree->topLevelItem(i)->data(j+1,Qt::CheckStateRole).toInt() > 0) { - mSlicerManagers[i]->SetNextTSlice(j); - break; + DataTree->topLevelItem(i)->data(j+1,Qt::CheckStateRole).toInt() > 0) { + mSlicerManagers[i]->SetNextTSlice(j); + break; } - QTimer::singleShot(1000/mFrameRate, this, SLOT(PlayNext())); + QTimer::singleShot(1000/mFrameRate, this, SLOT(PlayNext())); } } //------------------------------------------------------------------------------ void vvMainWindow::ShowLastImage() -{ +{ if (mSlicerManagers.size() > 1) { QTreeWidgetItem * item=DataTree->topLevelItem(DataTree->topLevelItemCount()-1); CurrentImageChanged(mSlicerManagers.back()->GetId()); //select new image item->setData(1,Qt::CheckStateRole,2); //show the new image in the first panel + //mSlicerManagers[GetSlicerIndexFromItem(item)]->GetSlicer(0)->SetActorVisibility("image", 0, 1); //Set the Last Image visibles DisplayChanged(item,1); } } //------------------------------------------------------------------------------ void vvMainWindow::UpdateRenderWindows() -{ +{ + for (unsigned int i = 0; i < mSlicerManagers.size(); i++) { + for (unsigned int j = 0; j < 4; ++j) { + mSlicerManagers[i]->GetSlicer(j)->RemoveLandmarks(); + mSlicerManagers[i]->GetSlicer(j)->DisplayLandmarks(); + } + } if (NOViewWidget->GetRenderWindow()) NOViewWidget->GetRenderWindow()->Render(); if (NEViewWidget->GetRenderWindow()) NEViewWidget->GetRenderWindow()->Render(); if (SOViewWidget->GetRenderWindow()) SOViewWidget->GetRenderWindow()->Render(); @@ -3079,7 +3554,7 @@ void vvMainWindow::UpdateRenderWindows() //------------------------------------------------------------------------------ void vvMainWindow::SegmentationOnCurrentImage() -{ +{ int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); vvSegmentationDialog segmentation; @@ -3089,7 +3564,7 @@ void vvMainWindow::SegmentationOnCurrentImage() //------------------------------------------------------------------------------ void vvMainWindow::SurfaceViewerLaunch() -{ +{ vvSurfaceViewerDialog surfaceViewer; surfaceViewer.exec(); } @@ -3098,13 +3573,13 @@ void vvMainWindow::SurfaceViewerLaunch() //------------------------------------------------------------------------------ int vvMainWindow::GetImageDuplicateFilenameNumber(std::string filename) -{ +{ int number=0; for(unsigned int l=0; lGetBaseFileName() == - vtksys::SystemTools::GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(filename))) { - number = std::max(number, v->GetBaseFileNameNumber()+1); + vtksys::SystemTools::GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(filename))) { + number = std::max(number, v->GetBaseFileNameNumber()+1); } } return number; @@ -3114,7 +3589,7 @@ int vvMainWindow::GetImageDuplicateFilenameNumber(std::string filename) //------------------------------------------------------------------------------ vvSlicerManager* vvMainWindow::AddImage(vvImage::Pointer image,std::string filename) -{ +{ // Change filename if another image exist with the same name int number = GetImageDuplicateFilenameNumber(filename); @@ -3141,7 +3616,7 @@ vvSlicerManager* vvMainWindow::AddImage(vvImage::Pointer image,std::string filen cButton->setColumn(COLUMN_CLOSE_IMAGE); cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png"))); connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)), - this,SLOT(CloseImage(QTreeWidgetItem*, int))); + this,SLOT(CloseImage(QTreeWidgetItem*, int))); QTreePushButton* rButton = new QTreePushButton; rButton->setItem(item); @@ -3149,7 +3624,7 @@ vvSlicerManager* vvMainWindow::AddImage(vvImage::Pointer image,std::string filen rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png"))); rButton->setEnabled(0); connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)), - this,SLOT(ReloadImage(QTreeWidgetItem*, int))); + this,SLOT(ReloadImage(QTreeWidgetItem*, int))); DataTree->addTopLevelItem(item); DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton); @@ -3161,44 +3636,48 @@ vvSlicerManager* vvMainWindow::AddImage(vvImage::Pointer image,std::string filen mSlicerManagers.back()->SetId(id.toStdString()); linkPanel->addImage(slicer_manager->GetFileName().c_str()// filename - , id.toStdString()); + , id.toStdString()); connect(mSlicerManagers.back(), SIGNAL(currentImageChanged(std::string)), - this, SLOT(CurrentImageChanged(std::string))); + this, SLOT(CurrentImageChanged(std::string))); connect(mSlicerManagers.back(), SIGNAL(currentPickedImageChanged(std::string)), - this, SLOT(CurrentPickedImageChanged(std::string))); + this, SLOT(CurrentPickedImageChanged(std::string))); connect(mSlicerManagers.back(), SIGNAL(UpdatePosition(int, double, double, double, double, double, double, double)), - this, SLOT(MousePositionChanged(int,double, double, double, double, double, double, double))); + this, SLOT(MousePositionChanged(int,double, double, double, double, double, double, double))); connect(mSlicerManagers.back(), SIGNAL(UpdateVector(int, double, double, double, double)), - this, SLOT(VectorChanged(int,double,double,double, double))); + this, SLOT(VectorChanged(int,double,double,double, double))); connect(mSlicerManagers.back(), SIGNAL(UpdateOverlay(int, double, double)), - this, SLOT(OverlayChanged(int,double,double))); + this, SLOT(OverlayChanged(int,double,double))); connect(mSlicerManagers.back(), SIGNAL(UpdateFusion(int, double)), - this, SLOT(FusionChanged(int,double))); + this, SLOT(FusionChanged(int,double))); + //connect(mSlicerManagers.back(), SIGNAL(UpdateFusionSequence(int, bool, unsigned int)), + // this, SLOT(FusionSequenceChanged(int, bool, unsigned int))); connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged()), - this,SLOT(WindowLevelChanged())); + this,SLOT(WindowLevelChanged())); connect(mSlicerManagers.back(), SIGNAL(UpdateSlice(int,int)), - this,SLOT(UpdateSlice(int,int))); - connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)), - this,SLOT(UpdateTSlice(int, int))); - connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)), - this,SLOT(ImageInfoChanged())); + this,SLOT(UpdateSlice(int,int))); + connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int, int)), + this,SLOT(UpdateTSlice(int, int, int))); + connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int, int)), + this,SLOT(ImageInfoChanged())); connect(mSlicerManagers.back(), SIGNAL(UpdateSliceRange(int,int,int,int,int)), - this,SLOT(UpdateSliceRange(int,int,int,int,int))); + this,SLOT(UpdateSliceRange(int,int,int,int,int))); connect(mSlicerManagers.back(), SIGNAL(UpdateLinkManager(std::string,int,double,double,double,int)), - this,SLOT(UpdateLinkManager(std::string,int,double,double,double,int))); + this,SLOT(UpdateLinkManager(std::string,int,double,double,double,int))); connect(mSlicerManagers.back(), SIGNAL(UpdateLinkedNavigation(std::string,vvSlicerManager*,vvSlicer*)), - this,SLOT(UpdateLinkedNavigation(std::string,vvSlicerManager*,vvSlicer*))); + this,SLOT(UpdateLinkedNavigation(std::string,vvSlicerManager*,vvSlicer*))); connect(mSlicerManagers.back(), SIGNAL(ChangeImageWithIndexOffset(vvSlicerManager*,int,int)), - this,SLOT(ChangeImageWithIndexOffset(vvSlicerManager*,int,int))); + this,SLOT(ChangeImageWithIndexOffset(vvSlicerManager*,int,int))); connect(mSlicerManagers.back(), SIGNAL(LandmarkAdded()),landmarksPanel,SLOT(AddPoint())); + + + + InitSlicers(); UpdateTree(); qApp->processEvents(); - InitSlicers(); - ShowLastImage(); InitDisplay(); + ShowLastImage(); qApp->processEvents(); - // End ImageInfoChanged(); return slicer_manager; @@ -3208,7 +3687,7 @@ vvSlicerManager* vvMainWindow::AddImage(vvImage::Pointer image,std::string filen //------------------------------------------------------------------------------ void vvMainWindow::UpdateCurrentSlicer() -{ +{ int index = -1; if (DataTree->selectedItems().size() > 0) { index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); @@ -3216,4 +3695,3 @@ void vvMainWindow::UpdateCurrentSlicer() mSlicerManagerCurrentIndex = index; } //------------------------------------------------------------------------------ -