#include "vtkViewImage.h" #include "vtkObjectFactory.h" #include "vtkProp.h" #include "vtkTextActor.h" #include "vtkCoordinate.h" #include "vtkProperty.h" #include "vtkProperty2D.h" #include "vtkTextProperty.h" #include "vtkScalarsToColors.h" #include "vtkImageMapToWindowLevelColors.h" #include "vtkImageData.h" #include "vtkActor.h" #include "vtkRenderWindow.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef WIN32 int rint(double a); #endif // WIN32 vtkCxxRevisionMacro(vtkViewImage, "$Revision: 1.13 $"); vtkStandardNewMacro(vtkViewImage); vtkViewImage::vtkViewImage() { this->Image = 0; this->Transform = 0; this->LookupTable = 0; this->LinkWindowLevel = true; this->LinkPosition = true; this->LinkZoom = false; this->Shift = 0.0; this->Scale = 1.0; this->Level = 128.0; this->Window = 255.0; this->ScalarBar = vtkScalarBarActor::New(); this->ScalarBar->GetLabelTextProperty()->SetColor (1.0,1.0,1.0); this->ScalarBar->GetTitleTextProperty()->SetColor (1.0,1.0,1.0); //this->ScalarBar->SetTextPositionToPrecedeScalarBar(); this->ScalarBar->GetLabelTextProperty()->BoldOff(); this->ScalarBar->GetLabelTextProperty()->ShadowOff(); this->ScalarBar->GetLabelTextProperty()->ItalicOff(); this->ScalarBar->SetNumberOfLabels (3); this->ScalarBar->GetLabelTextProperty()->SetFontSize (1); this->ScalarBar->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport(); this->ScalarBar->SetWidth (0.1); this->ScalarBar->SetHeight (0.5); this->ScalarBar->SetPosition (0.9,0.3); //this->ScalarBar->GetPositionCoordinate()->SetValue ( 0.1, 0.01); this->ScalarBar->VisibilityOff(); this->CurrentPoint[0] = 0.0; this->CurrentPoint[1] = 0.0; this->CurrentPoint[2] = 0.0; this->SetAboutData (""); } vtkViewImage::~vtkViewImage() { if( this->Transform ) { this->Transform->Delete(); } if( this->Image ) { this->Image->Delete(); } /* if( this->LookupTable ) // Are we registered? NO! { this->LookupTable->Delete(); }*/ this->ScalarBar->Delete(); this->RemoveAllDataSet(); } void vtkViewImage::SetImage (vtkImageData* image) { std::cerr<<"You should not use this function here\nPlease use vtkViewImage2D or vtkViewImage3D classes instead"<SetTableRange (0, 1); bwLut->SetSaturationRange (0, 0); bwLut->SetHueRange (0, 0); bwLut->SetValueRange (0, 1); bwLut->Build(); this->SetLookupTable (bwLut); this->AddActor (this->ScalarBar); bwLut->Delete(); } void vtkViewImage::RegisterImage(vtkImageData* image) { if(!image) return; if( image != this->Image ) { if( this->Image != NULL ) { this->Image->UnRegister (this); } this->Image = image; this->Image->Register (this); } } double vtkViewImage::GetWholeMinPosition(unsigned int p_axis) { if(!this->Image) { return -VTK_LARGE_FLOAT; } return this->Image->GetBounds()[p_axis * 2];// - //this->Image->GetSpacing()[p_axis] / 2; } double vtkViewImage::GetWholeMaxPosition(unsigned int p_axis) { if(!this->Image) { return VTK_LARGE_FLOAT; } return this->Image->GetBounds()[p_axis * 2 + 1];// + //this->Image->GetSpacing()[p_axis] / 2; } unsigned int vtkViewImage::GetOrthogonalAxis(unsigned int p_plan) { assert(p_planGetImage() ) { return 0; } assert(p_plan < NB_DIRECTION_IDS); double* spacing = this->GetImage()->GetSpacing(); double* origin = this->GetImage()->GetOrigin(); int axis = this->GetOrthogonalAxis(p_plan); double soft_pos = pos[axis]; double pos_max = this->GetWholeMaxPosition(axis); double pos_min = this->GetWholeMinPosition(axis); // Treat extreme position at the end of the last pixel if ((soft_pos > pos_max-0.005) && (soft_pos < pos_max+0.005)) { soft_pos = pos_max-0.005; } if ((soft_pos > pos_min-0.005) && (soft_pos < pos_min+0.005)) { soft_pos = pos_min+0.005; } return (int)rint((soft_pos-origin[axis])/spacing[axis]); } int vtkViewImage::GetSlice(unsigned int p_plan) { const double* pos = this->GetCurrentPoint(); return this->GetSliceForPoint (pos, p_plan); } void vtkViewImage::SyncSetSlice(unsigned int p_plan, int p_zslice) { if( !this->GetImage() ) { return; } assert(p_planGetOrthogonalAxis(p_plan); double* spacing = this->GetImage()->GetSpacing(); int* extent = this->GetImage()->GetWholeExtent(); double* origin = this->GetImage()->GetOrigin(); int slice = p_zslice; int dims[3]; dims[0] = extent[1]; dims[1] = extent[3]; dims[2] = extent[5]; if(slice >= dims[axis]) slice = dims[axis]; if(slice < 0) slice = 0; double pos[3]; this->GetCurrentPoint(pos); pos[axis] = origin[axis] + slice * spacing[axis]; this->SyncSetCurrentPoint(pos); } void vtkViewImage::SyncSetZSlice(int p_zslice) { if( this->IsLocked() ) { return; } this->SetZSlice(p_zslice); this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = dynamic_cast ( this->Children[i] ); if( view && view->GetLinkPosition()) { view->SyncSetZSlice (p_zslice); if( !view->GetRenderWindow()->GetNeverRendered() ) { view->Render(); } } } this->UnLock(); } void vtkViewImage::GetVoxelCoordinates(double pos[3], int p_coordinates[3]) { if(!this->Image) { return; } p_coordinates[this->GetOrthogonalAxis(SAGITTAL_ID)] = this->GetSliceForPoint(pos, SAGITTAL_ID); p_coordinates[this->GetOrthogonalAxis(CORONAL_ID)] = this->GetSliceForPoint(pos, CORONAL_ID); p_coordinates[this->GetOrthogonalAxis(AXIAL_ID)] = this->GetSliceForPoint(pos, AXIAL_ID); } void vtkViewImage::GetCurrentVoxelCoordinates(int p_coordinates[3]) { p_coordinates[this->GetOrthogonalAxis(SAGITTAL_ID)] = this->GetSlice(SAGITTAL_ID); p_coordinates[this->GetOrthogonalAxis(CORONAL_ID)] = this->GetSlice(CORONAL_ID); p_coordinates[this->GetOrthogonalAxis(AXIAL_ID)] = this->GetSlice(AXIAL_ID); } void vtkViewImage::SyncSetCurrentPoint(const double p_point[3]) { if( this->IsLocked() ) { return; } this->SetCurrentPoint (p_point); // this boolean is used so that the other observe won't call // SetCurrentPoint again and again and again... this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = reinterpret_cast ( this->Children[i] ); if( view && view->GetLinkPosition()) { view->SyncSetCurrentPoint (p_point); if( !view->GetRenderWindow()->GetNeverRendered() ) { view->Render(); } } } this->UnLock(); } double vtkViewImage::GetCurrentPointDoubleValue () { if (!this->Image) { return -1; } int coordinates[3]; this->GetCurrentVoxelCoordinates(coordinates); void *scalar = this->GetImage()->GetScalarPointer(coordinates); if( !scalar ) return -1.0; switch (this->GetImage()->GetScalarType()) { case VTK_DOUBLE: return (*(double*)scalar); case VTK_FLOAT: return (double) (*(float*)scalar); case VTK_UNSIGNED_LONG: return (double) (*(unsigned long*)scalar); case VTK_LONG: return (double) (*(long*)scalar); case VTK_UNSIGNED_INT: return (double) (*(unsigned int*)scalar); case VTK_INT: return (double) (*(int*)scalar); case VTK_UNSIGNED_SHORT: return (double) (*(unsigned short*)scalar); case VTK_SHORT: return (double) (*(short*)scalar); case VTK_UNSIGNED_CHAR: return (double) (*(unsigned char*)scalar); case VTK_CHAR: return (double) (*(char*)scalar); } return -1; } void vtkViewImage::SyncResetCurrentPoint() { if( this->IsLocked() ) { return; } this->ResetCurrentPoint(); this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = reinterpret_cast (this->Children[i]); if( view && view->GetLinkPosition() ) { view->SyncResetCurrentPoint (); if( !view->GetRenderWindow()->GetNeverRendered() ) { view->Render(); } } } this->UnLock(); } void vtkViewImage::ResetCurrentPoint() { if (!this->Image) { return; } double* spacing = this->GetImage()->GetSpacing(); int* ext = this->GetImage()->GetWholeExtent(); double* origin = this->GetImage()->GetOrigin(); double pos[3] = { rint ( origin[0] + ext[1] / 2.0 * spacing[0]), rint ( origin[1] + ext[3] / 2.0 * spacing[1]), rint ( origin[2] + ext[5] / 2.0 * spacing[2]) }; this->SetCurrentPoint(pos); } void vtkViewImage::SyncSetWindow (double w) { if( this->IsLocked() ) { return; } this->SetWindow (w); // this boolean is used so that the other observe won't call // SetCurrentPoint again and again and again... this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = reinterpret_cast (this->Children[i]); if( view && view->GetLinkWindowLevel() ) { view->SyncSetWindow (w); if( !view->GetRenderWindow()->GetNeverRendered() ) { view->Render(); } } } this->UnLock(); } void vtkViewImage::SyncSetLevel (double l) { if( this->IsLocked() ) { return; } this->SetLevel (l); // this boolean is used so that the other observe won't call // SetCurrentPoint again and again and again... this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = dynamic_cast (this->Children[i]); if( view && view->GetLinkWindowLevel() ) { view->SyncSetLevel (l); if( !view->GetRenderWindow()->GetNeverRendered() ) { view->Render(); } } } this->UnLock(); } void vtkViewImage::SetWindowLevelFrom(vtkViewImage* p_view) { if (p_view) { this->SetWindow( p_view->GetColorWindow() ); this->SetLevel( p_view->GetColorLevel() ); } } void vtkViewImage::SyncResetWindowLevel() { if( this->IsLocked() ) { return; } this->ResetWindowLevel(); this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = reinterpret_cast (this->Children[i]); if( view && view->GetLinkWindowLevel() ) { view->SyncResetWindowLevel (); if( !view->GetRenderWindow()->GetNeverRendered() ) { view->Render(); } } } this->UnLock(); } void vtkViewImage::ResetWindowLevel() { if (this->IsLocked()) { return; } if (!this->Image) { return; } this->Image->UpdateInformation(); this->Image->SetUpdateExtent( this->Image->GetWholeExtent() ); this->Image->Update(); double* range = this->Image->GetScalarRange(); vtkImageAccumulate* histogram = vtkImageAccumulate::New(); histogram->SetInput ( this->Image ); int extent[6] = {0, 1000, 0, 0, 0, 0}; histogram->SetComponentExtent (extent); double spacing[3] = { (range[1]-range[0])/1000.0, 0.0, 0.0}; histogram->SetComponentSpacing (spacing); double origin[3] = {range[0], 0.0, 0.0}; histogram->SetComponentOrigin (origin); histogram->Update(); vtkImageData* output = histogram->GetOutput(); vtkIntArray* ptData = vtkIntArray::SafeDownCast (output->GetPointData()->GetScalars()); if( !ptData) { std::cerr << "Error: Cannot cast point data." << std::endl; return; } double numVox = histogram->GetVoxelCount(); double onePercent = numVox/100.0; int start=1; double currentPercent = 0.0; while( currentPercent<0.1 && start<999) { double tuple; ptData->GetTuple (start, &tuple); currentPercent += tuple/onePercent; start++; } currentPercent = 0.0; int end = 999; while( currentPercent<0.1 && end>0 ) { double tuple; ptData->GetTuple (end, &tuple); currentPercent += tuple/onePercent; end--; } double window = (end-start)*(range[1]-range[0])/1000.0; //double window = range[1]-range[0]; double level = 0.5*(start + end)*(range[1]-range[0])/1000.0; //double level = 0.5*(range[1]+range[0]); window = (window-this->GetShift())/this->GetScale(); level = (level-this->GetShift())/this->GetScale(); //window = range[1]-range[0]; //level = 0.5*( range[0] + range[1]); this->SetWindow ( window ); this->SetLevel ( level ); histogram->Delete(); } bool vtkViewImage::HasDataSet (vtkDataSet* dataset) { if( !dataset ) { return false; } bool res = false; for( unsigned int i=0; iDataSetList.size(); i++) { if( dataset == this->DataSetList[i] ) { res = true; break; } } return res; } vtkActor* vtkViewImage::SyncAddDataSet (vtkDataSet* dataset, vtkProperty* property) { if( this->IsLocked() ) { return NULL; } vtkActor* actor = this->AddDataSet (dataset, property); this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = dynamic_cast (this->Children[i]); if( view ) { view->SyncAddDataSet (dataset, property); } } this->UnLock(); return actor; } vtkActor* vtkViewImage::AddDataSet (vtkDataSet* dataset, vtkProperty* property) { std::cerr<<"You should not use this function here\nPlease use vtkViewImage2D or vtkViewImage3D classes instead"<IsLocked() ) { return; } this->RemoveDataSet (dataset); this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = dynamic_cast (this->Children[i]); if( view ) { view->SyncRemoveDataSet (dataset); } } this->UnLock(); } void vtkViewImage::RemoveDataSet (vtkDataSet* dataset) { if (!dataset) { return; } std::vector t_actorlist = this->DataSetActorList; std::vector t_datasetlist = this->DataSetList; this->DataSetActorList.clear(); this->DataSetList.clear(); for (unsigned int i=0; iDataSetList.push_back (t_datasetlist[i]); this->DataSetActorList.push_back (t_actorlist[i]); } else { this->RemoveActor (t_actorlist[i]); } } } void vtkViewImage::SyncRemoveAllDataSet () { if( this->IsLocked() ) { return; } this->RemoveAllDataSet (); this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = dynamic_cast (this->Children[i]); if( view ) { view->SyncRemoveAllDataSet (); } } this->UnLock(); } void vtkViewImage::RemoveAllDataSet () { for (unsigned int i=0; iDataSetList.size(); i++) { this->RemoveDataSet (this->DataSetList[i]); } } void vtkViewImage::SyncColorDataSetByArray(vtkDataSet* dataset, const char* arrayname, vtkColorTransferFunction* transfer) { if( this->IsLocked() ) { return; } this->ColorDataSetByArray (dataset, arrayname, transfer); this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = dynamic_cast (this->Children[i]); if( view ) { view->SyncColorDataSetByArray (dataset, arrayname, transfer); } } this->UnLock(); } void vtkViewImage::ColorDataSetByArray(vtkDataSet* dataset, const char* arrayname, vtkColorTransferFunction* transfer) { bool doit = true; if (!dataset) { doit = false; } vtkDataArray* array = NULL; vtkMapper* mapper = NULL; if (doit) { for (unsigned int i=0; iDataSetList.size(); i++) { if (dataset == this->DataSetList[i]) { mapper = this->DataSetActorList[i]->GetMapper(); break; } } if (!mapper) { doit = false; } } if (doit) { mapper->Modified(); if (dataset->GetCellData()) { array = dataset->GetCellData()->GetArray (arrayname); if (array) { mapper->SetScalarModeToUseCellFieldData(); } } if (!array && dataset->GetPointData()) { array = dataset->GetPointData()->GetArray (arrayname); if (array) { mapper->SetScalarModeToUsePointFieldData(); } } if (!array) { mapper->SetScalarModeToDefault(); mapper->SetInterpolateScalarsBeforeMapping(0); doit = false; } } if (doit) { mapper->SetLookupTable (transfer); mapper->SetScalarRange (array->GetRange()[0], array->GetRange()[1]); mapper->SetInterpolateScalarsBeforeMapping(1); mapper->SelectColorArray (array->GetName()); } } vtkDataSet* vtkViewImage::GetDataSet (unsigned int i) { if (i<0 || i>this->DataSetList.size()) return NULL; return this->DataSetList[i]; } vtkActor* vtkViewImage::GetDataSetActor (unsigned int i) { if (i<0 || i>=this->DataSetActorList.size()) return NULL; return this->DataSetActorList[i]; } vtkActor* vtkViewImage::GetDataSetActor (vtkDataSet* dataset) { if (!dataset) return NULL; for (unsigned int i=0; iDataSetList.size(); i++) { if (dataset == this->DataSetList[i]) return this->DataSetActorList[i]; } return NULL; } void vtkViewImage::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); } void vtkViewImage::SyncSetZoom (double factor) { if( this->IsLocked() ) { return; } this->SetZoom (factor); this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = dynamic_cast(this->Children[i]); if( view ) { if( view->GetLinkZoom() ) { view->SyncSetZoom (factor); if( !view->GetRenderWindow()->GetNeverRendered() ) { view->Render(); } } } } this->UnLock(); } void vtkViewImage::SyncSetLookupTable (vtkScalarsToColors* lut) { if( this->IsLocked() ) { return; } this->SetLookupTable (lut); this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = dynamic_cast(this->Children[i]); if( view ) { view->SyncSetLookupTable (lut); if( !view->GetRenderWindow()->GetNeverRendered() ) { view->Render(); } } } this->UnLock(); } void vtkViewImage::SyncResetZoom () { if( this->IsLocked() ) { return; } this->ResetZoom (); this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = dynamic_cast(this->Children[i]); if( view ) { view->SyncResetZoom (); if( !view->GetRenderWindow()->GetNeverRendered() ) { view->Render(); } } } this->UnLock(); } void vtkViewImage::ResetZoom() { this->ResetCamera(); } void vtkViewImage::SyncReset () { if( this->IsLocked() ) { return; } this->Reset (); this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = dynamic_cast(this->Children[i]); if( view ) { view->SyncReset (); if( !view->GetRenderWindow()->GetNeverRendered() ) { view->Render(); } } } this->UnLock(); } void vtkViewImage::SyncSetMaskImage (vtkImageData* mask, vtkLookupTable* lut) { if( this->IsLocked() ) { return; } this->SetMaskImage (mask, lut); this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = dynamic_cast(this->Children[i]); if( view ) { view->SyncSetMaskImage (mask, lut); if( !view->GetRenderWindow()->GetNeverRendered() ) { view->Render(); } } } this->UnLock(); } void vtkViewImage::SyncSetOverlappingImage (vtkImageData* image) { if( this->IsLocked() ) { return; } this->SetOverlappingImage (image); this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = dynamic_cast(this->Children[i]); if( view ) { view->SyncSetOverlappingImage (image); if( !view->GetRenderWindow()->GetNeverRendered() ) { view->Render(); } } } this->UnLock(); } void vtkViewImage::SyncRemoveMaskImage () { if( this->IsLocked() ) { return; } this->RemoveMaskImage (); this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = dynamic_cast(this->Children[i]); if( view ) { view->SyncRemoveMaskImage (); if( !view->GetRenderWindow()->GetNeverRendered() ) { view->Render(); } } } this->UnLock(); } void vtkViewImage::SyncRemoveOverlappingImage () { if( this->IsLocked() ) { return; } this->RemoveOverlappingImage (); this->Lock(); for( unsigned int i=0; iChildren.size(); i++) { vtkViewImage* view = dynamic_cast(this->Children[i]); if( view ) { view->SyncRemoveOverlappingImage (); if( !view->GetRenderWindow()->GetNeverRendered() ) { view->Render(); } } } this->UnLock(); }