From 1548a47199250d3819961adb37becac65bc72f3c Mon Sep 17 00:00:00 2001 From: rblanc Date: Tue, 4 Dec 2012 15:15:29 +0100 Subject: [PATCH] 1/ some minor changes for compilation under windows / VC++ 2010 Express 2/ 1st prototype version of the sequence fusion visualization mode (not so clean, but it works) --- CMakeLists.txt | 5 + common/clitkCommon.h | 1 + common/rtkHndImageIO.cxx | 36 ++--- common/vvImageReader.cxx | 20 ++- fast_make.sh | 0 make_meta.sh | 0 make_new_tool.sh | 0 tools/CMakeLists.txt | 4 +- tools/make_new_tool.sh | 0 utilities/CxImage/CMakeLists.txt | 0 vv/CMakeLists.txt | 2 +- vv/make_vv_class.sh | 0 vv/qt_ui/vvMainWindow.ui | 17 +- vv/qt_ui/vvOverlayPanel.ui | 116 +++++++++++++- vv/vv.cxx | 2 +- vv/vvAnimatedGIFWriter.h | 2 +- vv/vvMainWindow.cxx | 257 +++++++++++++++++++++++++++---- vv/vvMainWindow.h | 8 + vv/vvOverlayPanel.cxx | 45 +++++- vv/vvOverlayPanel.h | 8 +- vv/vvSlicer.cxx | 44 ++++-- vv/vvSlicer.h | 6 + vv/vvSlicerManager.cxx | 134 ++++++++++++++-- vv/vvSlicerManager.h | 38 +++++ vv/vvToolBaseBase.h | 1 + 25 files changed, 659 insertions(+), 87 deletions(-) mode change 100755 => 100644 fast_make.sh mode change 100755 => 100644 make_meta.sh mode change 100755 => 100644 make_new_tool.sh mode change 100755 => 100644 tools/make_new_tool.sh mode change 100755 => 100644 utilities/CxImage/CMakeLists.txt mode change 100755 => 100644 vv/make_vv_class.sh 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..b7f73a2 100644 --- a/vv/qt_ui/vvOverlayPanel.ui +++ b/vv/qt_ui/vvOverlayPanel.ui @@ -6,8 +6,8 @@ 0 0 - 344 - 480 + 444 + 815 @@ -36,6 +36,118 @@ p, li { white-space: pre-wrap; } + + + + true + + + + 0 + 0 + + + + + 0 + 70 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + false + + + + 270 + 10 + 80 + 17 + + + + Temporal + + + + + + 210 + 10 + 61 + 17 + + + + Spatial + + + true + + + + + + 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 + 181 + 20 + + + + Qt::Horizontal + + + + diff --git a/vv/vv.cxx b/vv/vv.cxx index 47057e4..8ad9140 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 22041df..a1bdc96 100644 --- a/vv/vvMainWindow.cxx +++ b/vv/vvMainWindow.cxx @@ -181,6 +181,10 @@ vvMainWindow::vvMainWindow():vvMainWindowBase() contextMenu.addAction(actionAdd_fusion_image); contextActions.push_back(actionAdd_fusion_image); + contextMenu.addAction(actionAdd_USSequence_toCT); + contextActions.push_back(actionAdd_USSequence_toCT); + + contextMenu.addSeparator(); QAction* actionResetMatrix = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/identity.png")), tr("Reset transformation to identity")); @@ -234,6 +238,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 +286,13 @@ 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(actionSegmentation,SIGNAL(triggered()),this,SLOT(SegmentationOnCurrentImage())); connect(actionSurface_Viewer,SIGNAL(triggered()),this,SLOT(SurfaceViewerLaunch())); @@ -325,6 +333,10 @@ vvMainWindow::vvMainWindow():vvMainWindowBase() this,SLOT(SetFusionProperty(int,int,int,double,double, bool))); connect(landmarksPanel,SIGNAL(UpdateRenderWindows()),this,SLOT(UpdateRenderWindows())); + connect(overlayPanel,SIGNAL(FusionSequencePropertyUpdated(int, bool, unsigned int)), + this,SLOT(SetFusionSequenceProperty(int, bool,unsigned int))); + + playMode = 0;//pause mFrameRate = 10; playButton->setEnabled(0); @@ -361,6 +373,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase() //timerMemory->setInterval(5); connect(timerMemory, SIGNAL(timeout()), this, SLOT(UpdateMemoryUsage())); timerMemory->start(2000); + } //------------------------------------------------------------------------------ void vvMainWindow::show() @@ -904,6 +917,8 @@ void vvMainWindow::LoadImages(std::vector files, vvImageReader::Loa this, SLOT(OverlayChanged(int,double,double))); connect(mSlicerManagers.back(), SIGNAL(UpdateFusion(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())); connect(mSlicerManagers.back(), SIGNAL(UpdateSlice(int,int)), @@ -1013,6 +1028,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); @@ -1028,13 +1044,14 @@ 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") { + 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; } } - std::vector origin; + std::vector origin; std::vector inputSpacing; std::vector inputSize; std::vector sizeMM; @@ -1044,7 +1061,7 @@ void vvMainWindow::ImageInfoChanged() QString inputSizeInBytes; QString image = DataTree->selectedItems()[0]->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString(); - int nframes = mSlicerManagers[index]->GetSlicer(0)->GetTMax(); + int nframes = mSlicerManagers[index]->GetSlicer(0)->GetTMax(); if (nframes > 1 || playMode == 1) { playButton->setEnabled(1); frameRateLabel->setEnabled(1); @@ -1058,7 +1075,7 @@ void vvMainWindow::ImageInfoChanged() //read image header int NPixel = 1; - int tSlice = 0; + int tSlice = 0; vvImage::Pointer imageSelected; if (DataTree->topLevelItem(index) == DataTree->selectedItems()[0]) { imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage(); @@ -1070,19 +1087,23 @@ void vvMainWindow::ImageInfoChanged() imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetOverlay(); tSlice = mSlicerManagers[index]->GetSlicer(0)->GetOverlayTSlice(); } else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "fusion") { - imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetFusion(); - tSlice = mSlicerManagers[index]->GetSlicer(0)->GetFusionTSlice(); + 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(); + imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage(); + tSlice = mSlicerManagers[index]->GetSlicer(0)->GetTSlice(); } else { - imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage(); - tSlice = mSlicerManagers[index]->GetSlicer(0)->GetTSlice(); + imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage(); + tSlice = mSlicerManagers[index]->GetSlicer(0)->GetTSlice(); } - dimension = imageSelected->GetNumberOfDimensions(); + dimension = imageSelected->GetNumberOfDimensions(); origin.resize(dimension); inputSpacing.resize(dimension); inputSize.resize(dimension); @@ -1096,7 +1117,7 @@ void vvMainWindow::ImageInfoChanged() NPixel *= inputSize[i]; } inputSizeInBytes = GetSizeInBytes(imageSelected->GetActualMemorySize()*1000); - + QString dim = QString::number(dimension) + " ("; dim += pixelType + ")"; @@ -1107,10 +1128,11 @@ void vvMainWindow::ImageInfoChanged() infoPanel->setOrigin(GetVectorDoubleAsString(origin)); infoPanel->setSpacing(GetVectorDoubleAsString(inputSpacing)); infoPanel->setNPixel(QString::number(NPixel)+" ("+inputSizeInBytes+")"); - transformation = imageSelected->GetTransform()[tSlice]->GetMatrix(); + + transformation = imageSelected->GetTransform()[tSlice]->GetMatrix(); infoPanel->setTransformation(Get4x4MatrixDoubleAsString(transformation)); - landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(), + landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(), mSlicerManagers[index]->GetSlicer(0)->GetImage()->GetVTKImages().size()); landmarksPanel->SetCurrentPath(mInputPathName.toStdString()); landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str()); @@ -1123,7 +1145,7 @@ void vvMainWindow::ImageInfoChanged() } } - infoPanel->setFileName(image); + infoPanel->setFileName(image); infoPanel->setDimension(dim); infoPanel->setSizePixel(GetVectorIntAsString(inputSize)); infoPanel->setSizeMM(GetVectorDoubleAsString(sizeMM)); @@ -1143,10 +1165,11 @@ void vvMainWindow::ImageInfoChanged() break; } } - WindowLevelChanged(); + + WindowLevelChanged(); slicingPresetComboBox->setCurrentIndex(mSlicerManagers[index]->GetSlicingPreset()); - if (mSlicerManagers[index]->GetSlicer(0)->GetVF()) { + 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(), @@ -1160,8 +1183,8 @@ void vvMainWindow::ImageInfoChanged() } else { overlayPanel->getOverlayName(mSlicerManagers[index]->GetOverlayName().c_str()); } - - if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) { + + if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) { overlayPanel->getFusionName(mSlicerManagers[index]->GetFusionName().c_str()); } else { overlayPanel->getFusionName(mSlicerManagers[index]->GetFusionName().c_str()); @@ -1622,6 +1645,9 @@ void vvMainWindow::ReloadImage(QTreeWidgetItem* item, int column) else if (role == "fusion"){ mSlicerManagers[index]->ReloadFusion(); } + else if (role == "fusionSequence"){ + mSlicerManagers[index]->ReloadFusionSequence(); //same as for standard fusion + } else{ mSlicerManagers[index]->Reload(); } @@ -1680,15 +1706,22 @@ void vvMainWindow::WindowLevelChanged() else overlayPanel->getOverlayProperty(-1,0,0.,0.); - // Fusion image - if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) - overlayPanel->getFusionProperty(mSlicerManagers[index]->GetFusionOpacity(), - mSlicerManagers[index]->GetFusionThresholdOpacity(), - mSlicerManagers[index]->GetFusionColorMap(), - mSlicerManagers[index]->GetFusionWindow(), - mSlicerManagers[index]->GetFusionLevel()); + // 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()); + overlayPanel->getFusionSequenceProperty(mSlicerManagers[index]->GetFusionSequenceFrameIndex(), + mSlicerManagers[index]->GetFusionSequenceSpatialSyncFlag(), + mSlicerManagers[index]->GetFusionSequenceNbFrames()); + } else - overlayPanel->getFusionProperty(-1, -1, -1, -1, -1); + { + overlayPanel->getFusionProperty(-1, -1, -1, -1, -1); + overlayPanel->getFusionSequenceProperty(-1, false, 0); + } } //------------------------------------------------------------------------------ @@ -2013,7 +2046,8 @@ 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") { + 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(); @@ -2293,11 +2327,170 @@ void vvMainWindow::SetFusionProperty(int opacity, int thresOpacity, int colormap mSlicerManagers[index]->SetFusionLevel(level); mSlicerManagers[index]->SetFusionShowLegend(showLegend); mSlicerManagers[index]->SetColorMap(0); - mSlicerManagers[index]->Render(); + mSlicerManagers[index]->Render(); } } //------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +void vvMainWindow::SelectFusionSequence() +{ + int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); + //check if one overlay image is added + for (int child = 0; child < DataTree->topLevelItem(index)->childCount(); child++) + if ( (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "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()); + } + + AddFusionSequence(index,vecFileNames,vvImageReader::MERGEDWITHTIME); +} +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +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); + + } else { + QApplication::restoreOverrideCursor(); + QString error = "Cannot import the new image.\n"; + error += mSlicerManagers[index]->GetLastError().c_str(); + QMessageBox::information(this,tr("Problem reading image !"),error); + } + WindowLevelChanged(); + } + else + QMessageBox::information(this,tr("Problem reading fusion sequence !"),"File doesn't exist!"); +} +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +void vvMainWindow::SetFusionSequenceProperty(int fusionSequenceFrameIndex, bool spatialSyncFlag, unsigned int fusionSequenceNbFrames) +{ + int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]); + if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) { + int indexParent = GetSlicerIndexFromItem( DataTree->topLevelItem(index) ); + + mSlicerManagers[index]->SetFusionSequenceLength(fusionSequenceNbFrames); + mSlicerManagers[index]->SetFusionSequenceSpatialSyncFlag(spatialSyncFlag); + mSlicerManagers[index]->SetFusionSequenceFrameIndex(fusionSequenceFrameIndex); + + if (spatialSyncFlag) { //reslice the CT + //show the right frame of the US sequence + mSlicerManagers[index]->SetFusionSequenceTSlice(fusionSequenceFrameIndex); + + //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[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[i]->SetMatrix( mSlicerManagers[index]->GetFusionSequenceMainTransformMatrix() ); + mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[i]->PreMultiply(); + mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[i]->Concatenate( tmpMat ); + mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[i]->Update(); + } + + for (int i=0; iGetNumberOfSlicers(); i++) { + mSlicerManagers[indexParent]->GetSlicer(i)->ForceUpdateDisplayExtent(); + mSlicerManagers[indexParent]->GetSlicer(i)->Render(); + } + } + else { //flag is off. + //rather use a different method for switching on/off... or check whether the matrix is the same... + //TODO: reset the CT to its original state, as well as the US + } + + //TODO: recenter the view so that the US frame is visible? + //or when adding the sequence, also add the sequence as an independent image that is automatically linked, to guide the views... + } +} +//------------------------------------------------------------------------------ + + //------------------------------------------------------------------------------ void vvMainWindow::SaveAs() { @@ -3142,7 +3335,9 @@ vvSlicerManager* vvMainWindow::AddImage(vvImage::Pointer image,std::string filen connect(mSlicerManagers.back(), SIGNAL(UpdateOverlay(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())); connect(mSlicerManagers.back(), SIGNAL(UpdateSlice(int,int)), diff --git a/vv/vvMainWindow.h b/vv/vvMainWindow.h index e308314..f9e18b1 100644 --- a/vv/vvMainWindow.h +++ b/vv/vvMainWindow.h @@ -57,6 +57,9 @@ 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); + ///Adds a mesh to a SlicerManager, with optional warping by vector field void AddContour(int image_index, vvMesh::Pointer contour, bool propagation); ///This is used to show an image when opened or computed @@ -107,6 +110,7 @@ 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(); @@ -153,11 +157,15 @@ public slots: void OpenField(); void SelectOverlayImage(); void SelectFusionImage(); + //select the file(s) from the disk containing the image sequence to fuse + void SelectFusionSequence(); + 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); void GoToCursor(); void PlayPause(); diff --git a/vv/vvOverlayPanel.cxx b/vv/vvOverlayPanel.cxx index 346bd2c..e205c87 100644 --- a/vv/vvOverlayPanel.cxx +++ b/vv/vvOverlayPanel.cxx @@ -34,12 +34,14 @@ vvOverlayPanel::vvOverlayPanel(QWidget * parent):QWidget(parent) vFFrame->hide(); compareFrame->hide(); fusionFrame->hide(); + fCTUSFrame->hide(); subSamplingSpinBox->setEnabled(0); scaleSpinBox->setEnabled(0); lutCheckBox->hide(); lutCheckBox->setEnabled(0); fusionShowLegendCheckBox->setChecked(false); - + fCTUSActivateSpaceSyncCheckBox->setChecked(true); + connect(subSamplingSpinBox,SIGNAL(editingFinished()),this,SLOT(setVFProperty())); connect(scaleSpinBox,SIGNAL(editingFinished()),this,SLOT(setVFProperty())); connect(lutCheckBox,SIGNAL(clicked()),this,SLOT(setVFProperty())); @@ -58,7 +60,11 @@ vvOverlayPanel::vvOverlayPanel(QWidget * parent):QWidget(parent) connect(overlayLevelSpinBox,SIGNAL(valueChanged(double)),this,SLOT(setOverlayProperty())); connect(overlayLinkCheckBox,SIGNAL(stateChanged(int)),this,SLOT(setOverlayProperty())); + connect(fCTUSSlider,SIGNAL(valueChanged(int)),this,SLOT(setFusionSequenceProperty())); + connect(fCTUSActivateSpaceSyncCheckBox,SIGNAL(stateChanged(int)),this,SLOT(setFusionSequenceProperty())); + disableFusionSignals = false; + disableFusionSequenceSignals = false; } void vvOverlayPanel::getCurrentImageName(QString name) @@ -225,7 +231,7 @@ void vvOverlayPanel::setFusionProperty() { if (disableFusionSignals) return; - + fusionOpacitySpin->setValue(opacityHorizontalSlider->value()); fusionThresSpin->setValue(thresOpacityHorizontalSlider->value()); @@ -248,6 +254,41 @@ void vvOverlayPanel::getCurrentFusionInfo(int visibility,double value) valueFusionnedLabel->setText(fusionValue); } + +void vvOverlayPanel::getFusionSequenceProperty(int sequenceFrameIndex, bool spatialSync, unsigned int sequenceLenth) +{ + 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); + disableFusionSequenceSignals = false; + setFusionSequenceProperty(); + } else { + fCTUSFrame->hide(); + fCTUSFrame->setEnabled(0); + fCTUSSlider->setEnabled(0); + fCTUSSlider->setValue(0); + fCTUSSlider->setMaximum(0); + fCTUSActivateSpaceSyncCheckBox->setCheckState(Qt::Unchecked); + } +} + + +void vvOverlayPanel::setFusionSequenceProperty() +{ + if (disableFusionSequenceSignals) + return; + + emit FusionSequencePropertyUpdated(fCTUSSlider->value(), fCTUSActivateSpaceSyncCheckBox->isChecked(), fCTUSSlider->maximum()); +} + + + void vvOverlayPanel::VFColorChangeRequest() { QColor color(vfColorButton->palette().color(QPalette::Background)); diff --git a/vv/vvOverlayPanel.h b/vv/vvOverlayPanel.h index bd9e972..69abbc2 100644 --- a/vv/vvOverlayPanel.h +++ b/vv/vvOverlayPanel.h @@ -44,9 +44,12 @@ public: 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 getFusionSequenceProperty(int sequenceFrameIndex, bool spatialSync, unsigned int sequenceLength); + + 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); + //void getCurrentFusionSequenceInfo(int visibility,double value); bool getShowLegend(); @@ -56,15 +59,18 @@ public slots: void setFusionProperty(); void setFusionSpinProperty(); void VFColorChangeRequest(); + void setFusionSequenceProperty(); 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 FusionSequencePropertyUpdated(int sequenceFrameIndex, bool spatialSync, unsigned int sequenceLength); private: bool disableFusionSignals; + bool disableFusionSequenceSignals; }; // end class vvOverlayPanel //==================================================================== diff --git a/vv/vvSlicer.cxx b/vv/vvSlicer.cxx index 1e1245f..1ace5c2 100644 --- a/vv/vvSlicer.cxx +++ b/vv/vvSlicer.cxx @@ -475,7 +475,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 +497,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 +641,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; @@ -726,6 +726,7 @@ void vvSlicer::SetTSlice(int t) if (mVF->GetVTKImages().size() > (unsigned int)mCurrentTSlice) mVOIFilter->SetInput(mVF->GetVTKImages()[mCurrentTSlice]); } +//also temporarilly disabled... if (mOverlay && mOverlayActor->GetVisibility()) { if (mOverlay->GetVTKImages().size() > (unsigned int)t) { mCurrentOverlayTSlice = t; @@ -737,6 +738,32 @@ void vvSlicer::SetTSlice(int t) mConcatenatedOverlayTransform->Concatenate(mSlicingTransform); } } +//temporarilly disabled for testing fusionSequence + //if (mFusion && mFusionActor->GetVisibility()) { + // if (mFusion->GetVTKImages().size() > (unsigned int)t) { + // mCurrentFusionTSlice = t; + // mFusionReslice->SetInput( mFusion->GetVTKImages()[mCurrentFusionTSlice]); + + // // Update fusion transform + // mConcatenatedFusionTransform->Identity(); + // mConcatenatedFusionTransform->Concatenate(mFusion->GetTransform()[mCurrentFusionTSlice]); + // mConcatenatedFusionTransform->Concatenate(mSlicingTransform); + // } + //} + if (mSurfaceCutActors.size() > 0) + for (std::vector::iterator i=mSurfaceCutActors.begin(); + i!=mSurfaceCutActors.end(); i++) + (*i)->SetTimeSlice(mCurrentTSlice); + UpdateDisplayExtent(); +} +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +void vvSlicer::SetFusionSequenceTSlice(int t) +{ +//QMessageBox::information(NULL, "vvSlicer::SetFusionSequenceTSlice", "ENTER, t = " + QString::number(t) + ", currentFusionTSlice = " + QString::number(mCurrentFusionTSlice)); + //fusionSequence data is stored behind standard fusion data... if (mFusion && mFusionActor->GetVisibility()) { if (mFusion->GetVTKImages().size() > (unsigned int)t) { mCurrentFusionTSlice = t; @@ -748,10 +775,7 @@ void vvSlicer::SetTSlice(int t) mConcatenatedFusionTransform->Concatenate(mSlicingTransform); } } - if (mSurfaceCutActors.size() > 0) - for (std::vector::iterator i=mSurfaceCutActors.begin(); - i!=mSurfaceCutActors.end(); i++) - (*i)->SetTimeSlice(mCurrentTSlice); + UpdateDisplayExtent(); } //------------------------------------------------------------------------------ @@ -770,8 +794,9 @@ int vvSlicer::GetMaxCurrentTSlice() int t = mCurrentTSlice; if(mOverlay) t = std::max(t, mCurrentOverlayTSlice); - if(mFusion) - t = std::max(t, mCurrentFusionTSlice); + //TODO temporarily desactivated... + //if(mFusion) + // t = std::max(t, mCurrentFusionTSlice); return t; } //------------------------------------------------------------------------------ @@ -1008,7 +1033,6 @@ void vvSlicer::UpdateDisplayExtent() } } } - } //---------------------------------------------------------------------------- diff --git a/vv/vvSlicer.h b/vv/vvSlicer.h index a738a78..793b5f3 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" @@ -98,6 +101,9 @@ public: void SetLandmarks(vvLandmarks* landmarks); void SetTSlice(int t); + + void SetFusionSequenceTSlice(int t); + void SetSliceOrientation(int orientation); void AdjustResliceToSliceOrientation(vtkImageReslice *reslice); int GetTSlice(); diff --git a/vv/vvSlicerManager.cxx b/vv/vvSlicerManager.cxx index b175c46..b3cd57e 100644 --- a/vv/vvSlicerManager.cxx +++ b/vv/vvSlicerManager.cxx @@ -40,7 +40,6 @@ #include #include - //---------------------------------------------------------------------------- vvSlicerManager::vvSlicerManager(int numberOfSlicers) { @@ -63,6 +62,10 @@ vvSlicerManager::vvSlicerManager(int numberOfSlicers) mFusionLevel = 1000; mFusionShowLegend = true; + mFusionSequenceFrameIndex = -1; + mFusionSequenceSpatialSyncFlag = false; + mFusionSequenceNbFrames = 0; + mLandmarks = NULL; mLinkedId.resize(0); @@ -73,6 +76,8 @@ vvSlicerManager::vvSlicerManager(int numberOfSlicers) mPreviousSlice.resize(numberOfSlicers); mPreviousTSlice.resize(numberOfSlicers); mSlicingPreset = WORLD_SLICING; + + } //---------------------------------------------------------------------------- @@ -139,6 +144,8 @@ std::string vvSlicerManager::GetListOfAbsoluteFilePathInOneString(const std::str reader = mFusionReader; else if(actorType=="vector") reader = mVectorReader; + else if(actorType=="fusionSequence") + reader = mFusionSequenceReader; if(!reader) return ""; @@ -298,6 +305,54 @@ bool vvSlicerManager::SetFusion(std::string filename,int dim, std::string compon } //---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +bool vvSlicerManager::SetFusionSequence(std::vector filenames,int dim, std::string component, vvImageReader::LoadedImageType type) +{ + 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); + + //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... + if (mFusionSequenceFrameIndex>=mFusionSequenceNbFrames) { + mFusionSequenceFrameIndex=0; + } + + + if (mFusionSequenceReader->GetLastError().size() == 0) { + for ( unsigned int i = 0; i < mSlicers.size(); i++) { + mSlicers[i]->SetFusion(mFusionSequenceReader->GetOutput()); + } + } else { + mLastError = mFusionSequenceReader->GetLastError(); + return false; + } + double *fusRange = mFusionSequenceReader->GetOutput()->GetVTKImages()[0]->GetScalarRange(); + mFusionLevel = (fusRange[0]+fusRange[1])/2; + mFusionWindow = fusRange[1]-fusRange[0]; + + return true; +} +//---------------------------------------------------------------------------- + //---------------------------------------------------------------------------- bool vvSlicerManager::SetVF(std::string filename) @@ -468,6 +523,17 @@ void vvSlicerManager::SetTSlice(int slice) //---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +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) { @@ -810,6 +876,9 @@ void vvSlicerManager::ResetTransformationToIdentity(const std::string actorType) 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(); @@ -851,6 +920,7 @@ void vvSlicerManager::Reload() for ( unsigned int i = 0; i < mSlicers.size(); i++) { mSlicers[i]->SetImage(mImage); } + //TODO: check if this image is involved in a fusion sequence, then the main transform matrix should be updated. } //---------------------------------------------------------------------------- @@ -867,6 +937,33 @@ void vvSlicerManager::ReloadFusion() } //---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +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()); + mSlicers[i]->Render(); + } + + //Update the slider + mFusionSequenceNbFrames = mFusionSequenceReader->GetOutput()->GetTransform().size(); + if (mFusionSequenceFrameIndex>=mFusionSequenceNbFrames) { + mFusionSequenceFrameIndex=0; + } + + //Update the list of initial transforms + //Warning, the main transform will not be updated on reload......... + mFusionSequenceListInitialTransformMatrices.clear(); + for (unsigned i=0 ; iAddFusionSequenceInitialTransformMatrices( mFusionSequenceReader->GetOutput()->GetTransform()[i]->GetMatrix() ); + } + + //emit UpdateFusionSequence(mFusionSequenceFrameIndex, mFusionSequenceSpatialSyncFlag, mFusionSequenceNbFrames); +} +//---------------------------------------------------------------------------- + //---------------------------------------------------------------------------- void vvSlicerManager::ReloadOverlay() @@ -902,6 +999,10 @@ void vvSlicerManager::RemoveActor(const std::string& actor_type, int overlay_ind 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); @@ -984,14 +1085,17 @@ void vvSlicerManager::UpdateInfoOnCursorPosition(int slicer) 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); - } + + 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); @@ -1204,6 +1308,7 @@ void vvSlicerManager::SetLocalColorWindowing(const int slicer, const bool bCtrlK void vvSlicerManager::SetColorMap(int colormap) { double range[2]; + range[0] = mSlicers[0]->GetInput()->GetScalarRange()[0]; range[1] = mSlicers[0]->GetInput()->GetScalarRange()[1]; @@ -1261,12 +1366,17 @@ void vvSlicerManager::SetColorMap(int colormap) } vtkWindowLevelLookupTable* fusLUT = NULL; if (mSlicers[0]->GetFusion()) { // && mFusionColorMap >= 0) { - fusLUT = vtkWindowLevelLookupTable::New(); + 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); + + //check whether it is actually a fusionSequence or a fusion, before invoking mFusionReader... + double* frange; + if (mFusionReader.IsNull()) 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); diff --git a/vv/vvSlicerManager.h b/vv/vvSlicerManager.h index 4fc274c..ffaea78 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 @@ -114,6 +115,8 @@ class vvSlicerManager : public QObject { 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,30 @@ class vvSlicerManager : public QObject { mFusionShowLegend = show; } + + //set/get fusionSequence related data + void SetFusionSequenceFrameIndex(int sequenceFrameIndex) { mFusionSequenceFrameIndex = sequenceFrameIndex; } + void SetFusionSequenceSpatialSyncFlag(bool spatialSync) { mFusionSequenceSpatialSyncFlag = spatialSync; } + 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 ); + } + + int GetFusionSequenceFrameIndex() { return mFusionSequenceFrameIndex; } + bool GetFusionSequenceSpatialSyncFlag() { return mFusionSequenceSpatialSyncFlag; } + 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]; + } + double GetColorWindow() const; double GetColorLevel() const; double GetOverlayColorWindow() const; @@ -179,6 +206,7 @@ class vvSlicerManager : public QObject { return mFusionLevel; } + void SetCursorAndCornerAnnotationVisibility(int s); void UpdateViews(int current, int slicer); void UpdateLinked(int slicer); @@ -207,6 +235,7 @@ class vvSlicerManager : public QObject { void Reload(); void ReloadOverlay(); void ReloadFusion(); + void ReloadFusionSequence(); void ReloadVF(); void Activated(); @@ -236,6 +265,7 @@ 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); @@ -256,6 +286,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 +300,13 @@ protected: double mFusionLevel; bool mFusionShowLegend; + //fusionSequence related data + int mFusionSequenceFrameIndex; + bool mFusionSequenceSpatialSyncFlag; + unsigned int mFusionSequenceNbFrames; + vtkSmartPointer mFusionSequenceMainTransform; + std::vector< vtkSmartPointer > mFusionSequenceListInitialTransformMatrices; + 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; -- 2.47.1