#include <vtkCamera.h>\r
\r
#include <qfileinfo.h>\r
+#include <QMessageBox>\r
//----------------------------------------------------------------------------\r
vvSlicerManager::vvSlicerManager(int numberOfSlicers)\r
{\r
mFusionLevel = 1000;\r
mFusionShowLegend = true;\r
\r
+ mFusionSequenceInvolvementCode = -1;\r
+ mFusionSequenceIndexLinkedManager = -1;\r
mFusionSequenceFrameIndex = -1;\r
- mFusionSequenceSpatialSyncFlag = false;\r
mFusionSequenceNbFrames = 0;\r
- mFusionSequenceIndexLinkedManager = -1;\r
+ mFusionSequenceSpatialSyncFlag = false;\r
+ mFusionSequenceTemporalSyncFlag = false;\r
\r
mLandmarks = NULL;\r
mLinkedId.resize(0);\r
mSlicers.push_back(vtkSmartPointer<vvSlicer>::New());\r
mSelectedSlicer = -1;\r
\r
- mPreviousSlice.resize(numberOfSlicers);\r
- mPreviousTSlice.resize(numberOfSlicers);\r
+ mPreviousSlice.resize(numberOfSlicers, 0);\r
+ mPreviousTSlice.resize(numberOfSlicers, 0);\r
mSlicingPreset = WORLD_SLICING;\r
\r
\r
\r
\r
//----------------------------------------------------------------------------\r
-bool vvSlicerManager::SetFusion(std::string filename,int dim, std::string component)\r
+bool vvSlicerManager::SetFusion(std::vector<std::string> filenames,int dim, std::string component, vvImageReader::LoadedImageType type)\r
{\r
- mFusionName = filename;\r
+ mFusionName = filenames[0];\r
mFusionComponent = component;\r
if (dim > mImage->GetNumberOfDimensions()) {\r
- mLastError = " Overlay dimension cannot be greater then reference image!";\r
+ mLastError = " Fusion dimension cannot be greater than reference image!";\r
return false;\r
}\r
if (mFusionReader.IsNull())\r
mFusionReader = vvImageReader::New();\r
- std::vector<std::string> filenames;\r
- filenames.push_back(filename);\r
mFusionReader->SetInputFilenames(filenames);\r
- mFusionReader->Update(mImage->GetNumberOfDimensions(),component.c_str(),mType);\r
+ mFusionReader->Update(type);\r
if (mFusionReader->GetLastError().size() == 0) {\r
for ( unsigned int i = 0; i < mSlicers.size(); i++) {\r
mSlicers[i]->SetFusion(mFusionReader->GetOutput());\r
//----------------------------------------------------------------------------\r
\r
//----------------------------------------------------------------------------\r
-bool vvSlicerManager::SetFusionSequence(std::vector<std::string> filenames,int dim, std::string component, vvImageReader::LoadedImageType type)\r
+//this function is called by vvMainWindow::AddFusionSequence for the primary sequence (CT), while the given files constitute the secondary sequence.\r
+bool vvSlicerManager::SetFusionSequence(std::vector<std::string> filenames, int dim, std::string component, vvImageReader::LoadedImageType type)\r
{\r
+ mFusionSequenceInvolvementCode = 0;\r
+\r
mFusionName = filenames[0];\r
mFusionComponent = component;\r
\r
\r
if (mFusionSequenceReader->GetLastError().size() == 0) {\r
for ( unsigned int i = 0; i < mSlicers.size(); i++) {\r
- mSlicers[i]->SetFusion(mFusionSequenceReader->GetOutput(), true);\r
+ mSlicers[i]->SetFusion(mFusionSequenceReader->GetOutput(), mFusionSequenceInvolvementCode);\r
}\r
} else {\r
mLastError = mFusionSequenceReader->GetLastError();\r
}\r
\r
//adjust the time slider in the overlay panel\r
- mFusionSequenceNbFrames = mFusionSequenceReader->GetOutput()->GetTransform().size()-1; //actually, this is the maximum index...\r
+ mFusionSequenceNbFrames = mFusionSequenceReader->GetOutput()->GetTransform().size(); \r
mFusionSequenceFrameIndex = std::max<int>( 0, std::min<int>(mFusionSequenceFrameIndex, mFusionSequenceNbFrames));\r
\r
return true;\r
//----------------------------------------------------------------------------\r
void vvSlicerManager::UpdateSlicer(int num, bool state)\r
{\r
- if (mSlicers[num]->GetImage())\r
+ if (mSlicers[num]->GetImage()) {\r
mSlicers[num]->SetDisplayMode(state);\r
+ }\r
}\r
//----------------------------------------------------------------------------\r
\r
//----------------------------------------------------------------------------\r
void vvSlicerManager::SetTSlice(int slice, bool updateLinkedImages)\r
{\r
- if (!updateLinkedImages) {\r
+ if (!updateLinkedImages) { //for fusionSequence, TMax / MaxCurrentTSlice are irrelevant.\r
for ( unsigned int i = 0; i < mSlicers.size(); i++) {\r
mSlicers[i]->SetTSlice(slice, updateLinkedImages);\r
UpdateTSlice(i);\r
return;\r
}\r
\r
-\r
if (slice < 0)\r
slice = 0;\r
else if (slice > mSlicers[0]->GetTMax())\r
if (t > mSlicers[0]->GetTMax())\r
t = 0;\r
//std::cout << "vvSlicerManager::SetNextTSlice" << std::endl;\r
- emit UpdateTSlice(originating_slicer,t);\r
+ emit UpdateTSlice(originating_slicer,t, mFusionSequenceInvolvementCode);\r
}\r
//----------------------------------------------------------------------------\r
\r
if (t < 0)\r
t = mSlicers[0]->GetTMax();\r
//std::cout << "vvSlicerManager::SetPreviousTSlice" << std::endl;\r
- emit UpdateTSlice(originating_slicer,t);\r
+ emit UpdateTSlice(originating_slicer,t, mFusionSequenceInvolvementCode);\r
}\r
//----------------------------------------------------------------------------\r
\r
z >= mSlicers[slicer]->GetInput()->GetWholeExtent()[4]-0.5 &&\r
z <= mSlicers[slicer]->GetInput()->GetWholeExtent()[5]+0.5) {\r
for (std::list<std::string>::const_iterator i = mLinkedId.begin(); i != mLinkedId.end(); i++) {\r
- if (mFusionSequenceIndexLinkedManager>0) {\r
+ if (this->IsInvolvedInFusionSequence()) {\r
//this SlicerManager is involved in fusionSequence => do not synchronize the times\r
emit UpdateLinkManager(*i, slicer, p[0], p[1], p[2], -1);\r
}\r
mSlicers[i]->SetImage(mImage);\r
}\r
\r
- //check if this image is involved in a fusion sequence, then the main transform matrix should be updated.\r
- if (mFusionSequenceReader.IsNotNull()) {\r
+ //if this image is the primary sequence of a fusion sequence, then the main transform matrix should be updated.\r
+ if (this->IsMainSequenceOfFusionSequence()) {\r
SetFusionSequenceMainTransformMatrix( mImage->GetTransform()[0]->GetMatrix() );\r
}\r
}\r
//----------------------------------------------------------------------------\r
\r
//----------------------------------------------------------------------------\r
+//the secondary sequence is being reloaded.\r
void vvSlicerManager::ReloadFusionSequence()\r
{\r
+ // this is to keep the slice thickness, which needs to be artificially increased for visualization\r
+ double sp_x, sp_y, sp_z;\r
+ this->GetImage()->GetVTKImages()[0]->GetSpacing(sp_x, sp_y, sp_z);\r
+\r
mFusionSequenceReader->Update(mImage->GetNumberOfDimensions(),mFusionComponent.c_str(),vvImageReader::MERGEDWITHTIME);\r
\r
for ( unsigned int i = 0; i < mSlicers.size(); i++) {\r
- mSlicers[i]->SetFusion(mFusionSequenceReader->GetOutput(), true);\r
+ mSlicers[i]->SetFusion(mFusionSequenceReader->GetOutput(), 1);\r
mSlicers[i]->Render();\r
}\r
\r
}\r
\r
//Update the list of initial transforms\r
- //Warning, the main transform will not be updated on reload.........\r
mFusionSequenceListInitialTransformMatrices.clear();\r
for (unsigned i=0 ; i<mFusionSequenceNbFrames ; i++) {\r
this->AddFusionSequenceInitialTransformMatrices( mFusionSequenceReader->GetOutput()->GetTransform()[i]->GetMatrix() );\r
}\r
\r
+ // also update the slice thickness\r
+ for (unsigned i=0 ; i<this->GetImage()->GetTransform().size() ; i++) {\r
+ sp_x = this->GetImage()->GetVTKImages()[i]->GetSpacing()[0];\r
+ sp_y = this->GetImage()->GetVTKImages()[i]->GetSpacing()[1];\r
+ this->GetImage()->GetVTKImages()[i]->SetSpacing( sp_x, sp_y, sp_z);\r
+ }\r
+\r
}\r
//----------------------------------------------------------------------------\r
\r
//----------------------------------------------------------------------------\r
void vvSlicerManager::UpdateInfoOnCursorPosition(int slicer)\r
{\r
-//TODO: this is probably here that I shall prevent the overlayPanel to disappear when the mouse goes over the linked sequence!\r
// int view = mSlicers[slicer]->GetSliceOrientation();\r
// int slice = mSlicers[slicer]->GetSlice();\r
double x = mSlicers[slicer]->GetCursorPosition()[0];\r
double Zover = (z - fusion->GetOrigin()[2]) / fusion->GetSpacing()[2];\r
valueFus = this->GetScalarComponentAsDouble(fusion, Xover, Yover, Zover);\r
}\r
- else if (mFusionSequenceIndexLinkedManager>=0) {\r
+ else if (this->IsInvolvedInFusionSequence()) { \r
+ //if the cursor moves over the 'independent' version of the secondary sequence\r
+ //do not update the panel, just keep it as it is.\r
displayFus = 1;\r
valueFus = std::numeric_limits<double>::quiet_NaN();\r
}\r
void vvSlicerManager::UpdateTSlice(int slicer)\r
{\r
int slice = mSlicers[slicer]->GetSlice();\r
+\r
int tslice = mSlicers[slicer]->GetMaxCurrentTSlice();\r
- \r
- if (mFusionSequenceIndexLinkedManager>=0) tslice = mSlicers[slicer]->GetTSlice();\r
+ //if (this->IsInvolvedInFusionSequence()) tslice = mSlicers[slicer]->GetTSlice(); //actually, this is handled by the Slicer\r
\r
if (mPreviousSlice[slicer] == slice) {\r
if (mPreviousTSlice[slicer] == tslice) {\r
mPreviousSlice[slicer] = slice;\r
mPreviousTSlice[slicer] = tslice;\r
\r
- if (mFusionSequenceIndexLinkedManager>=0) return;\r
-\r
- emit UpdateTSlice(slicer, tslice);\r
+ emit UpdateTSlice(slicer, tslice, mFusionSequenceInvolvementCode);\r
}\r
//----------------------------------------------------------------------------\r
\r
//----------------------------------------------------------------------------\r
void vvSlicerManager::SetPreset(int preset)\r
{\r
+\r
//vtkLookupTable* LUT = static_cast<vtkLookupTable*>(mSlicers[0]->GetWindowLevel()->GetLookupTable());\r
double window = mSlicers[0]->GetColorWindow();\r
double level = mSlicers[0]->GetColorLevel();\r
\r
std::string component_type=mImage->GetScalarTypeAsITKString();\r
switch (preset) {\r
- case 0:\r
+ case WL_AUTO:\r
double range[2];\r
mImage->GetScalarRange(range);\r
window = range[1] - range[0];\r
level = (range[1] + range[0])* 0.5;\r
break;\r
- case 1:\r
+ case WL_HOUNSFIELD:\r
window = 2000;\r
level = 0;\r
break;\r
- case 2:\r
+ case WL_SOFTTISSUE:\r
window = 400;\r
level = 20;\r
break;\r
- case 3: // lungs (same as FOCAL)\r
+ case WL_LUNGS: // lungs (same as FOCAL)\r
window = 1700;\r
level = -300;\r
break;\r
- case 4:\r
+ case WL_BONES:\r
window = 1000;\r
level = 500;\r
break;\r
- case 5:\r
+ case WL_HEAD:\r
+ window = 200;\r
+ level = 70;\r
+ break;\r
+ case WL_BINARY:\r
window = 1;\r
level = 0.5;\r
break;\r
- case 6:\r
+ case WL_USER:\r
break;\r
- case 7:\r
+ case WL_VENTILATION:\r
window=1.;\r
level=0.;\r
break;\r
this->mSlicers[slicer]->GetConcatenatedTransform());\r
this->SetColorWindow(max-min);\r
this->SetColorLevel(0.5*(min+max));\r
- this->SetPreset(6);\r
+ this->SetPreset(WL_USER);\r
}\r
this->Render();\r
this->UpdateWindowLevel();\r
LUT->Build();\r
}\r
vtkWindowLevelLookupTable* fusLUT = NULL;\r
+\r
+ //FUSION / FUSION SEQUENCE\r
if (mSlicers[0]->GetFusion()) { // && mFusionColorMap >= 0) {\r
- fusLUT = vtkWindowLevelLookupTable::New();\r
+ fusLUT = vtkWindowLevelLookupTable::New();\r
double fusRange [2];\r
fusRange[0] = mFusionLevel - mFusionWindow/2;\r
fusRange[1] = mFusionLevel + mFusionWindow/2;\r
\r
- //check whether it is actually a fusionSequence or a fusion, before invoking mFusionReader...\r
- double* frange;\r
- if (mFusionReader.IsNull()) frange = mFusionSequenceReader->GetOutput()->GetVTKImages()[0]->GetScalarRange();\r
- else frange = mFusionReader->GetOutput()->GetVTKImages()[0]->GetScalarRange();\r
+ //check whether it is actually a fusionSequence or a fusion, before invoking mFusionReader...\r
+ double* frange;\r
+ if (this->IsInvolvedInFusionSequence()) \r
+ frange = mFusionSequenceReader->GetOutput()->GetVTKImages()[0]->GetScalarRange();\r
+ else\r
+ frange = mFusionReader->GetOutput()->GetVTKImages()[0]->GetScalarRange();\r
\r
- fusLUT->SetTableRange(frange);\r
+ fusLUT->SetTableRange(frange);\r
fusLUT->SetValueRange(1,1);\r
fusLUT->SetSaturationRange(1,1);\r
fusLUT->SetAlphaRange(1, 1);\r
fusLUT->SetValueRange(0,1);\r
fusLUT->SetSaturationRange(0,0);\r
}\r
- \r
+\r
fusLUT->ForceBuild();\r
double v[4];\r
- \r
+\r
// set color table transparency\r
//double alpha_range=(double)mFusionThresOpacity/10;\r
double range_end = fusRange[0] + (double)mFusionThresOpacity*(fusRange[1] - fusRange[0])/100;\r
}\r
}\r
for ( unsigned int i = 0; i < mSlicers.size(); i++) {\r
- \r
+\r
if (mSlicers[i]->GetOverlay()) {\r
vtkLookupTable* supLUT = vtkLookupTable::New();\r
supLUT->SetTableRange(range[0],range[1]);\r
} else {\r
mSlicers[i]->GetWindowLevel()->SetLookupTable(LUT);\r
}\r
- \r
+\r
if (mSlicers[i]->GetFusion()) {\r
mSlicers[i]->ShowFusionLegend(mFusionShowLegend);\r
mSlicers[i]->GetFusionMapper()->SetLookupTable(fusLUT);\r