From: rblanc Date: Tue, 15 Jan 2013 14:03:10 +0000 (+0100) Subject: Merge branch 'master' of git.creatis.insa-lyon.fr:clitk X-Git-Tag: v1.4.0~260^2 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=cf891024f9fed4d9ee3eabf13f2114a1d724df43;hp=e47bde8ac7d00b8980bf04fb60aa7925e5c42bfa;p=clitk.git Merge branch 'master' of git.creatis.insa-lyon.fr:clitk Conflicts: vv/vvMainWindow.cxx vv/vvMainWindow.h --- diff --git a/CMakeLists.txt b/CMakeLists.txt index ca68aa3..f64d0aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,11 @@ ENDIF(NOT DEFINED CLITK_SOURCE_DIR) SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) +IF(MSVC) + SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj" ) + SET( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /bigobj" ) +ENDIF(MSVC) + #========================================================= INCLUDE(${CLITK_SOURCE_DIR}/cmake/common.cmake) INCLUDE(${CLITK_SOURCE_DIR}/cmake/dependencies.cmake) diff --git a/common/clitkCommon.h b/common/clitkCommon.h index 9eb3652..8f9ce0f 100644 --- a/common/clitkCommon.h +++ b/common/clitkCommon.h @@ -40,6 +40,7 @@ # include #elif defined(_WIN32) # include +# include #endif //-------------------------------------------------------------------- diff --git a/common/rtkHndImageIO.cxx b/common/rtkHndImageIO.cxx index 8d59982..4791fd7 100644 --- a/common/rtkHndImageIO.cxx +++ b/common/rtkHndImageIO.cxx @@ -35,24 +35,24 @@ void rtk::HndImageIO::ReadImageInformation() size_t nelements = 0; nelements += fread ( (void *) hnd.sFileType, sizeof(char), 32, fp); - nelements += fread ( (void *) &hnd.FileLength, sizeof(uint32_t), 1, fp); + nelements += fread ( (void *) &hnd.FileLength, sizeof(itk::uint32_t), 1, fp); nelements += fread ( (void *) hnd.sChecksumSpec, sizeof(char), 4, fp); - nelements += fread ( (void *) &hnd.nCheckSum, sizeof(uint32_t), 1, fp); + nelements += fread ( (void *) &hnd.nCheckSum, sizeof(itk::uint32_t), 1, fp); nelements += fread ( (void *) hnd.sCreationDate, sizeof(char), 8, fp); nelements += fread ( (void *) hnd.sCreationTime, sizeof(char), 8, fp); nelements += fread ( (void *) hnd.sPatientID, sizeof(char), 16, fp); - nelements += fread ( (void *) &hnd.nPatientSer, sizeof(uint32_t), 1, fp); + nelements += fread ( (void *) &hnd.nPatientSer, sizeof(itk::uint32_t), 1, fp); nelements += fread ( (void *) hnd.sSeriesID, sizeof(char), 16, fp); - nelements += fread ( (void *) &hnd.nSeriesSer, sizeof(uint32_t), 1, fp); + nelements += fread ( (void *) &hnd.nSeriesSer, sizeof(itk::uint32_t), 1, fp); nelements += fread ( (void *) hnd.sSliceID, sizeof(char), 16, fp); - nelements += fread ( (void *) &hnd.nSliceSer, sizeof(uint32_t), 1, fp); - nelements += fread ( (void *) &hnd.SizeX, sizeof(uint32_t), 1, fp); - nelements += fread ( (void *) &hnd.SizeY, sizeof(uint32_t), 1, fp); + nelements += fread ( (void *) &hnd.nSliceSer, sizeof(itk::uint32_t), 1, fp); + nelements += fread ( (void *) &hnd.SizeX, sizeof(itk::uint32_t), 1, fp); + nelements += fread ( (void *) &hnd.SizeY, sizeof(itk::uint32_t), 1, fp); nelements += fread ( (void *) &hnd.dSliceZPos, sizeof(double), 1, fp); nelements += fread ( (void *) hnd.sModality, sizeof(char), 16, fp); - nelements += fread ( (void *) &hnd.nWindow, sizeof(uint32_t), 1, fp); - nelements += fread ( (void *) &hnd.nLevel, sizeof(uint32_t), 1, fp); - nelements += fread ( (void *) &hnd.nPixelOffset, sizeof(uint32_t), 1, fp); + nelements += fread ( (void *) &hnd.nWindow, sizeof(itk::uint32_t), 1, fp); + nelements += fread ( (void *) &hnd.nLevel, sizeof(itk::uint32_t), 1, fp); + nelements += fread ( (void *) &hnd.nPixelOffset, sizeof(itk::uint32_t), 1, fp); nelements += fread ( (void *) hnd.sImageType, sizeof(char), 4, fp); nelements += fread ( (void *) &hnd.dGantryRtn, sizeof(double), 1, fp); nelements += fread ( (void *) &hnd.dSAD, sizeof(double), 1, fp); @@ -95,7 +95,7 @@ void rtk::HndImageIO::ReadImageInformation() nelements += fread ( (void *) &hnd.dGating4DInfoZ, sizeof(double), 1, fp); nelements += fread ( (void *) &hnd.dGating4DInfoTime, sizeof(double), 1, fp); - if(nelements != /*char*/120 + /*uint32_t*/10 + /*double*/41) + if(nelements != /*char*/120 + /*itk::uint32_t*/10 + /*double*/41) itkGenericExceptionMacro(<< "Could not read header data in " << m_FileName); if(fclose (fp) != 0) @@ -133,16 +133,16 @@ void rtk::HndImageIO::Read(void * buffer) { FILE *fp; - uint32_t* buf = (uint32_t*)buffer; + itk::uint32_t* buf = (itk::uint32_t*)buffer; unsigned char *pt_lut; - uint32_t a; + itk::uint32_t a; unsigned char v; int lut_idx, lut_off; size_t num_read; char dc; short ds; long dl, diff=0; - uint32_t i; + itk::uint32_t i; fp = fopen (m_FileName.c_str(), "rb"); if (fp == NULL) @@ -160,13 +160,13 @@ void rtk::HndImageIO::Read(void * buffer) /* Read first row */ for (i = 0; i < GetDimensions(0); i++) { - if(1 != fread (&a, sizeof(uint32_t), 1, fp)) + if(1 != fread (&a, sizeof(itk::uint32_t), 1, fp)) itkGenericExceptionMacro(<< "Could not read first row in: " << m_FileName); buf[i] = a; } /* Read first pixel of second row */ - if(1 != fread (&a, sizeof(uint32_t), 1, fp)) + if(1 != fread (&a, sizeof(itk::uint32_t), 1, fp)) itkGenericExceptionMacro(<< "Could not read first pixel of second row"); buf[i++] = a; @@ -174,7 +174,7 @@ void rtk::HndImageIO::Read(void * buffer) lut_idx = 0; lut_off = 0; while (i < GetDimensions(0) * GetDimensions(1) ) { - uint32_t r11, r12, r21; + itk::uint32_t r11, r12, r21; r11 = buf[i-GetDimensions(0)-1]; r12 = buf[i-GetDimensions(0)]; @@ -211,7 +211,7 @@ void rtk::HndImageIO::Read(void * buffer) diff = ds; break; case 2: - num_read = fread (&dl, sizeof(uint32_t), 1, fp); + num_read = fread (&dl, sizeof(itk::uint32_t), 1, fp); if (num_read != 1) goto read_error; diff = dl; break; diff --git a/common/vvImageReader.cxx b/common/vvImageReader.cxx index c795cd9..f4f1a90 100644 --- a/common/vvImageReader.cxx +++ b/common/vvImageReader.cxx @@ -77,13 +77,13 @@ void vvImageReader::Update(int dim,std::string inputPixelType, LoadedImageType t switch(mDim) { case 2: UpdateWithDim<2>(mInputPixelType); - break;; + break; case 3: UpdateWithDim<3>(mInputPixelType); - break;; + break; case 4: UpdateWithDim<4>(mInputPixelType); - break;; + break; default: std::cerr << "dimension unknown in Update ! " << std::endl; } @@ -193,9 +193,21 @@ void vvImageReader::ReadMatImageTransform() } // TODO SR and BP: check on the list of transforms and not the first only - mImage->GetTransform()[0]->PostMultiply(); + mImage->GetTransform()[0]->PreMultiply(); mImage->GetTransform()[0]->Concatenate(matrix); mImage->GetTransform()[0]->Update(); + + //for image sequences, apply the transform to each images of the sequence + if (mImage->IsTimeSequence()) + { + for (unsigned i = 1 ; iGetTransform().size() ; i++) + { + mImage->GetTransform()[i]->PreMultiply(); + mImage->GetTransform()[i]->Concatenate(matrix); + mImage->GetTransform()[i]->Update(); + } + } + } } //------------------------------------------------------------------------------ diff --git a/fast_make.sh b/fast_make.sh old mode 100755 new mode 100644 diff --git a/make_meta.sh b/make_meta.sh old mode 100755 new mode 100644 diff --git a/make_new_tool.sh b/make_new_tool.sh old mode 100755 new mode 100644 diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 9df72e1..505c210 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -233,7 +233,7 @@ IF (CLITK_BUILD_TOOLS) IF(CLITK_EXPERIMENTAL) WRAP_GGO(clitkBinaryImageToMesh_GGO_C clitkBinaryImageToMesh.ggo) ADD_EXECUTABLE(clitkBinaryImageToMesh clitkBinaryImageToMesh.cxx ${clitkBinaryImageToMesh_GGO_C}) - TARGET_LINK_LIBRARIES(clitkBinaryImageToMesh itksys ${VTK_LIBRARIES}) + TARGET_LINK_LIBRARIES(clitkBinaryImageToMesh itksys ${ITK_LIBRARIES} ${VTK_LIBRARIES}) SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkBinaryImageToMesh) WRAP_GGO(clitkMeshToBinaryImage_GGO_C clitkMeshToBinaryImage.ggo) @@ -243,7 +243,7 @@ IF (CLITK_BUILD_TOOLS) WRAP_GGO(clitkMeshViewer_GGO_C clitkMeshViewer.ggo) ADD_EXECUTABLE(clitkMeshViewer clitkMeshViewer.cxx ${clitkMeshViewer_GGO_C}) - TARGET_LINK_LIBRARIES(clitkMeshViewer ${VTK_LIBRARIES}) + TARGET_LINK_LIBRARIES(clitkMeshViewer ${ITK_LIBRARIES} ${VTK_LIBRARIES}) SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMeshViewer) ENDIF(CLITK_EXPERIMENTAL) diff --git a/tools/make_new_tool.sh b/tools/make_new_tool.sh old mode 100755 new mode 100644 diff --git a/utilities/CxImage/CMakeLists.txt b/utilities/CxImage/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/vv/CMakeLists.txt b/vv/CMakeLists.txt index dbb360c..c37c3f6 100644 --- a/vv/CMakeLists.txt +++ b/vv/CMakeLists.txt @@ -251,7 +251,7 @@ ENDIF(UNIX OR APPLE) IF(WIN32) #INCLUDE(InstallRequiredSystemLibraries) - INSTALL(FILES ${EXECUTABLE_OUTPUT_PATH}/vv.exe DESTINATION .) + INSTALL(TARGETS vv DESTINATION bin) #INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/icons/ducky.png DESTINATION .) ENDIF(WIN32) #========================================================= diff --git a/vv/make_vv_class.sh b/vv/make_vv_class.sh old mode 100755 new mode 100644 diff --git a/vv/qt_ui/vvMainWindow.ui b/vv/qt_ui/vvMainWindow.ui index 8d3d8ff..07ddeb2 100644 --- a/vv/qt_ui/vvMainWindow.ui +++ b/vv/qt_ui/vvMainWindow.ui @@ -436,7 +436,7 @@ - 0 + 1 @@ -805,7 +805,7 @@ 0 0 1008 - 25 + 29 @@ -826,6 +826,7 @@ + @@ -1256,6 +1257,18 @@ true + + + + :/common/icons/rotateright.png:/common/icons/rotateright.png + + + Test / Fusion of US & CT sequences + + + true + + diff --git a/vv/qt_ui/vvOverlayPanel.ui b/vv/qt_ui/vvOverlayPanel.ui index dd7c83d..0e5a01f 100644 --- a/vv/qt_ui/vvOverlayPanel.ui +++ b/vv/qt_ui/vvOverlayPanel.ui @@ -6,8 +6,8 @@ 0 0 - 344 - 480 + 444 + 612 @@ -36,6 +36,134 @@ p, li { white-space: pre-wrap; } + + + + true + + + + 0 + 0 + + + + + 0 + 90 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + false + + + + 220 + 60 + 80 + 17 + + + + Temporal + + + + + + 220 + 10 + 61 + 17 + + + + Spatial + + + true + + + false + + + + + + 0 + 0 + 31 + 32 + + + + + + + :/common/icons/rotateright.png + + + + + + 30 + 0 + 171 + 32 + + + + Synchronized fusion of sequences + + + + + + 0 + 30 + 121 + 29 + + + + Browse fused sequence + + + + + + 130 + 36 + 151 + 20 + + + + Qt::Horizontal + + + + + + 20 + 60 + 131 + 23 + + + + Load Fused Seq. Signal + + + + diff --git a/vv/vv.cxx b/vv/vv.cxx index 2b20ac9..7506aa9 100644 --- a/vv/vv.cxx +++ b/vv/vv.cxx @@ -74,7 +74,7 @@ void open_sequence(vvMainWindow &window, std::vector &sequence_filenames, int n_image_loaded) { - const std::string open_mode_names[] = {"base", "overlay", "fusion", "vf", "contour"}; + const std::string open_mode_names[] = {"base", "overlay", "fusion", "vf", "contour", "fusionSequence"}; if(open_mode==O_BASE) window.LoadImages(sequence_filenames, vvImageReader::MERGEDWITHTIME); else if (open_mode==O_OVERLAY) diff --git a/vv/vvAnimatedGIFWriter.h b/vv/vvAnimatedGIFWriter.h index 2fde827..1baf2b9 100644 --- a/vv/vvAnimatedGIFWriter.h +++ b/vv/vvAnimatedGIFWriter.h @@ -8,7 +8,7 @@ class vtkImageAppend; -class VTK_IO_EXPORT vvAnimatedGIFWriter : public vtkGenericMovieWriter +class vvAnimatedGIFWriter : public vtkGenericMovieWriter //test this if link error... { public: static vvAnimatedGIFWriter *New(); diff --git a/vv/vvMainWindow.cxx b/vv/vvMainWindow.cxx index a44aadf..eb5fe7e 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 @@ -108,14 +108,14 @@ /*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() @@ -137,34 +137,34 @@ 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")); + tr("O&pen new Image")); actionOpen_new_image->setShortcut(QKeySequence(tr("Ctrl+O"))); 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); @@ -181,9 +181,15 @@ 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 @@ -193,9 +199,9 @@ vvMainWindow::vvMainWindow():vvMainWindowBase() // m->setObjectName(QString::fromUtf8("TOTOTO")); contextMenu.addMenu(m); QAction * a = m->addAction(QIcon(QString::fromUtf8(":/common/icons/GPSup.png")), - tr("BIDON")); + tr("BIDON")); QAction * b = m->addAction(QIcon(QString::fromUtf8(":/common/icons/GPSup.png")), - tr("BIDON2")); + tr("BIDON2")); m->addAction(a); m->addAction(b); connect(a,SIGNAL(triggered()),this,SLOT(AddFusionImage())); @@ -234,6 +240,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); @@ -281,10 +288,15 @@ 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())); connect(actionDocumentation,SIGNAL(triggered()),this,SLOT(ShowDocumentation())); connect(actionRegister_vv,SIGNAL(triggered()),this,SLOT(PopupRegisterForm())); + connect(overlayPanel, SIGNAL(FusionSequenceSignalButtonPressed()), this, SLOT(SelectFusionSequenceTemporalSignal())); + + /////////////////////////////////////////////// connect(actionSegmentation,SIGNAL(triggered()),this,SLOT(SegmentationOnCurrentImage())); connect(actionSurface_Viewer,SIGNAL(triggered()),this,SLOT(SurfaceViewerLaunch())); @@ -303,7 +315,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())); @@ -320,12 +332,16 @@ 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; playButton->setEnabled(0); @@ -362,6 +378,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase() //timerMemory->setInterval(5); connect(timerMemory, SIGNAL(timeout()), this, SLOT(UpdateMemoryUsage())); timerMemory->start(2000); + } //------------------------------------------------------------------------------ void vvMainWindow::show() @@ -414,7 +431,7 @@ 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); + mSlicerManagers[index]->GetImage()->GetVTKImages().size()-1,1,&ok); if (ok) { vvMidPosition midp; midp.slicer_manager = mSlicerManagers[index]; @@ -454,7 +471,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); @@ -506,25 +523,25 @@ 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(); + } } //------------------------------------------------------------------------------ @@ -567,7 +584,7 @@ void vvMainWindow::WarpImage() 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); + mSlicerManagers[index]->GetImage()->GetVTKImages().size()-1,1,&ok); if (ok) { WarpImage(mSlicerManagers[index],ref); } @@ -584,7 +601,7 @@ void vvMainWindow::WarpImage(vvSlicerManager* selected_slicer,int reference_phas 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"); @@ -636,7 +653,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) { @@ -658,14 +675,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) @@ -826,7 +843,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(); @@ -846,6 +862,7 @@ void vvMainWindow::LoadImages(std::vector files, vvImageReader::Loa else { SetImageSucceed = imageManager->SetImages(files,filetype, number); } + if (!SetImageSucceed) { QApplication::restoreOverrideCursor(); QString error = "Cannot open file \n"; @@ -872,7 +889,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); @@ -880,7 +897,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); @@ -894,34 +911,35 @@ 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++; } @@ -1020,6 +1038,7 @@ void vvMainWindow::ImageInfoChanged() 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); @@ -1035,9 +1054,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; } } @@ -1052,6 +1072,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); @@ -1080,6 +1101,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(); @@ -1103,7 +1128,7 @@ void vvMainWindow::ImageInfoChanged() NPixel *= inputSize[i]; } inputSizeInBytes = GetSizeInBytes(imageSelected->GetActualMemorySize()*1000); - + QString dim = QString::number(dimension) + " ("; dim += pixelType + ")"; @@ -1114,6 +1139,7 @@ void vvMainWindow::ImageInfoChanged() infoPanel->setOrigin(GetVectorDoubleAsString(origin)); infoPanel->setSpacing(GetVectorDoubleAsString(inputSpacing)); infoPanel->setNPixel(QString::number(NPixel)+" ("+inputSizeInBytes+")"); + transformation = imageSelected->GetTransform()[tSlice]->GetMatrix(); infoPanel->setTransformation(Get4x4MatrixDoubleAsString(transformation)); @@ -1151,13 +1177,14 @@ void vvMainWindow::ImageInfoChanged() // } // } 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); @@ -1167,7 +1194,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 { @@ -1250,7 +1277,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) { @@ -1280,12 +1307,12 @@ 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(); } } //------------------------------------------------------------------------------ @@ -1371,6 +1398,7 @@ 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(); @@ -1548,7 +1576,7 @@ void vvMainWindow::CloseImage(QTreeWidgetItem* item, int column) 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) { @@ -1556,10 +1584,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)); @@ -1570,7 +1613,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) { @@ -1580,7 +1623,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) { @@ -1593,8 +1636,27 @@ 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() ) { + //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); + } + + //TODO: also remove the image overlaid with the main sequence, as it is becoming invalid... + } + linkPanel->removeImage(index); mSlicerManagers[index]->RemoveActors(); + + //remove the slicer manager delete mSlicerManagers[index]; mSlicerManagers.erase(Manageriter); @@ -1620,17 +1682,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(); @@ -1668,6 +1737,9 @@ void vvMainWindow::FusionChanged(int visibility, double value) //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ +//called when AddOverlayImage, AddFusionSequence +//or when UpdateWindowLevel() is called ; when slicerManager emits WindowLevelChanged +//when ImageInfoChanged() is called void vvMainWindow::WindowLevelChanged() { // Base image @@ -1681,21 +1753,44 @@ 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); + } } //------------------------------------------------------------------------------ @@ -1814,7 +1909,6 @@ void vvMainWindow::UpdateLinkManager(std::string id, int slicer, double x, doubl { 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; @@ -1849,7 +1943,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); @@ -1892,17 +1986,17 @@ void vvMainWindow::SelectOverlayImage() return; } - QString Extensions = EXTENSIONS; - Extensions += ";;All Files (*)"; - QStringList files = QFileDialog::getOpenFileNames(this,tr("Load Overlay image"),mInputPathName,Extensions); - if (files.isEmpty()) - return; + QString Extensions = EXTENSIONS; + Extensions += ";;All Files (*)"; + QStringList files = QFileDialog::getOpenFileNames(this,tr("Load Overlay image"),mInputPathName,Extensions); + if (files.isEmpty()) + return; - std::vector vecFileNames; - for (int i = 0; i < files.size(); i++) { - vecFileNames.push_back(files[i].toStdString()); - } - AddOverlayImage(index,vecFileNames,vvImageReader::IMAGE); + std::vector vecFileNames; + for (int i = 0; i < files.size(); i++) { + vecFileNames.push_back(files[i].toStdString()); + } + AddOverlayImage(index,vecFileNames,vvImageReader::IMAGE); } //------------------------------------------------------------------------------ @@ -1914,7 +2008,7 @@ void vvMainWindow::AddOverlayImage(int index, std::vector fileNames { 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()); @@ -1946,7 +2040,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); @@ -1954,7 +2048,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); @@ -1998,12 +2092,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(); @@ -2020,19 +2114,20 @@ void vvMainWindow::SelectFusionImage() //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 ( (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "fusion") || + (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "fusionSequence") ) { + 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; } - QString Extensions = EXTENSIONS; - Extensions += ";;All Files (*)"; - QString file = QFileDialog::getOpenFileName(this,tr("Load Fusion image"),mInputPathName,Extensions); - if (!file.isEmpty()) - AddFusionImage(index,file); + QString Extensions = EXTENSIONS; + Extensions += ";;All Files (*)"; + QString file = QFileDialog::getOpenFileName(this,tr("Load Fusion image"),mInputPathName,Extensions); + if (!file.isEmpty()) + AddFusionImage(index,file); } //------------------------------------------------------------------------------ @@ -2053,7 +2148,7 @@ void vvMainWindow::AddFusionImage(int index, QString 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(file.toStdString().c_str()); reader->ReadImageInformation(); std::string component = reader->GetComponentTypeAsString(reader->GetComponentType()); @@ -2064,50 +2159,50 @@ void vvMainWindow::AddFusionImage(int index, QString file) 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(); - - for (int j = 1; j <= 4; j++) { - item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole)); - } + 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(); + + 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)), + //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)), + 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); - - //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(); + 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(); } else { QApplication::restoreOverrideCursor(); QString error = "Cannot import the new image.\n"; @@ -2147,16 +2242,16 @@ void vvMainWindow::OpenField() return; } - QString Extensions = "Images ( *.mhd)"; - 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); + QString Extensions = "Images ( *.mhd)"; + 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); } //------------------------------------------------------------------------------ @@ -2185,7 +2280,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); @@ -2194,7 +2289,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); @@ -2313,6 +2408,289 @@ 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]); + //check if one overlay image is already associated + for (int child = 0; child < DataTree->topLevelItem(index)->childCount(); child++) + if ( (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "fusion") || + (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "fusionSequence") ) { + 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; + } + + 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::SelectFusionSequenceTemporalSignal() { + + //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; + 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 + std::vector signal; + //...TODO, look for itk functions that can do that... vnl in the worst case. + signal.push_back(1);signal.push_back(2); + + //TODO: instead: if the loaded signal is longer, just crop it... + //this allows loading only the first few frames when testing. + //->maybe raise a message that this behavior may be unsafe... + + //if compatible with the fused image sequence (number of images = number of entries), enable the temporalSync + if ( signal.size() >= mSlicerManagers[index]->GetFusionSequenceNbFrames()) { + //for convenience, associate this sequence to both the current slicer manager, and to the linked one + mSlicerManagers[index]->SetFusionSequenceTemporalSignal(signal); + mSlicerManagers[ mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager() ]->SetFusionSequenceTemporalSignal(signal); + overlayPanel->enableFusionSequenceTemporalSync(); + QMessageBox::information(this,tr("Adding signal"),"would add the signal from file: "+ fileName); + } + else {//else, send a message to signal the failure... + QString error = "The provided signal doesn't have the same duration as the sequence\n"; + error += "Ignoring file: " + fileName; + QMessageBox::information(this,tr("Problem adding signal!"),error); + return; + } + +} +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +//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); + 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(); + 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 identiy + for (unsigned i=0 ; iGetImage()->GetTransform().size() ; i++) { + 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 + //TODO: add the temporal synchronisation stuff + //if the button is checked, get the phase of the requested US frame from the available signal + //and select the corresponding one in the CT. (check the one just before, and the one just after, and select the closest) + + //TODO: do it also the other way around, when modifying the time index related to CT, select a close frame + //this should not be done here directly, but the code should be inspired from the one here + //->find a good US frame such that when calling this function with this US frame, it produces the expected result + + + //TODO: select the right CT image to display + int mainSequenceFrameIndex=0; + //estimate the TSlice to set to the CT + + //and set it! + mSlicerManagers[index]->SetTSlice(mainSequenceFrameIndex, false); + } + + + //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() { @@ -2360,50 +2738,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()) @@ -2422,10 +2800,10 @@ 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()); } //------------------------------------------------------------------------------ @@ -2442,10 +2820,10 @@ 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()); } //------------------------------------------------------------------------------ @@ -2461,7 +2839,7 @@ void vvMainWindow::ReadSavedStateFile(const std::string& stateFile) //------------------------------------------------------------------------------ void vvMainWindow::LinkAllImages() { - linkPanel->linkAll(); + linkPanel->linkAll(); } //------------------------------------------------------------------------------ @@ -2472,7 +2850,7 @@ void vvMainWindow::AddLink(QString image1,QString image2,bool fromPanel) linkPanel->addLinkFromIds(image1, image2); return; } - + unsigned int sm1 = 0; unsigned int sm2 = 0; @@ -2529,15 +2907,32 @@ 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=mSlicerManagers[mSlicerManagers[i]->GetFusionSequenceIndexOfLinkedManager()]->GetFusionSequenceFrameIndex(); + int estimatedValue=0; + //TODO: if temporal sync is active + //estimate a corresponding time index for the secondary (US) sequence, and update it accordingly. + //estimatedValue = ... + 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; @@ -2552,7 +2947,7 @@ void vvMainWindow::NOHorizontalSliderMoved() { // if (mCurrentTime == NOHorizontalSlider->value()) return; HorizontalSliderMoved(NOHorizontalSlider->value(),COLUMN_UL_VIEW,0); -// mCurrentTime = NOHorizontalSlider->value(); + // mCurrentTime = NOHorizontalSlider->value(); } //------------------------------------------------------------------------------ @@ -2562,7 +2957,7 @@ void vvMainWindow::NEHorizontalSliderMoved() { // if (mCurrentTime == NEHorizontalSlider->value()) return; HorizontalSliderMoved(NEHorizontalSlider->value(),COLUMN_UR_VIEW,1); -// mCurrentTime = NEHorizontalSlider->value(); + // mCurrentTime = NEHorizontalSlider->value(); } //------------------------------------------------------------------------------ @@ -2683,8 +3078,8 @@ 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); @@ -2706,19 +3101,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; } @@ -2799,9 +3212,9 @@ 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; iSetMagnification(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); @@ -2854,9 +3267,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(); @@ -2897,13 +3310,13 @@ 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); + 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); + tr("Number of loops (0 means infinite):"), 0, 0, 1000000000, 1, &ok); if(ok) gif->SetLoops(loops); @@ -2922,7 +3335,7 @@ void vvMainWindow::SaveScreenshot(QVTKWidget *widget) mpg->SetQuality(2); bool ok; int fps = QInputDialog::getInteger(this, tr("Number of frames per second"), - tr("FPS:"), 5, 0, 1024, 1, &ok); + tr("FPS:"), 5, 0, 1024, 1, &ok); if(!ok) fps = 5; mpg->SetRate(fps); @@ -2935,7 +3348,7 @@ void vvMainWindow::SaveScreenshot(QVTKWidget *widget) mpg->SetQuality(2); bool ok; int fps = QInputDialog::getInteger(this, tr("Number of frames per second"), - tr("FPS:"), 5, 0, 1024, 1, &ok); + tr("FPS:"), 5, 0, 1024, 1, &ok); if(!ok) fps = 5; mpg->SetRate(fps); @@ -3024,11 +3437,11 @@ 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())); + } } } //------------------------------------------------------------------------------ @@ -3042,11 +3455,11 @@ void vvMainWindow::PlayNext() 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())); } } //------------------------------------------------------------------------------ @@ -3103,8 +3516,8 @@ int vvMainWindow::GetImageDuplicateFilenameNumber(std::string filename) 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; @@ -3141,7 +3554,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 +3562,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,37 +3574,41 @@ 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())); + + UpdateTree(); qApp->processEvents(); InitSlicers(); diff --git a/vv/vvMainWindow.h b/vv/vvMainWindow.h index a15ff8b..15ec687 100644 --- a/vv/vvMainWindow.h +++ b/vv/vvMainWindow.h @@ -57,6 +57,10 @@ class vvMainWindow: public vvMainWindowBase, void AddOverlayImage(int index, std::vector fileNames, vvImageReader::LoadedImageType type); void AddFusionImage(int index, QString filename); void AddROI(int index, QString filename); + + //Process the sequence for fusion: + void AddFusionSequence(int index, std::vector fileNames, vvImageReader::LoadedImageType type); + void AddLandmarks(int index, std::vector); ///Adds a mesh to a SlicerManager, with optional warping by vector field void AddContour(int image_index, vvMesh::Pointer contour, bool propagation); @@ -108,12 +112,13 @@ public slots: void VectorChanged(int visibility, double x, double y, double z, double value); void OverlayChanged(int visibility, double valueOver, double valueRef); void FusionChanged(int visibility, double value); + //void FusionSequenceChanged(int visibility, double value); void SegmentationOnCurrentImage(); void SurfaceViewerLaunch(); void WindowLevelChanged(); void UpdateSlice(int slicer, int slice); - void UpdateTSlice(int slicer, int slice); + void UpdateTSlice(int slicer, int slice, int code=-1); void UpdateSliceRange(int slicer, int min, int max, int tmin, int tmax); void WindowLevelEdited(); void SetWindowLevel(double w, double l); @@ -154,11 +159,16 @@ public slots: void OpenField(); void SelectOverlayImage(); void SelectFusionImage(); + //select the file(s) from the disk containing the image sequence to fuse + void SelectFusionSequence(); + void SelectFusionSequenceTemporalSignal(); + void ResetTransformationToIdentity(); void SetVFProperty(int subsampling,int scale,int lut, int width, double r, double g, double b); void SetOverlayProperty(int color, int linked, double window, double level); void SetFusionProperty(int opacity, int tresOpacity, int colormap,double window,double level, bool showLegend); + void SetFusionSequenceProperty(int fusionSequenceFrameIndex, bool spatialSyncFlag, unsigned int fusionSequenceNbFrames, bool temporalSyncFlag); void GoToCursor(); void GoToLandmark(); @@ -200,7 +210,7 @@ private: QString GetSizeInBytes(unsigned long size); QString GetVectorDoubleAsString(std::vector vectorDouble); QString GetVectorIntAsString(std::vector vectorInt); - int GetSlicerIndexFromItem(QTreeWidgetItem* item); + int GetSlicerIndexFromItem(QTreeWidgetItem* item); //this actually returns the SlicerManager index TODO: rename it to GetSlicerManagerIndexFromItem QTreeWidgetItem* GetItemFromSlicerManager(vvSlicerManager* sm); void SaveScreenshot(QVTKWidget *widget); int GetImageDuplicateFilenameNumber(std::string filename); diff --git a/vv/vvOverlayPanel.cxx b/vv/vvOverlayPanel.cxx index 346bd2c..649f1fd 100644 --- a/vv/vvOverlayPanel.cxx +++ b/vv/vvOverlayPanel.cxx @@ -29,17 +29,21 @@ //==================================================================== vvOverlayPanel::vvOverlayPanel(QWidget * parent):QWidget(parent) { + disableFusionSignals = true; + disableFusionSequenceSignals = true; + setupUi(this); vFFrame->hide(); compareFrame->hide(); fusionFrame->hide(); + fCTUSFrame->hide(); subSamplingSpinBox->setEnabled(0); scaleSpinBox->setEnabled(0); lutCheckBox->hide(); lutCheckBox->setEnabled(0); fusionShowLegendCheckBox->setChecked(false); - + connect(subSamplingSpinBox,SIGNAL(editingFinished()),this,SLOT(setVFProperty())); connect(scaleSpinBox,SIGNAL(editingFinished()),this,SLOT(setVFProperty())); connect(lutCheckBox,SIGNAL(clicked()),this,SLOT(setVFProperty())); @@ -58,7 +62,10 @@ vvOverlayPanel::vvOverlayPanel(QWidget * parent):QWidget(parent) connect(overlayLevelSpinBox,SIGNAL(valueChanged(double)),this,SLOT(setOverlayProperty())); connect(overlayLinkCheckBox,SIGNAL(stateChanged(int)),this,SLOT(setOverlayProperty())); - disableFusionSignals = false; + connect(fCTUSSlider,SIGNAL(valueChanged(int)),this,SLOT(setFusionSequenceProperty())); + connect(fCTUSActivateSpaceSyncCheckBox,SIGNAL(stateChanged(int)),this,SLOT(setFusionSequenceProperty())); + connect(fCTUSActivateTimeSyncCheckBox,SIGNAL(stateChanged(int)),this,SLOT(setFusionSequenceProperty())); + connect(fCTUSLoadSignalPushButton,SIGNAL(clicked()),this,SIGNAL(FusionSequenceSignalButtonPressed())); } void vvOverlayPanel::getCurrentImageName(QString name) @@ -225,7 +232,7 @@ void vvOverlayPanel::setFusionProperty() { if (disableFusionSignals) return; - + fusionOpacitySpin->setValue(opacityHorizontalSlider->value()); fusionThresSpin->setValue(thresOpacityHorizontalSlider->value()); @@ -248,6 +255,68 @@ void vvOverlayPanel::getCurrentFusionInfo(int visibility,double value) valueFusionnedLabel->setText(fusionValue); } + +void vvOverlayPanel::getFusionSequenceProperty(int sequenceFrameIndex, bool spatialSync, unsigned int sequenceLenth, bool temporalSync) +{ + if (sequenceFrameIndex > -1) { + disableFusionSequenceSignals = true; + fCTUSFrame->show(); + fCTUSFrame->setEnabled(1); + fCTUSSlider->setEnabled(1); + fCTUSSlider->setValue(sequenceFrameIndex); + fCTUSSlider->setMaximum(sequenceLenth); + if (spatialSync) fCTUSActivateSpaceSyncCheckBox->setCheckState(Qt::Checked); + else fCTUSActivateSpaceSyncCheckBox->setCheckState(Qt::Unchecked); + if (fCTUSActivateTimeSyncCheckBox->isEnabled()) { + if ( temporalSync ) fCTUSActivateTimeSyncCheckBox->setCheckState(Qt::Checked); + else fCTUSActivateTimeSyncCheckBox->setCheckState(Qt::Unchecked); + } + disableFusionSequenceSignals = false; + setFusionSequenceProperty(); + } else { + disableFusionSequenceSignals = true; + fCTUSFrame->hide(); + fCTUSFrame->setEnabled(0); + fCTUSSlider->setEnabled(0); + fCTUSSlider->setValue(0); + fCTUSSlider->setMaximum(0); + fCTUSActivateSpaceSyncCheckBox->setCheckState(Qt::Unchecked); + fCTUSActivateTimeSyncCheckBox->setCheckState(Qt::Unchecked); + disableFusionSequenceSignals = false; + setFusionSequenceProperty(); + } +} + + +void vvOverlayPanel::setFusionSequenceProperty() +{ + if (disableFusionSequenceSignals) + return; + emit FusionSequencePropertyUpdated(fCTUSSlider->value(), fCTUSActivateSpaceSyncCheckBox->isChecked(), fCTUSSlider->maximum(), fCTUSActivateTimeSyncCheckBox->isChecked()); +} + +void vvOverlayPanel::enableFusionSequenceTemporalSync() { + bool backup = disableFusionSequenceSignals; + disableFusionSequenceSignals=true; //not sure this is necessary, but just in case... + fCTUSActivateTimeSyncCheckBox->setEnabled(1); + fCTUSActivateTimeSyncCheckBox->setChecked(true); + disableFusionSequenceSignals = backup; // + + if (disableFusionSequenceSignals) return; + emit FusionSequencePropertyUpdated(fCTUSSlider->value(), fCTUSActivateSpaceSyncCheckBox->isChecked(), fCTUSSlider->maximum(), fCTUSActivateTimeSyncCheckBox->isChecked()); +} + +void vvOverlayPanel::updateFusionSequenceSliderValueFromWindow(int val, bool updateVisualization) { + if (fCTUSSlider->value()==val) return; + + disableFusionSequenceSignals = true; //not sure this is necessary, but just in case... + fCTUSSlider->setValue(val); + disableFusionSequenceSignals = false; + + if (disableFusionSequenceSignals) return; + if (updateVisualization) emit FusionSequencePropertyUpdated(fCTUSSlider->value(), fCTUSActivateSpaceSyncCheckBox->isChecked(), fCTUSSlider->maximum(), fCTUSActivateTimeSyncCheckBox->isChecked()); +} + void vvOverlayPanel::VFColorChangeRequest() { QColor color(vfColorButton->palette().color(QPalette::Background)); diff --git a/vv/vvOverlayPanel.h b/vv/vvOverlayPanel.h index bd9e972..b0e69db 100644 --- a/vv/vvOverlayPanel.h +++ b/vv/vvOverlayPanel.h @@ -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 ===========================================================================**/ #ifndef _vvOverlayPanel_H #define _vvOverlayPanel_H @@ -26,46 +26,54 @@ class vvOverlayPanel : public QWidget, private Ui::vvOverlayPanel { - Q_OBJECT + Q_OBJECT public: - // constructor - destructor - vvOverlayPanel(QWidget * parent=0); - ~vvOverlayPanel() {} + // constructor - destructor + vvOverlayPanel(QWidget * parent=0); + ~vvOverlayPanel() {} - void getCurrentImageName(QString name); + void getCurrentImageName(QString name); - void getVFProperty(int subsampling, int scale, int log); - void getVFName(QString name); + void getVFProperty(int subsampling, int scale, int log); + void getVFName(QString name); - void getOverlayProperty(int color, int linked, double window, double level); - void getOverlayName(QString name); + void getOverlayProperty(int color, int linked, double window, double level); + void getOverlayName(QString name); - void getFusionProperty(int opacity, int thresOpacity, int colormap, double window, double level); - void getFusionName(QString name); + void getFusionProperty(int opacity, int thresOpacity, int colormap, double window, double level); + void getFusionName(QString name); - void getCurrentVectorInfo(int visibility, double x, double y, double z, double value); - void getCurrentOverlayInfo(int visibility,double valueOver, double valueRef); - void getCurrentFusionInfo(int visibility,double value); - - bool getShowLegend(); + void getFusionSequenceProperty(int sequenceFrameIndex, bool spatialSync, unsigned int sequenceLength, bool temporalSync); + + void getCurrentVectorInfo(int visibility, double x, double y, double z, double value); + void getCurrentOverlayInfo(int visibility,double valueOver, double valueRef); + void getCurrentFusionInfo(int visibility,double value); + + bool getShowLegend(); + + void updateFusionSequenceSliderValueFromWindow(int val, bool updateVisualization); public slots: - void setVFProperty(); - void setOverlayProperty(); - void setFusionProperty(); - void setFusionSpinProperty(); - void VFColorChangeRequest(); + void setVFProperty(); + void setOverlayProperty(); + void setFusionProperty(); + void setFusionSpinProperty(); + void VFColorChangeRequest(); + void setFusionSequenceProperty(); + void enableFusionSequenceTemporalSync(); signals: - void VFPropertyUpdated(int subsampling, int scale, int log, int width, double r, double g, double b); - void OverlayPropertyUpdated(int color, int linked, double window, double level); - void FusionPropertyUpdated(int opacity, int thresOpacity, int colormap, double window, double level, bool showLegend); + void VFPropertyUpdated(int subsampling, int scale, int log, int width, double r, double g, double b); + void OverlayPropertyUpdated(int color, int linked, double window, double level); + void FusionPropertyUpdated(int opacity, int thresOpacity, int colormap, double window, double level, bool showLegend); + void FusionSequencePropertyUpdated(int sequenceFrameIndex, bool spatialSync, unsigned int sequenceLength, bool temporalSync); + void FusionSequenceSignalButtonPressed(); - private: - bool disableFusionSignals; - + bool disableFusionSignals; + bool disableFusionSequenceSignals; + }; // end class vvOverlayPanel //==================================================================== diff --git a/vv/vvSlicer.cxx b/vv/vvSlicer.cxx index fd5240b..efaf80f 100644 --- a/vv/vvSlicer.cxx +++ b/vv/vvSlicer.cxx @@ -16,6 +16,9 @@ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html ===========================================================================**/ +#include +#include + #include "vvSlicer.h" #include "vvImage.h" #include "vvSlicerManagerCommand.h" @@ -78,6 +81,7 @@ static void copyExtent(int* in, int* to){ //------------------------------------------------------------------------------ vvSlicer::vvSlicer() { + mFusionSequenceCode = -1; this->UnInstallPipeline(); mImage = NULL; mReducedExtent = new int[6]; @@ -308,7 +312,7 @@ void vvSlicer::SetCurrentPosition(double x, double y, double z, int t) mCurrentBeforeSlicingTransform[1]=y; mCurrentBeforeSlicingTransform[2]=z; mSlicingTransform->GetInverse()->TransformPoint(mCurrentBeforeSlicingTransform,mCurrent); - SetTSlice(t); + if (t>=0) SetTSlice(t); } //------------------------------------------------------------------------------ @@ -411,8 +415,9 @@ void vvSlicer::SetOverlay(vvImage::Pointer overlay) //------------------------------------------------------------------------------ -void vvSlicer::SetFusion(vvImage::Pointer fusion) +void vvSlicer::SetFusion(vvImage::Pointer fusion, int fusionSequenceCode) { + mFusionSequenceCode = fusionSequenceCode; if (fusion->GetVTKImages().size()) { mFusion = fusion; @@ -475,7 +480,7 @@ bool vvSlicer::GetActorVisibility(const std::string& actor_type, int overlay_ind else if (actor_type == "overlay") { vis = this->mOverlayActor->GetVisibility(); } - else if (actor_type == "fusion") { + else if ( (actor_type == "fusion") || (actor_type == "fusionSequence") ){ vis = this->mFusionActor->GetVisibility(); } else if (actor_type == "contour") @@ -497,7 +502,7 @@ void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_ind else if (actor_type == "overlay") { this->mOverlayActor->SetVisibility(vis); } - else if (actor_type == "fusion") { + else if ( (actor_type == "fusion") || (actor_type == "fusionSequence") ){ this->mFusionActor->SetVisibility(vis); } else if (actor_type == "contour") @@ -641,7 +646,7 @@ void vvSlicer::RemoveActor(const std::string& actor_type, int overlay_index) mOverlayActor = NULL; mOverlayMapper = NULL; } - if (actor_type == "fusion") { + if ( (actor_type == "fusion") || (actor_type == "fusionSequence") ) { Renderer->RemoveActor(mFusionActor); mFusion = NULL; mFusionActor = NULL; @@ -706,8 +711,19 @@ void vvSlicer::SetVFLog(int log) //------------------------------------------------------------------------------ -void vvSlicer::SetTSlice(int t) +void vvSlicer::SetTSlice(int t, bool updateLinkedImages) { + if (!updateLinkedImages) { + mCurrentTSlice = t; + mImageReslice->SetInput( mImage->GetVTKImages()[mCurrentTSlice] ); + // Update transform + mConcatenatedTransform->Identity(); + mConcatenatedTransform->Concatenate(mImage->GetTransform()[mCurrentTSlice]); + mConcatenatedTransform->Concatenate(mSlicingTransform); + UpdateDisplayExtent(); + return; + } + if (t < 0) mCurrentTSlice = 0; else if ((unsigned int)t >= mImage->GetVTKImages().size()) @@ -726,6 +742,7 @@ void vvSlicer::SetTSlice(int t) if (mVF->GetVTKImages().size() > (unsigned int)mCurrentTSlice) mVOIFilter->SetInput(mVF->GetVTKImages()[mCurrentTSlice]); } + //update the overlay if (mOverlay && mOverlayActor->GetVisibility()) { if (mOverlay->GetVTKImages().size() > (unsigned int)t) { mCurrentOverlayTSlice = t; @@ -737,7 +754,8 @@ void vvSlicer::SetTSlice(int t) mConcatenatedOverlayTransform->Concatenate(mSlicingTransform); } } - if (mFusion && mFusionActor->GetVisibility()) { + //update the fusion ; except in case this is a fusionSequence, in which case both 'times' should be independent. + if (mFusion && mFusionActor->GetVisibility() && (mFusionSequenceCode<0)) { if (mFusion->GetVTKImages().size() > (unsigned int)t) { mCurrentFusionTSlice = t; mFusionReslice->SetInput( mFusion->GetVTKImages()[mCurrentFusionTSlice]); @@ -757,6 +775,25 @@ void vvSlicer::SetTSlice(int t) //------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +void vvSlicer::SetFusionSequenceTSlice(int t) +{ + if (mFusion && mFusionActor->GetVisibility() && (mFusionSequenceCode>=0)) { + if (mFusion->GetVTKImages().size() > (unsigned int)t) { + mCurrentFusionTSlice = t; + mFusionReslice->SetInput( mFusion->GetVTKImages()[mCurrentFusionTSlice] ); + // Update fusion transform + mConcatenatedFusionTransform->Identity(); + mConcatenatedFusionTransform->Concatenate(mFusion->GetTransform()[mCurrentFusionTSlice]); //not really useful... + mConcatenatedFusionTransform->Concatenate(mSlicingTransform); + } + } + + UpdateDisplayExtent(); +} +//------------------------------------------------------------------------------ + + //------------------------------------------------------------------------------ int vvSlicer::GetTSlice() { @@ -770,7 +807,7 @@ int vvSlicer::GetMaxCurrentTSlice() int t = mCurrentTSlice; if(mOverlay) t = std::max(t, mCurrentOverlayTSlice); - if(mFusion) + if(mFusion&& (mFusionSequenceCode<0)) //ignore fusionSequence data: for these, the times are not to be related (this way) t = std::max(t, mCurrentFusionTSlice); return t; } @@ -1008,7 +1045,6 @@ void vvSlicer::UpdateDisplayExtent() } } } - } //---------------------------------------------------------------------------- @@ -1147,9 +1183,8 @@ void vvSlicer::ResetCamera() //---------------------------------------------------------------------------- void vvSlicer::SetDisplayMode(bool i) { - this->GetRenderer()->SetDraw(i); - if (i) - UpdateDisplayExtent(); + this->GetRenderer()->SetDraw(i); + if (i) UpdateDisplayExtent(); } //---------------------------------------------------------------------------- @@ -1324,6 +1359,7 @@ double vvSlicer::GetScalarComponentAsDouble(vtkImageData *image, double X, doubl ix = lrint(X); iy = lrint(Y); iz = lrint(Z); + if (ix < image->GetWholeExtent()[0] || ix > image->GetWholeExtent()[1] || iy < image->GetWholeExtent()[2] || diff --git a/vv/vvSlicer.h b/vv/vvSlicer.h index a738a78..7746331 100644 --- a/vv/vvSlicer.h +++ b/vv/vvSlicer.h @@ -20,6 +20,9 @@ #include #include +#include //TODO delete +#include + #include "vvLandmarks.h" #include "vvImage.h" #include "vvMesh.h" @@ -78,7 +81,7 @@ public: vtkActor* GetVFActor() ; vtkCornerAnnotation* GetAnnotation(); - void SetFusion(vvImage::Pointer inputFusion); + void SetFusion(vvImage::Pointer inputFusion, int fusionSequenceCode = -1); vvImage::Pointer GetFusion() { return mFusion; } @@ -97,7 +100,10 @@ public: } void SetLandmarks(vvLandmarks* landmarks); - void SetTSlice(int t); + void SetTSlice(int t, bool updateLinkedImages = true); + + void SetFusionSequenceTSlice(int t); + void SetSliceOrientation(int orientation); void AdjustResliceToSliceOrientation(vtkImageReslice *reslice); int GetTSlice(); @@ -200,6 +206,8 @@ public: } void SetVFColor(double r, double g, double b); + //necessary to flag the secondary sequence + void SetFusionSequenceCode(int code) {mFusionSequenceCode=code;} protected: vvSlicer(); ~vvSlicer(); @@ -212,6 +220,8 @@ protected: vvLandmarks* mLandmarks; + int mFusionSequenceCode; //-1: not involved in a fusion sequence, 0: main sequence (CT), 1: secondary sequence (US) + // __________ Image coordinates accounting for spacing and origin // Λ Λ // | | vvImage.GetTransform() diff --git a/vv/vvSlicerManager.cxx b/vv/vvSlicerManager.cxx index b175c46..67f78bc 100644 --- a/vv/vvSlicerManager.cxx +++ b/vv/vvSlicerManager.cxx @@ -1,1408 +1,1554 @@ -/*========================================================================= - 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://oncora1.lyon.fnclcc.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. - - 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 - ======================================================================-====*/ - -#include "vvSlicerManager.h" -#include "vvSlicer.h" -#include "vvImage.h" -#include "vvSlicerManagerCommand.h" -#include "vvInteractorStyleNavigator.h" -#include "vvLandmarks.h" -#include "vvMesh.h" -#include "vvBlendImageActor.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -//---------------------------------------------------------------------------- -vvSlicerManager::vvSlicerManager(int numberOfSlicers) -{ - mFileName = ""; - mId = ""; - mVFName = ""; - mOverlayName = ""; - mFusionName = ""; - mVFId = ""; - mLastError = ""; - mType = vvImageReader::UNDEFINEDIMAGETYPE; - mColorMap = 0; - mPreset = 0; - mOverlayColor = 130; - - mFusionOpacity = 30; - mFusionThresOpacity = 1; - mFusionColorMap = 3; - mFusionWindow = 1000; - mFusionLevel = 1000; - mFusionShowLegend = true; - - mLandmarks = NULL; - mLinkedId.resize(0); - - for ( int i = 0; i < numberOfSlicers; i++) - mSlicers.push_back(vtkSmartPointer::New()); - mSelectedSlicer = -1; - - mPreviousSlice.resize(numberOfSlicers); - mPreviousTSlice.resize(numberOfSlicers); - mSlicingPreset = WORLD_SLICING; -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -vvSlicerManager::~vvSlicerManager() -{ - if (mLandmarks) - delete mLandmarks; -} -//---------------------------------------------------------------------------- - - -//------------------------------------------------------------------------------ -void vvSlicerManager::SetFilename(std::string filename, int number) -{ - mFileName = filename; - mFileName = vtksys::SystemTools::GetFilenameName(mFileName); - mBaseFileName = vtksys::SystemTools::GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(mFileName)); - mBaseFileNameNumber = number; - - mFileName = mBaseFileName; - if (number != 0) { - mFileName.append("_"+clitk::toString(number)); - } - mFileName.append(vtksys::SystemTools::GetFilenameLastExtension(filename)); - - for(unsigned int i=0; iSetFileName(mFileName);//vtksys::SystemTools::GetFilenameWithoutLastExtension(filename)); - } - -} -//------------------------------------------------------------------------------ - - -//---------------------------------------------------------------------------- -void vvSlicerManager::AddContour(vvMesh::Pointer contour,bool propagate) -{ - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->AddContour(contour,propagate); - } -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::ToggleContourSuperposition() -{ - for ( unsigned int i = 0; i < mSlicers.size(); i++) - mSlicers[i]->ToggleContourSuperposition(); -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -std::string vvSlicerManager::GetListOfAbsoluteFilePathInOneString(const std::string &actorType) -{ - vvImageReader *reader = NULL; - - if(actorType=="image") - reader = mReader; - else if(actorType=="overlay") - reader = mOverlayReader; - else if(actorType=="fusion") - reader = mFusionReader; - else if(actorType=="vector") - reader = mVectorReader; - - if(!reader) - return ""; - - std::string list; - for(unsigned int i=0; iGetInputFilenames().size(); i++){ - QFileInfo fileinfo(reader->GetInputFilenames()[i].c_str()); //Do not show the path - if(i) - list += '\n'; - list += fileinfo.absoluteFilePath().toStdString(); - } - return list; -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -bool vvSlicerManager::SetImage(std::string filename, vvImageReader::LoadedImageType type, int n, unsigned int slice) -{ - mType = type; - if (mReader.IsNull()) - mReader = vvImageReader::New(); - std::vector filenames; - filenames.push_back(filename); - mReader->SetInputFilenames(filenames); - mReader->SetSlice(slice); // Only used for SLICED type - mReader->Update(type); - - SetFilename(filename, n); - // mFileName = vtksys::SystemTools::GetFilenameName(mFileName); - //mBaseFileName = vtksys::SystemTools::GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(mFileName)); - //mBaseFileNameNumber = n; - - if (mReader->GetLastError().size() == 0) { - mImage=mReader->GetOutput(); - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->SetFileName(vtksys::SystemTools::GetFilenameWithoutLastExtension(filename)); - mSlicers[i]->SetImage(mReader->GetOutput()); - } - } else { - mLastError = mReader->GetLastError(); - return false; - } - // if (n!=0) { - // mFileName.append("_"+clitk::toString(n)); - // } - return true; -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetImage(vvImage::Pointer image) -{ - mImage=image; - for (unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->SetImage(image); - } -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -bool vvSlicerManager::SetImages(std::vector filenames, vvImageReader::LoadedImageType type, int n) -{ - mType = type; - std::string fileWithoutExtension = vtksys::SystemTools::GetFilenameWithoutExtension(filenames[0]); - if (type == vvImageReader::DICOM) - fileWithoutExtension += "_dicom"; - else if (type == vvImageReader::MERGED) - fileWithoutExtension += "_merged"; - else if (type == vvImageReader::MERGEDWITHTIME) - fileWithoutExtension += "_merged_wt"; - - mFileName = vtksys::SystemTools::GetFilenameName(mFileName); - mFileName = fileWithoutExtension + vtksys::SystemTools::GetFilenameExtension(filenames[0]); - if (mReader.IsNull()) - mReader = vvImageReader::New(); - mReader->SetInputFilenames(filenames); - mReader->Update(type); - - mBaseFileName = vtksys::SystemTools::GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(mFileName)); - mBaseFileNameNumber = n; - - if (mReader->GetLastError().size() == 0) { - mImage=mReader->GetOutput(); - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->SetFileName(fileWithoutExtension); - mSlicers[i]->SetImage(mReader->GetOutput()); - } - } else { - mLastError = mReader->GetLastError(); - return false; - } - if (n!=0) { - mFileName.append("_"+clitk::toString(n)); - } - return true; -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -bool vvSlicerManager::SetOverlay(std::vector filenames,int dim, std::string component, vvImageReader::LoadedImageType type) -{ - mOverlayName = filenames[0]; - mOverlayComponent = component; - if (dim > mImage->GetNumberOfDimensions()) { - mLastError = " Overlay dimension cannot be greater than reference image!"; - return false; - } - if (mOverlayReader.IsNull()) - mOverlayReader = vvImageReader::New(); - mOverlayReader->SetInputFilenames(filenames); - mOverlayReader->Update(type); - if (mOverlayReader->GetLastError().size() == 0) { - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->SetOverlay(mOverlayReader->GetOutput()); - } - } else { - mLastError = mOverlayReader->GetLastError(); - return false; - } - return true; -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -bool vvSlicerManager::SetFusion(std::string filename,int dim, std::string component) -{ - mFusionName = filename; - mFusionComponent = component; - if (dim > mImage->GetNumberOfDimensions()) { - mLastError = " Overlay dimension cannot be greater then reference image!"; - return false; - } - if (mFusionReader.IsNull()) - mFusionReader = vvImageReader::New(); - std::vector filenames; - filenames.push_back(filename); - mFusionReader->SetInputFilenames(filenames); - mFusionReader->Update(mImage->GetNumberOfDimensions(),component.c_str(),mType); - if (mFusionReader->GetLastError().size() == 0) { - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->SetFusion(mFusionReader->GetOutput()); - } - } else { - mLastError = mFusionReader->GetLastError(); - return false; - } - double *fusRange = mFusionReader->GetOutput()->GetVTKImages()[0]->GetScalarRange(); - mFusionLevel = (fusRange[0]+fusRange[1])/2; - mFusionWindow = fusRange[1]-fusRange[0]; - - return true; -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -bool vvSlicerManager::SetVF(std::string filename) -{ - if (mVectorReader.IsNull()) - mVectorReader = vvImageReader::New(); - mVectorReader->SetInputFilename(filename); - - if (mType == vvImageReader::IMAGEWITHTIME) - mVectorReader->Update(vvImageReader::VECTORFIELDWITHTIME); - else - mVectorReader->Update(vvImageReader::VECTORFIELD); - if (mVectorReader->GetLastError().size() != 0) { - mLastError = mVectorReader->GetLastError(); - return false; - } else - return SetVF(mVectorReader->GetOutput(),filename); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -bool vvSlicerManager::SetVF(vvImage::Pointer vf,std::string filename) -{ - if (vf->GetNumberOfDimensions() > mImage->GetNumberOfDimensions()) { - mLastError = "Sorry, vector field dimension cannot be greater then reference image."; - return false; - } - if (vf->GetNumberOfDimensions() == 4) { - if (vf->GetSpacing()[3] != mImage->GetSpacing()[3]) { - mLastError = "Sorry, vector field time spacing cannot be different from time spacing of the reference image."; - return false; - } - if (vf->GetOrigin()[3] != mImage->GetOrigin()[3]) { - mLastError = "Sorry, vector field time origin cannot be different from time origin of the reference image."; - return false; - } - } - mVF=vf; - mVFName = filename; - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->SetVF(vf); - } - return true; -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -vvSlicer* vvSlicerManager::GetSlicer(int i) -{ - return mSlicers[i]; -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::UpdateSlicer(int num, bool state) -{ - if (mSlicers[num]->GetImage()) - mSlicers[num]->SetDisplayMode(state); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetSlicerWindow(int i, vtkRenderWindow* RW) -{ - mSlicers[i]->SetRenderWindow(i,RW); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetInteractorStyleNavigator(int i, vtkInteractorStyle* style) -{ - vvSlicerManagerCommand *smc = vvSlicerManagerCommand::New(); - smc->SM = this; - smc->SetSlicerNumber(i); - mSlicers[i]->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style); - - mSlicers[i]->GetRenderWindow()->GetInteractor()-> - GetInteractorStyle()->AddObserver(vtkCommand::KeyPressEvent, smc); - mSlicers[i]->GetRenderWindow()->GetInteractor()-> - GetInteractorStyle()->AddObserver(vtkCommand::WindowLevelEvent, smc); - mSlicers[i]->GetRenderWindow()->GetInteractor()-> - GetInteractorStyle()->AddObserver(vtkCommand::EndWindowLevelEvent, smc); - mSlicers[i]->GetRenderWindow()->GetInteractor()-> - GetInteractorStyle()->AddObserver(vtkCommand::StartWindowLevelEvent, smc); - mSlicers[i]->GetRenderWindow()->GetInteractor()-> - GetInteractorStyle()->AddObserver(vtkCommand::PickEvent, smc); - mSlicers[i]->GetRenderWindow()->GetInteractor()-> - GetInteractorStyle()->AddObserver(vtkCommand::StartPickEvent, smc); - mSlicers[i]->GetRenderWindow()->GetInteractor()-> - GetInteractorStyle()->AddObserver(vtkCommand::LeaveEvent, smc); - mSlicers[i]->GetRenderWindow()->GetInteractor()-> - GetInteractorStyle()->AddObserver(vtkCommand::UserEvent, smc); - mSlicers[i]->GetRenderWindow()->GetInteractor()-> - GetInteractorStyle()->AddObserver(vtkCommand::MouseWheelForwardEvent, smc); - mSlicers[i]->GetRenderWindow()->GetInteractor()-> - GetInteractorStyle()->AddObserver(vtkCommand::MouseWheelBackwardEvent, smc); - // mSlicers[i]->GetRenderWindow()->GetInteractor()-> - // GetInteractorStyle()->AddObserver(vtkCommand::LeftButtonReleaseEvent, smc); - mSlicers[i]->GetRenderWindow()->GetInteractor()-> - GetInteractorStyle()->AddObserver(vtkCommand::EndPickEvent, smc); - mSlicers[i]->GetRenderWindow()->GetInteractor()-> - GetInteractorStyle()->AddObserver(vtkCommand::EndInteractionEvent, smc); - smc->Delete(); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::LeftButtonReleaseEvent(int slicer) -{ - emit LeftButtonReleaseSignal(slicer); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::EmitMousePositionUpdated(int slicer) -{ - emit MousePositionUpdatedSignal(slicer); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::EmitKeyPressed(std::string KeyPress) -{ - emit KeyPressedSignal(KeyPress); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetSliceOrientation(int slicer, int orientation) -{ - mSlicers[slicer]->SetSliceOrientation(orientation); - emit UpdateOrientation(slicer, orientation); -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -int vvSlicerManager::GetTSlice() -{ - return mSlicers[0]->GetTSlice(); -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetTSlice(int slice) -{ - if (slice < 0) - slice = 0; - else if (slice > mSlicers[0]->GetTMax()) - slice = mSlicers[0]->GetTMax(); - if (mLandmarks) - mLandmarks->SetTime(slice); - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - if (slice != mSlicers[i]->GetMaxCurrentTSlice()) { - mSlicers[i]->SetTSlice(slice); - UpdateTSlice(i); - } - } -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetNextTSlice(int originating_slicer) -{ - int t = mSlicers[0]->GetMaxCurrentTSlice(); - t++; - if (t > mSlicers[0]->GetTMax()) - t = 0; - //std::cout << "vvSlicerManager::SetNextTSlice" << std::endl; - emit UpdateTSlice(originating_slicer,t); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetPreviousTSlice(int originating_slicer) -{ - int t = mSlicers[0]->GetMaxCurrentTSlice(); - t--; - if (t < 0) - t = mSlicers[0]->GetTMax(); - //std::cout << "vvSlicerManager::SetPreviousTSlice" << std::endl; - emit UpdateTSlice(originating_slicer,t); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::ToggleInterpolation() -{ - bool interpolate=!(mSlicers[0]->GetImageActor()->GetInterpolate()); - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->GetImageActor()->SetInterpolate(interpolate); - if (mSlicers[i]->GetOverlayActor()) - mSlicers[i]->GetOverlayActor()->SetInterpolate(interpolate); - if (mSlicers[i]->GetFusionActor()) - mSlicers[i]->GetFusionActor()->SetInterpolate(interpolate); - } -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetTSliceInSlicer(int tslice, int slicer) -{ - if (tslice < 0) - tslice = 0; - else if (tslice > mSlicers[slicer]->GetTMax()) - tslice = mSlicers[slicer]->GetTMax(); - if (mLandmarks) - mLandmarks->SetTime(tslice); - - if (mSlicers[slicer]->GetMaxCurrentTSlice() == tslice) return; - - mSlicers[slicer]->SetTSlice(tslice); - - if(mSlicingPreset==VOXELS_SLICING) { - vtkMatrix4x4 *imageTransformInverse = vtkMatrix4x4::New(); - mImage->GetTransform()[mSlicers[slicer]->GetTSlice()]->GetInverse(imageTransformInverse); - this->GetSlicer(slicer)->GetSlicingTransform()->SetMatrix(imageTransformInverse); - imageTransformInverse->Delete(); - } - - UpdateTSlice(slicer); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetColorWindow(double s) -{ - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->SetColorWindow(s); - } -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetColorLevel(double s) -{ - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->SetColorLevel(s); - } -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetOverlayColorWindow(double s) -{ - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->SetOverlayColorWindow(s); - } -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetOverlayColorLevel(double s) -{ - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->SetOverlayColorLevel(s); - } -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetLinkOverlayWindowLevel(bool b) -{ - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->SetLinkOverlayWindowLevel(b); - } -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetCursorAndCornerAnnotationVisibility(int s) -{ - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->SetCursorVisibility(s); - mSlicers[i]->SetCornerAnnotationVisibility(s); - } -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetOpacity(int i, double factor) -{ - mSlicers[i]->SetOpacity(1/factor); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::UpdateViews(int current,int slicer) -{ - double p[3], pt[3]; - p[0] = mSlicers[slicer]->GetCurrentPosition()[0]; - p[1] = mSlicers[slicer]->GetCurrentPosition()[1]; - p[2] = mSlicers[slicer]->GetCurrentPosition()[2]; - mSlicers[slicer]->GetSlicingTransform()->GetInverse()->TransformPoint(p, pt); - - double x = (pt[0] - mSlicers[slicer]->GetInput()->GetOrigin()[0]) - /mSlicers[slicer]->GetInput()->GetSpacing()[0]; - double y = (pt[1] - mSlicers[slicer]->GetInput()->GetOrigin()[1]) - /mSlicers[slicer]->GetInput()->GetSpacing()[1]; - double z = (pt[2] - mSlicers[slicer]->GetInput()->GetOrigin()[2]) - /mSlicers[slicer]->GetInput()->GetSpacing()[2]; - - if (x >= mSlicers[slicer]->GetInput()->GetWholeExtent()[0]-0.5 && - x <= mSlicers[slicer]->GetInput()->GetWholeExtent()[1]+0.5 && - y >= mSlicers[slicer]->GetInput()->GetWholeExtent()[2]-0.5 && - y <= mSlicers[slicer]->GetInput()->GetWholeExtent()[3]+0.5 && - z >= mSlicers[slicer]->GetInput()->GetWholeExtent()[4]-0.5 && - z <= mSlicers[slicer]->GetInput()->GetWholeExtent()[5]+0.5) { - mSlicers[slicer]->UpdateCursorPosition(); - mSlicers[slicer]->SetCursorColor(10,212,255); - mSelectedSlicer = slicer; - - switch (mSlicers[slicer]->GetSliceOrientation()) { - case vtkImageViewer2::SLICE_ORIENTATION_XY: - if (mSlicers[slicer]->GetSlice() != (int)lrint(z)) - mSlicers[slicer]->SetSlice((int)lrint(z)); - break; - - case vtkImageViewer2::SLICE_ORIENTATION_XZ: - if (mSlicers[slicer]->GetSlice() != (int)lrint(y)) - mSlicers[slicer]->SetSlice((int)lrint(y)); - break; - - case vtkImageViewer2::SLICE_ORIENTATION_YZ: - if (mSlicers[slicer]->GetSlice() != (int)lrint(x)) - mSlicers[slicer]->SetSlice((int)lrint(x)); - break; - } - mSlicers[slicer]->Render(); - - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - if (i != (unsigned int)slicer - && mSlicers[i]->GetRenderer()->GetDraw() - && mSlicers[i]->GetRenderWindow()->GetSize()[0] > 2 - && mSlicers[i]->GetRenderWindow()->GetSize()[1] > 2) { - mSlicers[i]->SetCurrentPosition(p[0], p[1], p[2], mSlicers[slicer]->GetMaxCurrentTSlice()); - mSlicers[i]->UpdateCursorPosition(); - if (current) { //do not display corner annotation if image is the one picked - mSlicers[i]->SetCurrentPosition(-VTK_DOUBLE_MAX,-VTK_DOUBLE_MAX, - -VTK_DOUBLE_MAX, mSlicers[slicer]->GetMaxCurrentTSlice()); - mSlicers[i]->SetCursorColor(255,10,212); - } else { - mSlicers[i]->SetCursorColor(150,10,282); - } - switch (mSlicers[i]->GetSliceOrientation()) { - case vtkImageViewer2::SLICE_ORIENTATION_XY: - if (mSlicers[i]->GetSlice() != (int)lrint(z)) - mSlicers[i]->SetSlice((int)lrint(z)); - break; - - case vtkImageViewer2::SLICE_ORIENTATION_XZ: - if (mSlicers[i]->GetSlice() != (int)lrint(y)) - mSlicers[i]->SetSlice((int)lrint(y)); - break; - - case vtkImageViewer2::SLICE_ORIENTATION_YZ: - if (mSlicers[i]->GetSlice() != (int)lrint(x)) - mSlicers[i]->SetSlice((int)lrint(x)); - break; - } - - mSlicers[i]->Render(); - - UpdateSlice(i); - UpdateTSlice(i); - } - } - } -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::UpdateLinked(int slicer) -{ - double p[3], pt[3]; - p[0] = mSlicers[slicer]->GetCurrentPosition()[0]; - p[1] = mSlicers[slicer]->GetCurrentPosition()[1]; - p[2] = mSlicers[slicer]->GetCurrentPosition()[2]; - mSlicers[slicer]->GetSlicingTransform()->GetInverse()->TransformPoint(p, pt); - double x = (pt[0] - mSlicers[slicer]->GetInput()->GetOrigin()[0]) / mSlicers[slicer]->GetInput()->GetSpacing()[0]; - double y = (pt[1] - mSlicers[slicer]->GetInput()->GetOrigin()[1]) / mSlicers[slicer]->GetInput()->GetSpacing()[1]; - double z = (pt[2] - mSlicers[slicer]->GetInput()->GetOrigin()[2]) / mSlicers[slicer]->GetInput()->GetSpacing()[2]; - - if (x >= mSlicers[slicer]->GetInput()->GetWholeExtent()[0]-0.5 && - x <= mSlicers[slicer]->GetInput()->GetWholeExtent()[1]+0.5 && - y >= mSlicers[slicer]->GetInput()->GetWholeExtent()[2]-0.5 && - y <= mSlicers[slicer]->GetInput()->GetWholeExtent()[3]+0.5 && - z >= mSlicers[slicer]->GetInput()->GetWholeExtent()[4]-0.5 && - z <= mSlicers[slicer]->GetInput()->GetWholeExtent()[5]+0.5) { - for (std::list::const_iterator i = mLinkedId.begin(); i != mLinkedId.end(); i++) { - emit UpdateLinkManager(*i, slicer, p[0], p[1], p[2], mSlicers[slicer]->GetMaxCurrentTSlice()); - } - } -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -void vvSlicerManager::UpdateLinkedNavigation(vvSlicer *refSlicer, bool bPropagate) -{ - vtkCamera *refCam = refSlicer->GetRenderer()->GetActiveCamera(); - - double refPosition[3]; - refCam->GetPosition(refPosition); - refPosition[refSlicer->GetSliceOrientation()] = refSlicer->GetSlice() * - refSlicer->GetInput()->GetSpacing()[refSlicer->GetSliceOrientation()] + - refSlicer->GetInput()->GetOrigin()[refSlicer->GetSliceOrientation()]; - - refSlicer->GetSlicingTransform()->TransformPoint(refPosition, refPosition); - mSlicers[0]->GetSlicingTransform()->GetInverse()->TransformPoint(refPosition, refPosition); - - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - vtkCamera *camera = mSlicers[i]->GetRenderer()->GetActiveCamera(); - camera->SetParallelScale(refCam->GetParallelScale()); - - double position[3], focal[3]; - camera->GetPosition(position); - camera->GetFocalPoint(focal); - - for(int j=0; j<3; j++) { - if(j!=mSlicers[i]->GetSliceOrientation()) { - position[j] = refPosition[j]; - focal[j] = refPosition[j]; - } - } - - camera->SetFocalPoint(focal); - camera->SetPosition(position); - - //Fix for bug #243 - mSlicers[i]->ForceUpdateDisplayExtent(); - } - - Render(); - if(bPropagate) - for (std::list::const_iterator i = mLinkedId.begin(); i != mLinkedId.end(); i++) - emit UpdateLinkedNavigation(*i, this, refSlicer); -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -double vvSlicerManager::GetColorWindow() const -{ - if (mSlicers.size()) - return mSlicers[0]->GetColorWindow(); - return -1; -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -double vvSlicerManager::GetColorLevel() const -{ - if (mSlicers.size()) - return mSlicers[0]->GetColorLevel(); - return -1; -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -double vvSlicerManager::GetOverlayColorWindow() const -{ - if (mSlicers.size()) - return mSlicers[0]->GetOverlayColorWindow(); - return -1; -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -double vvSlicerManager::GetOverlayColorLevel() const -{ - if (mSlicers.size()) - return mSlicers[0]->GetOverlayColorLevel(); - return -1; -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -bool vvSlicerManager::GetLinkOverlayWindowLevel() const -{ - if (mSlicers.size()) - return mSlicers[0]->GetLinkOverlayWindowLevel(); - return -1; -} -//---------------------------------------------------------------------------- - -//------------------------------------------------------------------------------ -void vvSlicerManager::ResetTransformationToIdentity(const std::string actorType) -{ - if(actorType == "image") - for(unsigned int i=0; iGetImage()->GetTransform().size(); i++) - this->GetImage()->GetTransform()[i]->Identity(); - else if(actorType == "overlay") - for(unsigned int i=0; iGetImage()->GetTransform().size(); i++) - this->GetSlicer(0)->GetOverlay()->GetTransform()[i]->Identity(); - else if(actorType == "fusion") - for(unsigned int i=0; iGetImage()->GetTransform().size(); i++) - this->GetSlicer(0)->GetFusion()->GetTransform()[i]->Identity(); - else if(actorType == "vf") - for(unsigned int i=0; iGetImage()->GetTransform().size(); i++) - this->GetVF()->GetTransform()[i]->Identity(); - else - return; - - for(int i=0; i< this->GetNumberOfSlicers(); i++){ - this->GetSlicer(i)->ForceUpdateDisplayExtent(); - this->GetSlicer(i)->ResetCamera(); - this->GetSlicer(i)->Render(); - } -} -//------------------------------------------------------------------------------ - -//---------------------------------------------------------------------------- -void vvSlicerManager::Render() -{ - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->Render(); - } -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::GenerateDefaultLookupTable() -{ - SetPreset(mPreset); - SetColorMap(mColorMap); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::Reload() -{ - mReader->Update(mType); - mImage=mReader->GetOutput(); - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->SetImage(mImage); - } -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::ReloadFusion() -{ - mFusionReader->Update(mImage->GetNumberOfDimensions(),mFusionComponent.c_str(),mType); - - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->SetFusion(mFusionReader->GetOutput()); - mSlicers[i]->Render(); - } -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::ReloadOverlay() -{ - mOverlayReader->Update(mImage->GetNumberOfDimensions(),mOverlayComponent.c_str(),mType); - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->SetOverlay(mOverlayReader->GetOutput()); - mSlicers[i]->Render(); - } -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::ReloadVF() -{ - mVectorReader->Update(vvImageReader::VECTORFIELD); //deletes the old images through the VF::Init() function - mVF=mVectorReader->GetOutput(); - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->SetVF(mVF); - mSlicers[i]->Render(); - } -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::RemoveActor(const std::string& actor_type, int overlay_index) -{ - if (actor_type =="overlay") - mOverlayReader = NULL; - - if (actor_type =="fusion") - mFusionReader = NULL; - - for (unsigned int i = 0; i < mSlicers.size(); i++) - mSlicers[i]->RemoveActor(actor_type,overlay_index); - - if (actor_type=="vector") { - mVF=NULL; - mVectorReader=NULL; - } -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::RemoveActors() -{ - ///This method leaks a few objects. See RemoveActor for what a - ///correct implementation would look like - //DS -> probably due to the reader (now released in the - //RemoveActor() function. (I hope) - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - mSlicers[i]->SetDisplayMode(0); - mSlicers[i]->GetRenderer()->RemoveActor(mSlicers[i]->GetImageActor()); - } -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::UpdateInfoOnCursorPosition(int slicer) -{ - // int view = mSlicers[slicer]->GetSliceOrientation(); - // int slice = mSlicers[slicer]->GetSlice(); - double x = mSlicers[slicer]->GetCursorPosition()[0]; - double y = mSlicers[slicer]->GetCursorPosition()[1]; - double z = mSlicers[slicer]->GetCursorPosition()[2]; - double X = (x - mSlicers[slicer]->GetInput()->GetOrigin()[0])/ - mSlicers[slicer]->GetInput()->GetSpacing()[0]; - double Y = (y - mSlicers[slicer]->GetInput()->GetOrigin()[1])/ - mSlicers[slicer]->GetInput()->GetSpacing()[1]; - double Z = (z - mSlicers[slicer]->GetInput()->GetOrigin()[2])/ - mSlicers[slicer]->GetInput()->GetSpacing()[2]; - double value = -VTK_DOUBLE_MAX; - int displayVec = 0; - double xVec=0, yVec=0, zVec=0, valueVec=0; - int displayOver = 0; - int displayFus = 0; - double valueOver=0, valueFus=0; - if (X >= mSlicers[slicer]->GetInput()->GetWholeExtent()[0] && - X <= mSlicers[slicer]->GetInput()->GetWholeExtent()[1] && - Y >= mSlicers[slicer]->GetInput()->GetWholeExtent()[2] && - Y <= mSlicers[slicer]->GetInput()->GetWholeExtent()[3] && - Z >= mSlicers[slicer]->GetInput()->GetWholeExtent()[4] && - Z <= mSlicers[slicer]->GetInput()->GetWholeExtent()[5]) { - value = this->GetScalarComponentAsDouble(mSlicers[slicer]->GetInput(), X, Y, Z); - - if (mSlicers[slicer]->GetVFActor() ) { - displayVec = 1; - unsigned int currentTime = mSlicers[slicer]->GetMaxCurrentTSlice(); - vtkImageData *vf = NULL; - - if (mSlicers[slicer]->GetVF()->GetVTKImages().size() > currentTime) - vf = mSlicers[slicer]->GetVF()->GetVTKImages()[currentTime]; - else - vf = mSlicers[slicer]->GetVF()->GetVTKImages()[0]; - - if (vf) { - double Xvf = (x - vf->GetOrigin()[0])/ vf->GetSpacing()[0]; - double Yvf = (y - vf->GetOrigin()[1])/ vf->GetSpacing()[1]; - double Zvf = (z - vf->GetOrigin()[2])/ vf->GetSpacing()[2]; - xVec = this->GetScalarComponentAsDouble( vf, Xvf, Yvf, Zvf, 0); - yVec = this->GetScalarComponentAsDouble( vf, Xvf, Yvf, Zvf, 1); - zVec = this->GetScalarComponentAsDouble( vf, Xvf, Yvf, Zvf, 2); - valueVec = sqrt(xVec*xVec + yVec*yVec + zVec*zVec); - } - } - if (mSlicers[slicer]->GetOverlayActor() ) { - displayOver = 1; - vtkImageData *overlay = dynamic_cast(mSlicers[slicer]->GetOverlayMapper()->GetInput()); - double Xover = (x - overlay->GetOrigin()[0]) / overlay->GetSpacing()[0]; - double Yover = (y - overlay->GetOrigin()[1]) / overlay->GetSpacing()[1]; - double Zover = (z - overlay->GetOrigin()[2]) / overlay->GetSpacing()[2]; - valueOver = this->GetScalarComponentAsDouble(overlay, Xover, Yover, Zover); - } - if (mSlicers[slicer]->GetFusionActor() ) { - displayFus = 1; - vtkImageData *fusion = dynamic_cast(mSlicers[slicer]->GetFusionMapper()->GetInput()); - double Xover = (x - fusion->GetOrigin()[0]) / fusion->GetSpacing()[0]; - double Yover = (y - fusion->GetOrigin()[1]) / fusion->GetSpacing()[1]; - double Zover = (z - fusion->GetOrigin()[2]) / fusion->GetSpacing()[2]; - valueFus = this->GetScalarComponentAsDouble(fusion, Xover, Yover, Zover); - } - emit UpdatePosition(mSlicers[slicer]->GetCursorVisibility(), - x,y,z,X,Y,Z,value); - emit UpdateVector(displayVec,xVec, yVec, zVec, valueVec); - emit UpdateOverlay(displayOver,valueOver,value); - emit UpdateFusion(displayFus,valueFus); - } -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::Activated() -{ - emit currentImageChanged(mId); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::Picked() -{ - emit currentPickedImageChanged(mId); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::UpdateWindowLevel() -{ - emit WindowLevelChanged(); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::UpdateSlice(int slicer) -{ - if (mPreviousSlice[slicer] == mSlicers[slicer]->GetSlice()) { - //DD("============= NOTHING"); - return; - } - //std::cout << "vvSlicerManager::UpdateSlice " << slicer << " " << mSlicers[slicer]->GetSlice() << std::endl; - emit UpdateSlice(slicer, mSlicers[slicer]->GetSlice()); - mSlicers[slicer]->Render(); // DS <-- I add this, this could/must be the only Render ... - mPreviousSlice[slicer] = mSlicers[slicer]->GetSlice(); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::UpdateTSlice(int slicer) -{ - int slice = mSlicers[slicer]->GetSlice(); - int tslice = mSlicers[slicer]->GetMaxCurrentTSlice(); - if (mPreviousSlice[slicer] == slice) { - if (mPreviousTSlice[slicer] == tslice) { - // DD("************** NOTHING ***********"); - return; - } - } - mPreviousSlice[slicer] = slice; - mPreviousTSlice[slicer] = tslice; - //std::cout << "vvSlicerManager::UpdateTSlice " << slicer << " " << tslice << std::endl; - emit UpdateTSlice(slicer, tslice); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::UpdateSliceRange(int slicer) -{ - emit UpdateSliceRange(slicer, - mSlicers[slicer]->GetSliceRange()[0], mSlicers[slicer]->GetSliceRange()[1], - 0,mSlicers[slicer]->GetTMax()); -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetSlicingPreset(SlicingPresetType preset) -{ - if(mSlicingPreset==preset) - return; - - vtkMatrix4x4 *imageTransformInverse = vtkMatrix4x4::New(); - mImage->GetTransform()[this->GetTSlice()]->GetInverse(imageTransformInverse); - - for(int i=0; i< this->GetNumberOfSlicers(); i++){ - vvSlicer *s = this->GetSlicer(i); - switch(preset) - { - case WORLD_SLICING: - s->GetSlicingTransform()->Identity(); - break; - case VOXELS_SLICING: - s->GetSlicingTransform()->SetMatrix(imageTransformInverse); - break; - default: - imageTransformInverse->Delete(); - return; - } - s->ForceUpdateDisplayExtent(); - s->SetSlice((s->GetInput()->GetWholeExtent()[s->GetSliceOrientation()*2+1] - +s->GetInput()->GetWholeExtent()[s->GetSliceOrientation()*2])/2.0); - s->ResetCamera(); - s->Render(); - } - - imageTransformInverse->Delete(); - mSlicingPreset = preset; -} - -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetPreset(int preset) -{ - //vtkLookupTable* LUT = static_cast(mSlicers[0]->GetWindowLevel()->GetLookupTable()); - double window = mSlicers[0]->GetColorWindow(); - double level = mSlicers[0]->GetColorLevel(); - - std::string component_type=mImage->GetScalarTypeAsITKString(); - switch (preset) { - case 0: - double range[2]; - mImage->GetScalarRange(range); - window = range[1] - range[0]; - level = (range[1] + range[0])* 0.5; - break; - case 1: - window = 2000; - level = 0; - break; - case 2: - window = 400; - level = 20; - break; - case 3: // lungs (same as FOCAL) - window = 1700; - level = -300; - break; - case 4: - window = 1000; - level = 500; - break; - case 5: - window = 1; - level = 0.5; - break; - case 6: - break; - case 7: - window=1.; - level=0.; - break; - } - mPreset = preset; - this->SetColorWindow(window); - this->SetColorLevel(level); - - //if (LUT) - //{ - // SetColorMap(-1); - //} -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetLocalColorWindowing(const int slicer, const bool bCtrlKey) -{ - double min, max; - if(bCtrlKey && this->mSlicers[slicer]->GetFusion()) { - int t = mSlicers[slicer]->GetFusionTSlice(); - this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, - this->mSlicers[slicer]->GetFusion()->GetVTKImages()[t], - this->mSlicers[slicer]->GetConcatenatedFusionTransform()); - this->SetFusionWindow(max-min); - this->SetFusionLevel(0.5*(min+max)); - this->SetColorMap(mColorMap); - } - else if(bCtrlKey && this->mSlicers[slicer]->GetOverlay()) { - int t = mSlicers[slicer]->GetOverlayTSlice(); - this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, - this->mSlicers[slicer]->GetOverlay()->GetVTKImages()[t], - this->mSlicers[slicer]->GetConcatenatedOverlayTransform()); - if(this->mSlicers[slicer]->GetLinkOverlayWindowLevel()){ - this->SetColorWindow(max-min); - this->SetColorLevel(0.5*(min+max)); - } else { - this->SetOverlayColorWindow(max-min); - this->SetOverlayColorLevel(0.5*(min+max)); - } - } - else { - int t = this->GetTSlice(); - this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, - this->mSlicers[slicer]->GetImage()->GetVTKImages()[t], - this->mSlicers[slicer]->GetConcatenatedTransform()); - this->SetColorWindow(max-min); - this->SetColorLevel(0.5*(min+max)); - this->SetPreset(6); - } - this->Render(); - this->UpdateWindowLevel(); -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::SetColorMap(int colormap) -{ - double range[2]; - range[0] = mSlicers[0]->GetInput()->GetScalarRange()[0]; - range[1] = mSlicers[0]->GetInput()->GetScalarRange()[1]; - - double window = mSlicers[0]->GetWindowLevel()->GetWindow(); - double level = mSlicers[0]->GetWindowLevel()->GetLevel(); - - vtkLookupTable* LUT = static_cast(mSlicers[0]->GetWindowLevel()->GetLookupTable()); - switch (colormap) { - case -1: - break; - case 0: - LUT = NULL; - break; - case 1: - if (LUT == NULL) - LUT = vtkLookupTable::New(); - LUT->SetValueRange(0,1); - LUT->SetSaturationRange(1,1); - LUT->SetHueRange(0,0.18); - break; - case 2: - if (LUT == NULL) - LUT = vtkLookupTable::New(); - LUT->SetValueRange(0,1); - LUT->SetSaturationRange(1,1); - LUT->SetHueRange(0.4,0.80); - break; - case 3: - if (LUT == NULL) - LUT = vtkLookupTable::New(); - LUT->SetValueRange(0.5,1); - LUT->SetSaturationRange(1,1); - LUT->SetHueRange(0.666,0); - break; - case 4: - if (LUT == NULL) - LUT = vtkLookupTable::New(); - LUT->SetValueRange(1,1); - LUT->SetSaturationRange(1,1); - LUT->SetHueRange(0,1); - LUT->SetAlphaRange(1, 1); - break; - case 5: - if (LUT == NULL) - LUT = vtkLookupTable::New(); - LUT->SetValueRange(1,1); - LUT->SetSaturationRange(1,1); - LUT->SetHueRange(1,0.1); - //LUT->SetRampToLinear(); - break; - } - if (LUT) { - LUT->SetTableRange(level-fabs(window)/2,level+fabs(window)/2); - LUT->Build(); - } - vtkWindowLevelLookupTable* fusLUT = NULL; - if (mSlicers[0]->GetFusion()) { // && mFusionColorMap >= 0) { - fusLUT = vtkWindowLevelLookupTable::New(); - double fusRange [2]; - fusRange[0] = mFusionLevel - mFusionWindow/2; - fusRange[1] = mFusionLevel + mFusionWindow/2; - double* frange = mFusionReader->GetOutput()->GetVTKImages()[0]->GetScalarRange(); - fusLUT->SetTableRange(frange); - fusLUT->SetValueRange(1,1); - fusLUT->SetSaturationRange(1,1); - fusLUT->SetAlphaRange(1, 1); - fusLUT->SetWindow(mFusionWindow); - fusLUT->SetLevel(mFusionLevel); - if (mFusionColorMap == 1) - fusLUT->SetHueRange(0,0.18); - else if (mFusionColorMap == 2) - fusLUT->SetHueRange(0.4,0.80); - else if (mFusionColorMap == 3) - { - fusLUT->SetHueRange(0.666, 0); - fusLUT->SetValueRange(0.5, 1); - } - else if (mFusionColorMap == 4) - fusLUT->SetHueRange(0,1); - else if (mFusionColorMap <= 0) - { - fusLUT->SetValueRange(0,1); - fusLUT->SetSaturationRange(0,0); - } - - fusLUT->ForceBuild(); - double v[4]; - - // set color table transparency - //double alpha_range=(double)mFusionThresOpacity/10; - double range_end = fusRange[0] + (double)mFusionThresOpacity*(fusRange[1] - fusRange[0])/100; - double curr_value = fusRange[0]; - int nvalues = fusLUT->GetNumberOfTableValues(); - for (double i = 0; curr_value < range_end; i++) { - fusLUT->GetTableValue(i, v); - v[3] = 0; - //if (curr_value >= -alpha_range && curr_value <= alpha_range) v[3] = pow(fabs(curr_value/alpha_range),2); - //else v[3] = 1; - fusLUT->SetTableValue(i, v); - curr_value += (fusRange[1] - fusRange[0])/nvalues; - } - } - for ( unsigned int i = 0; i < mSlicers.size(); i++) { - - if (mSlicers[i]->GetOverlay()) { - vtkLookupTable* supLUT = vtkLookupTable::New(); - supLUT->SetTableRange(range[0],range[1]); - supLUT->SetValueRange(1,1); - supLUT->SetSaturationRange(1,1); - supLUT->SetHueRange(double(mOverlayColor)/360,double(mOverlayColor)/360); - supLUT->Build(); - vtkLookupTable* invLUT = vtkLookupTable::New(); - invLUT->SetTableRange(range[0],range[1]); - invLUT->SetValueRange(1,1); - invLUT->SetSaturationRange(1,1); - invLUT->SetHueRange(double((mOverlayColor+180)%360)/360,double((mOverlayColor+180)%360)/360); - invLUT->Build(); - mSlicers[i]->GetWindowLevel()->SetLookupTable(supLUT); - mSlicers[i]->GetOverlayMapper()->SetLookupTable(invLUT); - invLUT->Delete(); - supLUT->Delete(); - } else if (mSlicers[i]->GetOverlay()) { - mSlicers[i]->GetWindowLevel()->SetLookupTable(LUT); - } else { - mSlicers[i]->GetWindowLevel()->SetLookupTable(LUT); - } - - if (mSlicers[i]->GetFusion()) { - mSlicers[i]->ShowFusionLegend(mFusionShowLegend); - mSlicers[i]->GetFusionMapper()->SetLookupTable(fusLUT); - mSlicers[i]->GetFusionActor()->SetOpacity(double(mFusionOpacity)/100); - } - } - if (fusLUT) - fusLUT->Delete(); - if (colormap >= 0) - mColorMap = colormap; -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -vvLandmarks* vvSlicerManager::GetLandmarks() -{ - if (mLandmarks == NULL) { - mLandmarks = new vvLandmarks(mSlicers[0]->GetTMax()+1); - for (unsigned int i = 0; i < mSlicers.size(); i++) - mSlicers[i]->SetLandmarks(mLandmarks); - } - return mLandmarks; -} -//---------------------------------------------------------------------------- - - -//---------------------------------------------------------------------------- -void vvSlicerManager::AddLandmark(float x,float y,float z,float t) -{ - double x_index = (x - mSlicers[0]->GetInput()->GetOrigin()[0])/mSlicers[0]->GetInput()->GetSpacing()[0]; - double y_index = (y - mSlicers[0]->GetInput()->GetOrigin()[1])/mSlicers[0]->GetInput()->GetSpacing()[1]; - double z_index = (z - mSlicers[0]->GetInput()->GetOrigin()[2])/mSlicers[0]->GetInput()->GetSpacing()[2]; - if (x_index >= mSlicers[0]->GetInput()->GetWholeExtent()[0]-0.5 && - x_index <= mSlicers[0]->GetInput()->GetWholeExtent()[1]+0.5 && - y_index >= mSlicers[0]->GetInput()->GetWholeExtent()[2]-0.5 && - y_index <= mSlicers[0]->GetInput()->GetWholeExtent()[3]+0.5 && - z_index >= mSlicers[0]->GetInput()->GetWholeExtent()[4]-0.5 && - z_index <= mSlicers[0]->GetInput()->GetWholeExtent()[5]+0.5) { - double value = this->GetScalarComponentAsDouble(mSlicers[0]->GetInput(), x_index, y_index, z_index); - this->GetLandmarks()->AddLandmark(x,y,z,t,value); - emit LandmarkAdded(); - } -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -void vvSlicerManager::PrevImage(int slicer) -{ - emit ChangeImageWithIndexOffset(this, slicer, -1); -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -void vvSlicerManager::NextImage(int slicer) -{ - emit ChangeImageWithIndexOffset(this, slicer, 1); -} -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -void vvSlicerManager::VerticalSliderHasChanged(int slicer, int slice) -{ - emit AVerticalSliderHasChanged(slicer, slice); -} - -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -double vvSlicerManager::GetScalarComponentAsDouble(vtkImageData *image, double X, double Y, double Z, int component) -{ - int ix, iy, iz; - return mSlicers[0]->GetScalarComponentAsDouble(image, X, Y, Z, ix, iy, iz, component); -} -//---------------------------------------------------------------------------- +/*========================================================================= + 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://oncora1.lyon.fnclcc.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. + + 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 + ======================================================================-====*/ + +#include "vvSlicerManager.h" +#include "vvSlicer.h" +#include "vvImage.h" +#include "vvSlicerManagerCommand.h" +#include "vvInteractorStyleNavigator.h" +#include "vvLandmarks.h" +#include "vvMesh.h" +#include "vvBlendImageActor.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +//---------------------------------------------------------------------------- +vvSlicerManager::vvSlicerManager(int numberOfSlicers) +{ + mFileName = ""; + mId = ""; + mVFName = ""; + mOverlayName = ""; + mFusionName = ""; + mVFId = ""; + mLastError = ""; + mType = vvImageReader::UNDEFINEDIMAGETYPE; + mColorMap = 0; + mPreset = 0; + mOverlayColor = 130; + + mFusionOpacity = 30; + mFusionThresOpacity = 1; + mFusionColorMap = 3; + mFusionWindow = 1000; + mFusionLevel = 1000; + mFusionShowLegend = true; + + mFusionSequenceInvolvementCode = -1; + mFusionSequenceIndexLinkedManager = -1; + mFusionSequenceFrameIndex = -1; + mFusionSequenceNbFrames = 0; + mFusionSequenceSpatialSyncFlag = false; + mFusionSequenceTemporalSyncFlag = false; + + mLandmarks = NULL; + mLinkedId.resize(0); + + for ( int i = 0; i < numberOfSlicers; i++) + mSlicers.push_back(vtkSmartPointer::New()); + mSelectedSlicer = -1; + + mPreviousSlice.resize(numberOfSlicers, 0); + mPreviousTSlice.resize(numberOfSlicers, 0); + mSlicingPreset = WORLD_SLICING; + + +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +vvSlicerManager::~vvSlicerManager() +{ + if (mLandmarks) + delete mLandmarks; +} +//---------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------ +void vvSlicerManager::SetFilename(std::string filename, int number) +{ + mFileName = filename; + mFileName = vtksys::SystemTools::GetFilenameName(mFileName); + mBaseFileName = vtksys::SystemTools::GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(mFileName)); + mBaseFileNameNumber = number; + + mFileName = mBaseFileName; + if (number != 0) { + mFileName.append("_"+clitk::toString(number)); + } + mFileName.append(vtksys::SystemTools::GetFilenameLastExtension(filename)); + + for(unsigned int i=0; iSetFileName(mFileName);//vtksys::SystemTools::GetFilenameWithoutLastExtension(filename)); + } + +} +//------------------------------------------------------------------------------ + + +//---------------------------------------------------------------------------- +void vvSlicerManager::AddContour(vvMesh::Pointer contour,bool propagate) +{ + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->AddContour(contour,propagate); + } +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::ToggleContourSuperposition() +{ + for ( unsigned int i = 0; i < mSlicers.size(); i++) + mSlicers[i]->ToggleContourSuperposition(); +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +std::string vvSlicerManager::GetListOfAbsoluteFilePathInOneString(const std::string &actorType) +{ + vvImageReader *reader = NULL; + + if(actorType=="image") + reader = mReader; + else if(actorType=="overlay") + reader = mOverlayReader; + else if(actorType=="fusion") + reader = mFusionReader; + else if(actorType=="vector") + reader = mVectorReader; + else if(actorType=="fusionSequence") + reader = mFusionSequenceReader; + + if(!reader) + return ""; + + std::string list; + for(unsigned int i=0; iGetInputFilenames().size(); i++){ + QFileInfo fileinfo(reader->GetInputFilenames()[i].c_str()); //Do not show the path + if(i) + list += '\n'; + list += fileinfo.absoluteFilePath().toStdString(); + } + return list; +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +bool vvSlicerManager::SetImage(std::string filename, vvImageReader::LoadedImageType type, int n, unsigned int slice) +{ + mType = type; + if (mReader.IsNull()) + mReader = vvImageReader::New(); + std::vector filenames; + filenames.push_back(filename); + mReader->SetInputFilenames(filenames); + mReader->SetSlice(slice); // Only used for SLICED type + mReader->Update(type); + + SetFilename(filename, n); + // mFileName = vtksys::SystemTools::GetFilenameName(mFileName); + //mBaseFileName = vtksys::SystemTools::GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(mFileName)); + //mBaseFileNameNumber = n; + + if (mReader->GetLastError().size() == 0) { + mImage=mReader->GetOutput(); + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetFileName(vtksys::SystemTools::GetFilenameWithoutLastExtension(filename)); + mSlicers[i]->SetImage(mReader->GetOutput()); + } + } else { + mLastError = mReader->GetLastError(); + return false; + } + // if (n!=0) { + // mFileName.append("_"+clitk::toString(n)); + // } + return true; +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetImage(vvImage::Pointer image) +{ + mImage=image; + for (unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetImage(image); + } +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +bool vvSlicerManager::SetImages(std::vector filenames, vvImageReader::LoadedImageType type, int n) +{ + mType = type; + std::string fileWithoutExtension = vtksys::SystemTools::GetFilenameWithoutExtension(filenames[0]); + if (type == vvImageReader::DICOM) + fileWithoutExtension += "_dicom"; + else if (type == vvImageReader::MERGED) + fileWithoutExtension += "_merged"; + else if (type == vvImageReader::MERGEDWITHTIME) + fileWithoutExtension += "_merged_wt"; + + mFileName = vtksys::SystemTools::GetFilenameName(mFileName); + mFileName = fileWithoutExtension + vtksys::SystemTools::GetFilenameExtension(filenames[0]); + if (mReader.IsNull()) + mReader = vvImageReader::New(); + mReader->SetInputFilenames(filenames); + mReader->Update(type); + + mBaseFileName = vtksys::SystemTools::GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(mFileName)); + mBaseFileNameNumber = n; + + if (mReader->GetLastError().size() == 0) { + mImage=mReader->GetOutput(); + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetFileName(fileWithoutExtension); + mSlicers[i]->SetImage(mReader->GetOutput()); + } + } else { + mLastError = mReader->GetLastError(); + return false; + } + if (n!=0) { + mFileName.append("_"+clitk::toString(n)); + } + return true; +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +bool vvSlicerManager::SetOverlay(std::vector filenames,int dim, std::string component, vvImageReader::LoadedImageType type) +{ + mOverlayName = filenames[0]; + mOverlayComponent = component; + if (dim > mImage->GetNumberOfDimensions()) { + mLastError = " Overlay dimension cannot be greater than reference image!"; + return false; + } + if (mOverlayReader.IsNull()) + mOverlayReader = vvImageReader::New(); + mOverlayReader->SetInputFilenames(filenames); + mOverlayReader->Update(type); + if (mOverlayReader->GetLastError().size() == 0) { + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetOverlay(mOverlayReader->GetOutput()); + } + } else { + mLastError = mOverlayReader->GetLastError(); + return false; + } + return true; +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +bool vvSlicerManager::SetFusion(std::string filename,int dim, std::string component) +{ + mFusionName = filename; + mFusionComponent = component; + if (dim > mImage->GetNumberOfDimensions()) { + mLastError = " Overlay dimension cannot be greater then reference image!"; + return false; + } + if (mFusionReader.IsNull()) + mFusionReader = vvImageReader::New(); + std::vector filenames; + filenames.push_back(filename); + mFusionReader->SetInputFilenames(filenames); + mFusionReader->Update(mImage->GetNumberOfDimensions(),component.c_str(),mType); + if (mFusionReader->GetLastError().size() == 0) { + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetFusion(mFusionReader->GetOutput()); + } + } else { + mLastError = mFusionReader->GetLastError(); + return false; + } + double *fusRange = mFusionReader->GetOutput()->GetVTKImages()[0]->GetScalarRange(); + mFusionLevel = (fusRange[0]+fusRange[1])/2; + mFusionWindow = fusRange[1]-fusRange[0]; + + return true; +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +//this function is called by vvMainWindow::AddFusionSequence for the primary sequence (CT), while the given files constitute the secondary sequence. +bool vvSlicerManager::SetFusionSequence(std::vector filenames, int dim, std::string component, vvImageReader::LoadedImageType type) +{ + mFusionSequenceInvolvementCode = 0; + + mFusionName = filenames[0]; + mFusionComponent = component; + + if (dim > mImage->GetNumberOfDimensions()) { + mLastError = " Fusion Sequence dimension cannot be greater than reference image!"; + return false; + } + + if (mFusionSequenceReader.IsNull()) + mFusionSequenceReader = vvImageReader::New(); + + mFusionSequenceReader->SetInputFilenames(filenames); + mFusionSequenceReader->Update(type); + + + if (mFusionSequenceReader->GetLastError().size() == 0) { + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetFusion(mFusionSequenceReader->GetOutput(), mFusionSequenceInvolvementCode); + } + } else { + mLastError = mFusionSequenceReader->GetLastError(); + return false; + } + double *fusRange = mFusionSequenceReader->GetOutput()->GetVTKImages()[0]->GetScalarRange(); + mFusionLevel = (fusRange[0]+fusRange[1])/2; + mFusionWindow = fusRange[1]-fusRange[0]; + + //store the initial transform matrices of each frame, and reset them to identity + mFusionSequenceListInitialTransformMatrices.clear(); + for (unsigned i=0 ; iGetOutput()->GetTransform().size() ; i++) { + AddFusionSequenceInitialTransformMatrices( mFusionSequenceReader->GetOutput()->GetTransform()[i]->GetMatrix() ); + mFusionSequenceReader->GetOutput()->GetTransform()[i]->Identity(); + mFusionSequenceReader->GetOutput()->GetTransform()[i]->Update(); + } + + //adjust the time slider in the overlay panel + mFusionSequenceNbFrames = mFusionSequenceReader->GetOutput()->GetTransform().size()-1; //actually, this is the maximum index... + mFusionSequenceFrameIndex = std::max( 0, std::min(mFusionSequenceFrameIndex, mFusionSequenceNbFrames)); + + return true; +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +bool vvSlicerManager::SetVF(std::string filename) +{ + if (mVectorReader.IsNull()) + mVectorReader = vvImageReader::New(); + mVectorReader->SetInputFilename(filename); + + if (mType == vvImageReader::IMAGEWITHTIME) + mVectorReader->Update(vvImageReader::VECTORFIELDWITHTIME); + else + mVectorReader->Update(vvImageReader::VECTORFIELD); + if (mVectorReader->GetLastError().size() != 0) { + mLastError = mVectorReader->GetLastError(); + return false; + } else + return SetVF(mVectorReader->GetOutput(),filename); +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +bool vvSlicerManager::SetVF(vvImage::Pointer vf,std::string filename) +{ + if (vf->GetNumberOfDimensions() > mImage->GetNumberOfDimensions()) { + mLastError = "Sorry, vector field dimension cannot be greater then reference image."; + return false; + } + if (vf->GetNumberOfDimensions() == 4) { + if (vf->GetSpacing()[3] != mImage->GetSpacing()[3]) { + mLastError = "Sorry, vector field time spacing cannot be different from time spacing of the reference image."; + return false; + } + if (vf->GetOrigin()[3] != mImage->GetOrigin()[3]) { + mLastError = "Sorry, vector field time origin cannot be different from time origin of the reference image."; + return false; + } + } + mVF=vf; + mVFName = filename; + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetVF(vf); + } + return true; +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +vvSlicer* vvSlicerManager::GetSlicer(int i) +{ + return mSlicers[i]; +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::UpdateSlicer(int num, bool state) +{ + if (mSlicers[num]->GetImage()) { + mSlicers[num]->SetDisplayMode(state); + } +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetSlicerWindow(int i, vtkRenderWindow* RW) +{ + mSlicers[i]->SetRenderWindow(i,RW); +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetInteractorStyleNavigator(int i, vtkInteractorStyle* style) +{ + vvSlicerManagerCommand *smc = vvSlicerManagerCommand::New(); + smc->SM = this; + smc->SetSlicerNumber(i); + mSlicers[i]->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style); + + mSlicers[i]->GetRenderWindow()->GetInteractor()-> + GetInteractorStyle()->AddObserver(vtkCommand::KeyPressEvent, smc); + mSlicers[i]->GetRenderWindow()->GetInteractor()-> + GetInteractorStyle()->AddObserver(vtkCommand::WindowLevelEvent, smc); + mSlicers[i]->GetRenderWindow()->GetInteractor()-> + GetInteractorStyle()->AddObserver(vtkCommand::EndWindowLevelEvent, smc); + mSlicers[i]->GetRenderWindow()->GetInteractor()-> + GetInteractorStyle()->AddObserver(vtkCommand::StartWindowLevelEvent, smc); + mSlicers[i]->GetRenderWindow()->GetInteractor()-> + GetInteractorStyle()->AddObserver(vtkCommand::PickEvent, smc); + mSlicers[i]->GetRenderWindow()->GetInteractor()-> + GetInteractorStyle()->AddObserver(vtkCommand::StartPickEvent, smc); + mSlicers[i]->GetRenderWindow()->GetInteractor()-> + GetInteractorStyle()->AddObserver(vtkCommand::LeaveEvent, smc); + mSlicers[i]->GetRenderWindow()->GetInteractor()-> + GetInteractorStyle()->AddObserver(vtkCommand::UserEvent, smc); + mSlicers[i]->GetRenderWindow()->GetInteractor()-> + GetInteractorStyle()->AddObserver(vtkCommand::MouseWheelForwardEvent, smc); + mSlicers[i]->GetRenderWindow()->GetInteractor()-> + GetInteractorStyle()->AddObserver(vtkCommand::MouseWheelBackwardEvent, smc); + // mSlicers[i]->GetRenderWindow()->GetInteractor()-> + // GetInteractorStyle()->AddObserver(vtkCommand::LeftButtonReleaseEvent, smc); + mSlicers[i]->GetRenderWindow()->GetInteractor()-> + GetInteractorStyle()->AddObserver(vtkCommand::EndPickEvent, smc); + mSlicers[i]->GetRenderWindow()->GetInteractor()-> + GetInteractorStyle()->AddObserver(vtkCommand::EndInteractionEvent, smc); + smc->Delete(); +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::LeftButtonReleaseEvent(int slicer) +{ + emit LeftButtonReleaseSignal(slicer); +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::EmitMousePositionUpdated(int slicer) +{ + emit MousePositionUpdatedSignal(slicer); +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::EmitKeyPressed(std::string KeyPress) +{ + emit KeyPressedSignal(KeyPress); +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetSliceOrientation(int slicer, int orientation) +{ + mSlicers[slicer]->SetSliceOrientation(orientation); + emit UpdateOrientation(slicer, orientation); +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +int vvSlicerManager::GetTSlice() +{ + return mSlicers[0]->GetTSlice(); +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetTSlice(int slice, bool updateLinkedImages) +{ + if (!updateLinkedImages) { //for fusionSequence, TMax / MaxCurrentTSlice are irrelevant. + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetTSlice(slice, updateLinkedImages); + UpdateTSlice(i); + } + return; + } + + if (slice < 0) + slice = 0; + else if (slice > mSlicers[0]->GetTMax()) + slice = mSlicers[0]->GetTMax(); + if (mLandmarks) + mLandmarks->SetTime(slice); + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + if (slice != mSlicers[i]->GetMaxCurrentTSlice()) { + mSlicers[i]->SetTSlice(slice, updateLinkedImages); + UpdateTSlice(i); + } + } +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetFusionSequenceTSlice(int slice) +{ + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetFusionSequenceTSlice(slice); + UpdateTSlice(i); + } +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetNextTSlice(int originating_slicer) +{ + int t = mSlicers[0]->GetMaxCurrentTSlice(); + t++; + if (t > mSlicers[0]->GetTMax()) + t = 0; + //std::cout << "vvSlicerManager::SetNextTSlice" << std::endl; + emit UpdateTSlice(originating_slicer,t, mFusionSequenceInvolvementCode); +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetPreviousTSlice(int originating_slicer) +{ + int t = mSlicers[0]->GetMaxCurrentTSlice(); + t--; + if (t < 0) + t = mSlicers[0]->GetTMax(); + //std::cout << "vvSlicerManager::SetPreviousTSlice" << std::endl; + emit UpdateTSlice(originating_slicer,t, mFusionSequenceInvolvementCode); +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::ToggleInterpolation() +{ + bool interpolate=!(mSlicers[0]->GetImageActor()->GetInterpolate()); + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->GetImageActor()->SetInterpolate(interpolate); + if (mSlicers[i]->GetOverlayActor()) + mSlicers[i]->GetOverlayActor()->SetInterpolate(interpolate); + if (mSlicers[i]->GetFusionActor()) + mSlicers[i]->GetFusionActor()->SetInterpolate(interpolate); + } +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetTSliceInSlicer(int tslice, int slicer) +{ + if (tslice < 0) + tslice = 0; + else if (tslice > mSlicers[slicer]->GetTMax()) + tslice = mSlicers[slicer]->GetTMax(); + if (mLandmarks) + mLandmarks->SetTime(tslice); + + if (mSlicers[slicer]->GetMaxCurrentTSlice() == tslice) return; + + mSlicers[slicer]->SetTSlice(tslice); + + if(mSlicingPreset==VOXELS_SLICING) { + vtkMatrix4x4 *imageTransformInverse = vtkMatrix4x4::New(); + mImage->GetTransform()[mSlicers[slicer]->GetTSlice()]->GetInverse(imageTransformInverse); + this->GetSlicer(slicer)->GetSlicingTransform()->SetMatrix(imageTransformInverse); + imageTransformInverse->Delete(); + } + + UpdateTSlice(slicer); +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetColorWindow(double s) +{ + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetColorWindow(s); + } +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetColorLevel(double s) +{ + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetColorLevel(s); + } +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetOverlayColorWindow(double s) +{ + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetOverlayColorWindow(s); + } +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetOverlayColorLevel(double s) +{ + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetOverlayColorLevel(s); + } +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetLinkOverlayWindowLevel(bool b) +{ + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetLinkOverlayWindowLevel(b); + } +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetCursorAndCornerAnnotationVisibility(int s) +{ + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetCursorVisibility(s); + mSlicers[i]->SetCornerAnnotationVisibility(s); + } +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetOpacity(int i, double factor) +{ + mSlicers[i]->SetOpacity(1/factor); +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::UpdateViews(int current,int slicer) +{ + double p[3], pt[3]; + p[0] = mSlicers[slicer]->GetCurrentPosition()[0]; + p[1] = mSlicers[slicer]->GetCurrentPosition()[1]; + p[2] = mSlicers[slicer]->GetCurrentPosition()[2]; + mSlicers[slicer]->GetSlicingTransform()->GetInverse()->TransformPoint(p, pt); + + double x = (pt[0] - mSlicers[slicer]->GetInput()->GetOrigin()[0]) + /mSlicers[slicer]->GetInput()->GetSpacing()[0]; + double y = (pt[1] - mSlicers[slicer]->GetInput()->GetOrigin()[1]) + /mSlicers[slicer]->GetInput()->GetSpacing()[1]; + double z = (pt[2] - mSlicers[slicer]->GetInput()->GetOrigin()[2]) + /mSlicers[slicer]->GetInput()->GetSpacing()[2]; + + if (x >= mSlicers[slicer]->GetInput()->GetWholeExtent()[0]-0.5 && + x <= mSlicers[slicer]->GetInput()->GetWholeExtent()[1]+0.5 && + y >= mSlicers[slicer]->GetInput()->GetWholeExtent()[2]-0.5 && + y <= mSlicers[slicer]->GetInput()->GetWholeExtent()[3]+0.5 && + z >= mSlicers[slicer]->GetInput()->GetWholeExtent()[4]-0.5 && + z <= mSlicers[slicer]->GetInput()->GetWholeExtent()[5]+0.5) { + mSlicers[slicer]->UpdateCursorPosition(); + mSlicers[slicer]->SetCursorColor(10,212,255); + mSelectedSlicer = slicer; + + switch (mSlicers[slicer]->GetSliceOrientation()) { + case vtkImageViewer2::SLICE_ORIENTATION_XY: + if (mSlicers[slicer]->GetSlice() != (int)lrint(z)) + mSlicers[slicer]->SetSlice((int)lrint(z)); + break; + + case vtkImageViewer2::SLICE_ORIENTATION_XZ: + if (mSlicers[slicer]->GetSlice() != (int)lrint(y)) + mSlicers[slicer]->SetSlice((int)lrint(y)); + break; + + case vtkImageViewer2::SLICE_ORIENTATION_YZ: + if (mSlicers[slicer]->GetSlice() != (int)lrint(x)) + mSlicers[slicer]->SetSlice((int)lrint(x)); + break; + } + mSlicers[slicer]->Render(); + + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + if (i != (unsigned int)slicer + && mSlicers[i]->GetRenderer()->GetDraw() + && mSlicers[i]->GetRenderWindow()->GetSize()[0] > 2 + && mSlicers[i]->GetRenderWindow()->GetSize()[1] > 2) { + mSlicers[i]->SetCurrentPosition(p[0], p[1], p[2], mSlicers[slicer]->GetMaxCurrentTSlice()); + mSlicers[i]->UpdateCursorPosition(); + if (current) { //do not display corner annotation if image is the one picked + mSlicers[i]->SetCurrentPosition(-VTK_DOUBLE_MAX,-VTK_DOUBLE_MAX, + -VTK_DOUBLE_MAX, mSlicers[slicer]->GetMaxCurrentTSlice()); + mSlicers[i]->SetCursorColor(255,10,212); + } else { + mSlicers[i]->SetCursorColor(150,10,282); + } + switch (mSlicers[i]->GetSliceOrientation()) { + case vtkImageViewer2::SLICE_ORIENTATION_XY: + if (mSlicers[i]->GetSlice() != (int)lrint(z)) + mSlicers[i]->SetSlice((int)lrint(z)); + break; + + case vtkImageViewer2::SLICE_ORIENTATION_XZ: + if (mSlicers[i]->GetSlice() != (int)lrint(y)) + mSlicers[i]->SetSlice((int)lrint(y)); + break; + + case vtkImageViewer2::SLICE_ORIENTATION_YZ: + if (mSlicers[i]->GetSlice() != (int)lrint(x)) + mSlicers[i]->SetSlice((int)lrint(x)); + break; + } + + mSlicers[i]->Render(); + + UpdateSlice(i); + UpdateTSlice(i); + } + } + } +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::UpdateLinked(int slicer) +{ + double p[3], pt[3]; + p[0] = mSlicers[slicer]->GetCurrentPosition()[0]; + p[1] = mSlicers[slicer]->GetCurrentPosition()[1]; + p[2] = mSlicers[slicer]->GetCurrentPosition()[2]; + mSlicers[slicer]->GetSlicingTransform()->GetInverse()->TransformPoint(p, pt); + double x = (pt[0] - mSlicers[slicer]->GetInput()->GetOrigin()[0]) / mSlicers[slicer]->GetInput()->GetSpacing()[0]; + double y = (pt[1] - mSlicers[slicer]->GetInput()->GetOrigin()[1]) / mSlicers[slicer]->GetInput()->GetSpacing()[1]; + double z = (pt[2] - mSlicers[slicer]->GetInput()->GetOrigin()[2]) / mSlicers[slicer]->GetInput()->GetSpacing()[2]; + + if (x >= mSlicers[slicer]->GetInput()->GetWholeExtent()[0]-0.5 && + x <= mSlicers[slicer]->GetInput()->GetWholeExtent()[1]+0.5 && + y >= mSlicers[slicer]->GetInput()->GetWholeExtent()[2]-0.5 && + y <= mSlicers[slicer]->GetInput()->GetWholeExtent()[3]+0.5 && + z >= mSlicers[slicer]->GetInput()->GetWholeExtent()[4]-0.5 && + z <= mSlicers[slicer]->GetInput()->GetWholeExtent()[5]+0.5) { + for (std::list::const_iterator i = mLinkedId.begin(); i != mLinkedId.end(); i++) { + if (this->IsInvolvedInFusionSequence()) { + //this SlicerManager is involved in fusionSequence => do not synchronize the times + emit UpdateLinkManager(*i, slicer, p[0], p[1], p[2], -1); + } + else { + emit UpdateLinkManager(*i, slicer, p[0], p[1], p[2], mSlicers[slicer]->GetMaxCurrentTSlice()); + } + } + } +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +void vvSlicerManager::UpdateLinkedNavigation(vvSlicer *refSlicer, bool bPropagate) +{ + vtkCamera *refCam = refSlicer->GetRenderer()->GetActiveCamera(); + + double refPosition[3]; + refCam->GetPosition(refPosition); + refPosition[refSlicer->GetSliceOrientation()] = refSlicer->GetSlice() * + refSlicer->GetInput()->GetSpacing()[refSlicer->GetSliceOrientation()] + + refSlicer->GetInput()->GetOrigin()[refSlicer->GetSliceOrientation()]; + + refSlicer->GetSlicingTransform()->TransformPoint(refPosition, refPosition); + mSlicers[0]->GetSlicingTransform()->GetInverse()->TransformPoint(refPosition, refPosition); + + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + vtkCamera *camera = mSlicers[i]->GetRenderer()->GetActiveCamera(); + camera->SetParallelScale(refCam->GetParallelScale()); + + double position[3], focal[3]; + camera->GetPosition(position); + camera->GetFocalPoint(focal); + + for(int j=0; j<3; j++) { + if(j!=mSlicers[i]->GetSliceOrientation()) { + position[j] = refPosition[j]; + focal[j] = refPosition[j]; + } + } + + camera->SetFocalPoint(focal); + camera->SetPosition(position); + + //Fix for bug #243 + mSlicers[i]->ForceUpdateDisplayExtent(); + } + + Render(); + if(bPropagate) + for (std::list::const_iterator i = mLinkedId.begin(); i != mLinkedId.end(); i++) + emit UpdateLinkedNavigation(*i, this, refSlicer); +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +double vvSlicerManager::GetColorWindow() const +{ + if (mSlicers.size()) + return mSlicers[0]->GetColorWindow(); + return -1; +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +double vvSlicerManager::GetColorLevel() const +{ + if (mSlicers.size()) + return mSlicers[0]->GetColorLevel(); + return -1; +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +double vvSlicerManager::GetOverlayColorWindow() const +{ + if (mSlicers.size()) + return mSlicers[0]->GetOverlayColorWindow(); + return -1; +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +double vvSlicerManager::GetOverlayColorLevel() const +{ + if (mSlicers.size()) + return mSlicers[0]->GetOverlayColorLevel(); + return -1; +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +bool vvSlicerManager::GetLinkOverlayWindowLevel() const +{ + if (mSlicers.size()) + return mSlicers[0]->GetLinkOverlayWindowLevel(); + return -1; +} +//---------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +void vvSlicerManager::ResetTransformationToIdentity(const std::string actorType) +{ + if(actorType == "image") + for(unsigned int i=0; iGetImage()->GetTransform().size(); i++) + this->GetImage()->GetTransform()[i]->Identity(); + else if(actorType == "overlay") + for(unsigned int i=0; iGetImage()->GetTransform().size(); i++) + this->GetSlicer(0)->GetOverlay()->GetTransform()[i]->Identity(); + else if(actorType == "fusion") + for(unsigned int i=0; iGetImage()->GetTransform().size(); i++) + this->GetSlicer(0)->GetFusion()->GetTransform()[i]->Identity(); + else if(actorType == "fusionSequence") //TODO: Check what should really be done here + for(unsigned int i=0; iGetImage()->GetTransform().size(); i++) + this->GetSlicer(0)->GetFusion()->GetTransform()[i]->Identity(); + else if(actorType == "vf") + for(unsigned int i=0; iGetImage()->GetTransform().size(); i++) + this->GetVF()->GetTransform()[i]->Identity(); + else + return; + + for(int i=0; i< this->GetNumberOfSlicers(); i++){ + this->GetSlicer(i)->ForceUpdateDisplayExtent(); + this->GetSlicer(i)->ResetCamera(); + this->GetSlicer(i)->Render(); + } +} +//------------------------------------------------------------------------------ + +//---------------------------------------------------------------------------- +void vvSlicerManager::Render() +{ + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->Render(); + } +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::GenerateDefaultLookupTable() +{ + SetPreset(mPreset); + SetColorMap(mColorMap); +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::Reload() +{ + mReader->Update(mType); + mImage=mReader->GetOutput(); + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetImage(mImage); + } + + //if this image is the primary sequence of a fusion sequence, then the main transform matrix should be updated. + if (this->IsMainSequenceOfFusionSequence()) { + SetFusionSequenceMainTransformMatrix( mImage->GetTransform()[0]->GetMatrix() ); + } +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::ReloadFusion() +{ + mFusionReader->Update(mImage->GetNumberOfDimensions(),mFusionComponent.c_str(),mType); + + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetFusion(mFusionReader->GetOutput()); + mSlicers[i]->Render(); + } +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +//the secondary sequence is being reloaded. +void vvSlicerManager::ReloadFusionSequence() +{ + mFusionSequenceReader->Update(mImage->GetNumberOfDimensions(),mFusionComponent.c_str(),vvImageReader::MERGEDWITHTIME); + + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetFusion(mFusionSequenceReader->GetOutput(), 1); + mSlicers[i]->Render(); + } + + //Update the slider + mFusionSequenceNbFrames = mFusionSequenceReader->GetOutput()->GetTransform().size(); + if (mFusionSequenceFrameIndex>=mFusionSequenceNbFrames) { + mFusionSequenceFrameIndex=0; + } + + //Update the list of initial transforms + mFusionSequenceListInitialTransformMatrices.clear(); + for (unsigned i=0 ; iAddFusionSequenceInitialTransformMatrices( mFusionSequenceReader->GetOutput()->GetTransform()[i]->GetMatrix() ); + } + +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::ReloadOverlay() +{ + mOverlayReader->Update(mImage->GetNumberOfDimensions(),mOverlayComponent.c_str(),mType); + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetOverlay(mOverlayReader->GetOutput()); + mSlicers[i]->Render(); + } +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::ReloadVF() +{ + mVectorReader->Update(vvImageReader::VECTORFIELD); //deletes the old images through the VF::Init() function + mVF=mVectorReader->GetOutput(); + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetVF(mVF); + mSlicers[i]->Render(); + } +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::RemoveActor(const std::string& actor_type, int overlay_index) +{ + if (actor_type =="overlay") + mOverlayReader = NULL; + + if (actor_type =="fusion") + mFusionReader = NULL; + + if (actor_type =="fusionSequence") { + mFusionSequenceReader = NULL; + } + + for (unsigned int i = 0; i < mSlicers.size(); i++) + mSlicers[i]->RemoveActor(actor_type,overlay_index); + + if (actor_type=="vector") { + mVF=NULL; + mVectorReader=NULL; + } +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::RemoveActors() +{ + ///This method leaks a few objects. See RemoveActor for what a + ///correct implementation would look like + //DS -> probably due to the reader (now released in the + //RemoveActor() function. (I hope) + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetDisplayMode(0); + mSlicers[i]->GetRenderer()->RemoveActor(mSlicers[i]->GetImageActor()); + } +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::UpdateInfoOnCursorPosition(int slicer) +{ + // int view = mSlicers[slicer]->GetSliceOrientation(); + // int slice = mSlicers[slicer]->GetSlice(); + double x = mSlicers[slicer]->GetCursorPosition()[0]; + double y = mSlicers[slicer]->GetCursorPosition()[1]; + double z = mSlicers[slicer]->GetCursorPosition()[2]; + double X = (x - mSlicers[slicer]->GetInput()->GetOrigin()[0])/ + mSlicers[slicer]->GetInput()->GetSpacing()[0]; + double Y = (y - mSlicers[slicer]->GetInput()->GetOrigin()[1])/ + mSlicers[slicer]->GetInput()->GetSpacing()[1]; + double Z = (z - mSlicers[slicer]->GetInput()->GetOrigin()[2])/ + mSlicers[slicer]->GetInput()->GetSpacing()[2]; + double value = -VTK_DOUBLE_MAX; + int displayVec = 0; + double xVec=0, yVec=0, zVec=0, valueVec=0; + int displayOver = 0; + int displayFus = 0; + double valueOver=0, valueFus=0; + if (X >= mSlicers[slicer]->GetInput()->GetWholeExtent()[0] && + X <= mSlicers[slicer]->GetInput()->GetWholeExtent()[1] && + Y >= mSlicers[slicer]->GetInput()->GetWholeExtent()[2] && + Y <= mSlicers[slicer]->GetInput()->GetWholeExtent()[3] && + Z >= mSlicers[slicer]->GetInput()->GetWholeExtent()[4] && + Z <= mSlicers[slicer]->GetInput()->GetWholeExtent()[5]) { + + value = this->GetScalarComponentAsDouble(mSlicers[slicer]->GetInput(), X, Y, Z); + + if (mSlicers[slicer]->GetVFActor() ) { + displayVec = 1; + unsigned int currentTime = mSlicers[slicer]->GetMaxCurrentTSlice(); + vtkImageData *vf = NULL; + + if (mSlicers[slicer]->GetVF()->GetVTKImages().size() > currentTime) + vf = mSlicers[slicer]->GetVF()->GetVTKImages()[currentTime]; + else + vf = mSlicers[slicer]->GetVF()->GetVTKImages()[0]; + + if (vf) { + double Xvf = (x - vf->GetOrigin()[0])/ vf->GetSpacing()[0]; + double Yvf = (y - vf->GetOrigin()[1])/ vf->GetSpacing()[1]; + double Zvf = (z - vf->GetOrigin()[2])/ vf->GetSpacing()[2]; + xVec = this->GetScalarComponentAsDouble( vf, Xvf, Yvf, Zvf, 0); + yVec = this->GetScalarComponentAsDouble( vf, Xvf, Yvf, Zvf, 1); + zVec = this->GetScalarComponentAsDouble( vf, Xvf, Yvf, Zvf, 2); + valueVec = sqrt(xVec*xVec + yVec*yVec + zVec*zVec); + } + } + if (mSlicers[slicer]->GetOverlayActor() ) { + displayOver = 1; + vtkImageData *overlay = dynamic_cast(mSlicers[slicer]->GetOverlayMapper()->GetInput()); + double Xover = (x - overlay->GetOrigin()[0]) / overlay->GetSpacing()[0]; + double Yover = (y - overlay->GetOrigin()[1]) / overlay->GetSpacing()[1]; + double Zover = (z - overlay->GetOrigin()[2]) / overlay->GetSpacing()[2]; + valueOver = this->GetScalarComponentAsDouble(overlay, Xover, Yover, Zover); + } + + if ( mSlicers[slicer]->GetFusionActor() ) { + displayFus = 1; + vtkImageData *fusion = dynamic_cast(mSlicers[slicer]->GetFusionMapper()->GetInput()); + double Xover = (x - fusion->GetOrigin()[0]) / fusion->GetSpacing()[0]; + double Yover = (y - fusion->GetOrigin()[1]) / fusion->GetSpacing()[1]; + double Zover = (z - fusion->GetOrigin()[2]) / fusion->GetSpacing()[2]; + valueFus = this->GetScalarComponentAsDouble(fusion, Xover, Yover, Zover); + } + else if (this->IsInvolvedInFusionSequence()) { + //if the cursor moves over the 'independent' version of the secondary sequence + //do not update the panel, just keep it as it is. + displayFus = 1; + valueFus = std::numeric_limits::quiet_NaN(); + } + + emit UpdatePosition(mSlicers[slicer]->GetCursorVisibility(), + x,y,z,X,Y,Z,value); + emit UpdateVector(displayVec,xVec, yVec, zVec, valueVec); + emit UpdateOverlay(displayOver,valueOver,value); + emit UpdateFusion(displayFus,valueFus); + } +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::Activated() +{ + emit currentImageChanged(mId); +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::Picked() +{ + emit currentPickedImageChanged(mId); +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::UpdateWindowLevel() +{ + emit WindowLevelChanged(); +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::UpdateSlice(int slicer) +{ + if (mPreviousSlice[slicer] == mSlicers[slicer]->GetSlice()) { + //DD("============= NOTHING"); + return; + } + //std::cout << "vvSlicerManager::UpdateSlice " << slicer << " " << mSlicers[slicer]->GetSlice() << std::endl; + emit UpdateSlice(slicer, mSlicers[slicer]->GetSlice()); + mSlicers[slicer]->Render(); // DS <-- I add this, this could/must be the only Render ... + mPreviousSlice[slicer] = mSlicers[slicer]->GetSlice(); +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::UpdateTSlice(int slicer) +{ + int slice = mSlicers[slicer]->GetSlice(); + + int tslice = mSlicers[slicer]->GetMaxCurrentTSlice(); + //if (this->IsInvolvedInFusionSequence()) tslice = mSlicers[slicer]->GetTSlice(); //actually, this is handled by the Slicer + + if (mPreviousSlice[slicer] == slice) { + if (mPreviousTSlice[slicer] == tslice) { + // DD("************** NOTHING ***********"); + return; + } + } + mPreviousSlice[slicer] = slice; + mPreviousTSlice[slicer] = tslice; + + emit UpdateTSlice(slicer, tslice, mFusionSequenceInvolvementCode); +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::UpdateSliceRange(int slicer) +{ + emit UpdateSliceRange(slicer, + mSlicers[slicer]->GetSliceRange()[0], mSlicers[slicer]->GetSliceRange()[1], + 0,mSlicers[slicer]->GetTMax()); +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetSlicingPreset(SlicingPresetType preset) +{ + if(mSlicingPreset==preset) + return; + + vtkMatrix4x4 *imageTransformInverse = vtkMatrix4x4::New(); + mImage->GetTransform()[this->GetTSlice()]->GetInverse(imageTransformInverse); + + for(int i=0; i< this->GetNumberOfSlicers(); i++){ + vvSlicer *s = this->GetSlicer(i); + switch(preset) + { + case WORLD_SLICING: + s->GetSlicingTransform()->Identity(); + break; + case VOXELS_SLICING: + s->GetSlicingTransform()->SetMatrix(imageTransformInverse); + break; + default: + imageTransformInverse->Delete(); + return; + } + s->ForceUpdateDisplayExtent(); + s->SetSlice((s->GetInput()->GetWholeExtent()[s->GetSliceOrientation()*2+1] + +s->GetInput()->GetWholeExtent()[s->GetSliceOrientation()*2])/2.0); + s->ResetCamera(); + s->Render(); + } + + imageTransformInverse->Delete(); + mSlicingPreset = preset; +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetPreset(int preset) +{ + //vtkLookupTable* LUT = static_cast(mSlicers[0]->GetWindowLevel()->GetLookupTable()); + double window = mSlicers[0]->GetColorWindow(); + double level = mSlicers[0]->GetColorLevel(); + + std::string component_type=mImage->GetScalarTypeAsITKString(); + switch (preset) { + case 0: + double range[2]; + mImage->GetScalarRange(range); + window = range[1] - range[0]; + level = (range[1] + range[0])* 0.5; + break; + case 1: + window = 2000; + level = 0; + break; + case 2: + window = 400; + level = 20; + break; + case 3: // lungs (same as FOCAL) + window = 1700; + level = -300; + break; + case 4: + window = 1000; + level = 500; + break; + case 5: + window = 1; + level = 0.5; + break; + case 6: + break; + case 7: + window=1.; + level=0.; + break; + } + mPreset = preset; + this->SetColorWindow(window); + this->SetColorLevel(level); + + //if (LUT) + //{ + // SetColorMap(-1); + //} +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetLocalColorWindowing(const int slicer, const bool bCtrlKey) +{ + double min, max; + if(bCtrlKey && this->mSlicers[slicer]->GetFusion()) { + int t = mSlicers[slicer]->GetFusionTSlice(); + this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, + this->mSlicers[slicer]->GetFusion()->GetVTKImages()[t], + this->mSlicers[slicer]->GetConcatenatedFusionTransform()); + this->SetFusionWindow(max-min); + this->SetFusionLevel(0.5*(min+max)); + this->SetColorMap(mColorMap); + } + else if(bCtrlKey && this->mSlicers[slicer]->GetOverlay()) { + int t = mSlicers[slicer]->GetOverlayTSlice(); + this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, + this->mSlicers[slicer]->GetOverlay()->GetVTKImages()[t], + this->mSlicers[slicer]->GetConcatenatedOverlayTransform()); + if(this->mSlicers[slicer]->GetLinkOverlayWindowLevel()){ + this->SetColorWindow(max-min); + this->SetColorLevel(0.5*(min+max)); + } else { + this->SetOverlayColorWindow(max-min); + this->SetOverlayColorLevel(0.5*(min+max)); + } + } + else { + int t = this->GetTSlice(); + this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, + this->mSlicers[slicer]->GetImage()->GetVTKImages()[t], + this->mSlicers[slicer]->GetConcatenatedTransform()); + this->SetColorWindow(max-min); + this->SetColorLevel(0.5*(min+max)); + this->SetPreset(6); + } + this->Render(); + this->UpdateWindowLevel(); +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::SetColorMap(int colormap) +{ + double range[2]; + + range[0] = mSlicers[0]->GetInput()->GetScalarRange()[0]; + range[1] = mSlicers[0]->GetInput()->GetScalarRange()[1]; + + double window = mSlicers[0]->GetWindowLevel()->GetWindow(); + double level = mSlicers[0]->GetWindowLevel()->GetLevel(); + + vtkLookupTable* LUT = static_cast(mSlicers[0]->GetWindowLevel()->GetLookupTable()); + switch (colormap) { + case -1: + break; + case 0: + LUT = NULL; + break; + case 1: + if (LUT == NULL) + LUT = vtkLookupTable::New(); + LUT->SetValueRange(0,1); + LUT->SetSaturationRange(1,1); + LUT->SetHueRange(0,0.18); + break; + case 2: + if (LUT == NULL) + LUT = vtkLookupTable::New(); + LUT->SetValueRange(0,1); + LUT->SetSaturationRange(1,1); + LUT->SetHueRange(0.4,0.80); + break; + case 3: + if (LUT == NULL) + LUT = vtkLookupTable::New(); + LUT->SetValueRange(0.5,1); + LUT->SetSaturationRange(1,1); + LUT->SetHueRange(0.666,0); + break; + case 4: + if (LUT == NULL) + LUT = vtkLookupTable::New(); + LUT->SetValueRange(1,1); + LUT->SetSaturationRange(1,1); + LUT->SetHueRange(0,1); + LUT->SetAlphaRange(1, 1); + break; + case 5: + if (LUT == NULL) + LUT = vtkLookupTable::New(); + LUT->SetValueRange(1,1); + LUT->SetSaturationRange(1,1); + LUT->SetHueRange(1,0.1); + //LUT->SetRampToLinear(); + break; + } + if (LUT) { + LUT->SetTableRange(level-fabs(window)/2,level+fabs(window)/2); + LUT->Build(); + } + vtkWindowLevelLookupTable* fusLUT = NULL; + + //FUSION / FUSION SEQUENCE + if (mSlicers[0]->GetFusion()) { // && mFusionColorMap >= 0) { + fusLUT = vtkWindowLevelLookupTable::New(); + double fusRange [2]; + fusRange[0] = mFusionLevel - mFusionWindow/2; + fusRange[1] = mFusionLevel + mFusionWindow/2; + + //check whether it is actually a fusionSequence or a fusion, before invoking mFusionReader... + double* frange; + if (this->IsInvolvedInFusionSequence()) + frange = mFusionSequenceReader->GetOutput()->GetVTKImages()[0]->GetScalarRange(); + else + frange = mFusionReader->GetOutput()->GetVTKImages()[0]->GetScalarRange(); + + fusLUT->SetTableRange(frange); + fusLUT->SetValueRange(1,1); + fusLUT->SetSaturationRange(1,1); + fusLUT->SetAlphaRange(1, 1); + fusLUT->SetWindow(mFusionWindow); + fusLUT->SetLevel(mFusionLevel); + if (mFusionColorMap == 1) + fusLUT->SetHueRange(0,0.18); + else if (mFusionColorMap == 2) + fusLUT->SetHueRange(0.4,0.80); + else if (mFusionColorMap == 3) + { + fusLUT->SetHueRange(0.666, 0); + fusLUT->SetValueRange(0.5, 1); + } + else if (mFusionColorMap == 4) + fusLUT->SetHueRange(0,1); + else if (mFusionColorMap <= 0) + { + fusLUT->SetValueRange(0,1); + fusLUT->SetSaturationRange(0,0); + } + + fusLUT->ForceBuild(); + double v[4]; + + // set color table transparency + //double alpha_range=(double)mFusionThresOpacity/10; + double range_end = fusRange[0] + (double)mFusionThresOpacity*(fusRange[1] - fusRange[0])/100; + double curr_value = fusRange[0]; + int nvalues = fusLUT->GetNumberOfTableValues(); + for (double i = 0; curr_value < range_end; i++) { + fusLUT->GetTableValue(i, v); + v[3] = 0; + //if (curr_value >= -alpha_range && curr_value <= alpha_range) v[3] = pow(fabs(curr_value/alpha_range),2); + //else v[3] = 1; + fusLUT->SetTableValue(i, v); + curr_value += (fusRange[1] - fusRange[0])/nvalues; + } + } + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + + if (mSlicers[i]->GetOverlay()) { + vtkLookupTable* supLUT = vtkLookupTable::New(); + supLUT->SetTableRange(range[0],range[1]); + supLUT->SetValueRange(1,1); + supLUT->SetSaturationRange(1,1); + supLUT->SetHueRange(double(mOverlayColor)/360,double(mOverlayColor)/360); + supLUT->Build(); + vtkLookupTable* invLUT = vtkLookupTable::New(); + invLUT->SetTableRange(range[0],range[1]); + invLUT->SetValueRange(1,1); + invLUT->SetSaturationRange(1,1); + invLUT->SetHueRange(double((mOverlayColor+180)%360)/360,double((mOverlayColor+180)%360)/360); + invLUT->Build(); + mSlicers[i]->GetWindowLevel()->SetLookupTable(supLUT); + mSlicers[i]->GetOverlayMapper()->SetLookupTable(invLUT); + invLUT->Delete(); + supLUT->Delete(); + } else if (mSlicers[i]->GetOverlay()) { + mSlicers[i]->GetWindowLevel()->SetLookupTable(LUT); + } else { + mSlicers[i]->GetWindowLevel()->SetLookupTable(LUT); + } + + if (mSlicers[i]->GetFusion()) { + mSlicers[i]->ShowFusionLegend(mFusionShowLegend); + mSlicers[i]->GetFusionMapper()->SetLookupTable(fusLUT); + mSlicers[i]->GetFusionActor()->SetOpacity(double(mFusionOpacity)/100); + } + } + if (fusLUT) + fusLUT->Delete(); + if (colormap >= 0) + mColorMap = colormap; +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +vvLandmarks* vvSlicerManager::GetLandmarks() +{ + if (mLandmarks == NULL) { + mLandmarks = new vvLandmarks(mSlicers[0]->GetTMax()+1); + for (unsigned int i = 0; i < mSlicers.size(); i++) + mSlicers[i]->SetLandmarks(mLandmarks); + } + return mLandmarks; +} +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +void vvSlicerManager::AddLandmark(float x,float y,float z,float t) +{ + double x_index = (x - mSlicers[0]->GetInput()->GetOrigin()[0])/mSlicers[0]->GetInput()->GetSpacing()[0]; + double y_index = (y - mSlicers[0]->GetInput()->GetOrigin()[1])/mSlicers[0]->GetInput()->GetSpacing()[1]; + double z_index = (z - mSlicers[0]->GetInput()->GetOrigin()[2])/mSlicers[0]->GetInput()->GetSpacing()[2]; + if (x_index >= mSlicers[0]->GetInput()->GetWholeExtent()[0]-0.5 && + x_index <= mSlicers[0]->GetInput()->GetWholeExtent()[1]+0.5 && + y_index >= mSlicers[0]->GetInput()->GetWholeExtent()[2]-0.5 && + y_index <= mSlicers[0]->GetInput()->GetWholeExtent()[3]+0.5 && + z_index >= mSlicers[0]->GetInput()->GetWholeExtent()[4]-0.5 && + z_index <= mSlicers[0]->GetInput()->GetWholeExtent()[5]+0.5) { + double value = this->GetScalarComponentAsDouble(mSlicers[0]->GetInput(), x_index, y_index, z_index); + this->GetLandmarks()->AddLandmark(x,y,z,t,value); + emit LandmarkAdded(); + } +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +void vvSlicerManager::PrevImage(int slicer) +{ + emit ChangeImageWithIndexOffset(this, slicer, -1); +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +void vvSlicerManager::NextImage(int slicer) +{ + emit ChangeImageWithIndexOffset(this, slicer, 1); +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +void vvSlicerManager::VerticalSliderHasChanged(int slicer, int slice) +{ + emit AVerticalSliderHasChanged(slicer, slice); +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +double vvSlicerManager::GetScalarComponentAsDouble(vtkImageData *image, double X, double Y, double Z, int component) +{ + int ix, iy, iz; + return mSlicers[0]->GetScalarComponentAsDouble(image, X, Y, Z, ix, iy, iz, component); +} +//---------------------------------------------------------------------------- diff --git a/vv/vvSlicerManager.h b/vv/vvSlicerManager.h index 4fc274c..d634fbd 100644 --- a/vv/vvSlicerManager.h +++ b/vv/vvSlicerManager.h @@ -66,6 +66,7 @@ class vvSlicerManager : public QObject { bool SetOverlay(std::vector filenames, int dim, std::string component, vvImageReader::LoadedImageType type); bool SetFusion(std::string filename, int dim, std::string component); + bool SetFusionSequence(std::vector filenames, int dim, std::string component, vvImageReader::LoadedImageType type); ///Set a VF by loading it from the disk bool SetVF(std::string filename); ///Set a VF from memory @@ -109,11 +110,13 @@ class vvSlicerManager : public QObject { void SetSliceOrientation(int slicer, int orientation); int GetTSlice(); - void SetTSlice(int slice); + void SetTSlice(int slice, bool updateLinkedImages = true); void SetNextTSlice(int originating_slicer); void SetPreviousTSlice(int originating_slicer); void SetTSliceInSlicer(int tslice, int slicer); + void SetFusionSequenceTSlice(int slice); + void GenerateDefaultLookupTable(); void SetColorWindow(double s); void SetColorLevel(double s); @@ -146,6 +149,42 @@ class vvSlicerManager : public QObject { mFusionShowLegend = show; } + + //set/get fusionSequence related data + void SetFusionSequenceFrameIndex(int sequenceFrameIndex) { mFusionSequenceFrameIndex = sequenceFrameIndex; } + void SetFusionSequenceSpatialSyncFlag(bool spatialSync) { mFusionSequenceSpatialSyncFlag = spatialSync; } + void SetFusionSequenceTemporalSyncFlag(bool temporalSync) { mFusionSequenceTemporalSyncFlag = temporalSync; } + void SetFusionSequenceLength(unsigned int fusionSequenceNbFrames) { mFusionSequenceNbFrames = fusionSequenceNbFrames; } + void SetFusionSequenceMainTransformMatrix(vtkSmartPointer mat) { + mFusionSequenceMainTransform = vtkSmartPointer::New(); + mFusionSequenceMainTransform->DeepCopy(mat); + } + void AddFusionSequenceInitialTransformMatrices(vtkSmartPointer mat) { + vtkSmartPointer tmpMat = vtkSmartPointer::New(); + tmpMat->DeepCopy(mat); + mFusionSequenceListInitialTransformMatrices.push_back( tmpMat ); + } + void SetFusionSequenceIndexOfLinkedManager(int index) { mFusionSequenceIndexLinkedManager = index; } + void SetFusionSequenceTemporalSignal(std::vector s) { mFusionSequenceTemporalSignal = s; } + + void SetFusionSequenceInvolvmentCode(int code) { mFusionSequenceInvolvementCode=code; } + int GetFusionSequenceInvolvmentCode() { return mFusionSequenceInvolvementCode;} + bool IsInvolvedInFusionSequence() {return (!(mFusionSequenceInvolvementCode==-1));} + bool IsMainSequenceOfFusionSequence() {return (mFusionSequenceInvolvementCode==0);} + bool IsSecondarySequenceOfFusionSequence() {return (mFusionSequenceInvolvementCode==1);} + + int GetFusionSequenceIndexOfLinkedManager() { return mFusionSequenceIndexLinkedManager; } + int GetFusionSequenceFrameIndex() { return mFusionSequenceFrameIndex; } + bool GetFusionSequenceSpatialSyncFlag() { return mFusionSequenceSpatialSyncFlag; } + bool GetFusionSequenceTemporalSyncFlag() { return mFusionSequenceTemporalSyncFlag; } + unsigned int GetFusionSequenceNbFrames() { return mFusionSequenceNbFrames; } + const vtkSmartPointer& GetFusionSequenceMainTransformMatrix() {return mFusionSequenceMainTransform;} + const std::vector< vtkSmartPointer >& GetFusionSequenceInitialTransformMatrices() {return mFusionSequenceListInitialTransformMatrices;} + const vtkSmartPointer& GetFusionSequenceInitialTransformMatrixAtFrame(unsigned i) { + return mFusionSequenceListInitialTransformMatrices[i]; + } + const std::vector& GetFusionSequenceTemporalSignal() {return mFusionSequenceTemporalSignal;} + double GetColorWindow() const; double GetColorLevel() const; double GetOverlayColorWindow() const; @@ -179,6 +218,7 @@ class vvSlicerManager : public QObject { return mFusionLevel; } + void SetCursorAndCornerAnnotationVisibility(int s); void UpdateViews(int current, int slicer); void UpdateLinked(int slicer); @@ -207,6 +247,7 @@ class vvSlicerManager : public QObject { void Reload(); void ReloadOverlay(); void ReloadFusion(); + void ReloadFusionSequence(); void ReloadVF(); void Activated(); @@ -236,11 +277,12 @@ signals : void UpdateVector(int display, double x, double y, double z, double value); void UpdateOverlay(int display, double valueOver, double valueRef); void UpdateFusion(int display, double valueFus); + void UpdateFusionSequence(int fusionSequenceFrameIndex, bool fusionSequenceSpatialSyncFlag, unsigned int fusionSequenceNbFrames); void MousePositionUpdatedSignal(int slicer); void KeyPressedSignal(std::string KeyPressed); void UpdateOrientation(int slicer, int orientation); void UpdateSlice(int slicer, int slice); - void UpdateTSlice(int slicer, int slice); + void UpdateTSlice(int slicer, int slice, int code); void UpdateSliceRange(int slice, int min, int max, int tmin, int tmax); void WindowLevelChanged(); void UpdateLinkManager(std::string, int slicer, double x, double y, double z, int temps); @@ -256,6 +298,7 @@ protected: vvImageReader::Pointer mReader; vvImageReader::Pointer mOverlayReader; vvImageReader::Pointer mFusionReader; + vvImageReader::Pointer mFusionSequenceReader; vvImageReader::Pointer mVectorReader; vvImage::Pointer mImage; vvImage::Pointer mVF; @@ -269,6 +312,16 @@ protected: double mFusionLevel; bool mFusionShowLegend; + //Fusion of sequences related data + int mFusionSequenceInvolvementCode; //-1: not involved, 0: main sequence(CT), 1: secondary sequence (US) + int mFusionSequenceIndexLinkedManager; //index of the other sequence involved in the visualization + int mFusionSequenceFrameIndex; //temporal index of the current image in the sequence (<->TSlice) + unsigned int mFusionSequenceNbFrames; //number of frames in the temporal sequence + bool mFusionSequenceSpatialSyncFlag, mFusionSequenceTemporalSyncFlag; //flags indicating whether the spatial/temporal synchronization are actives + vtkSmartPointer mFusionSequenceMainTransform; + std::vector< vtkSmartPointer > mFusionSequenceListInitialTransformMatrices; + std::vector mFusionSequenceTemporalSignal; + int mPreset; SlicingPresetType mSlicingPreset; vvImageReader::LoadedImageType mType; diff --git a/vv/vvToolBaseBase.h b/vv/vvToolBaseBase.h index 37d974a..fa93d14 100644 --- a/vv/vvToolBaseBase.h +++ b/vv/vvToolBaseBase.h @@ -19,6 +19,7 @@ #ifndef VVTOOLBASEBASE_H #define VVTOOLBASEBASE_H +#include #include "vvMainWindowBase.h" #include "vvToolCreatorBase.h" class QXmlStreamWriter;