NIREP
|
00001 /*========================================================================= 00002 00003 Program: vtkINRIA3D 00004 Module: $Id: NIREPvtkViewImage2D.cxx,v 1.15 2010/12/02 23:20:19 hawle Exp $ 00005 Language: C++ 00006 Author: $Author: hawle $ 00007 Date: $Date: 2010/12/02 23:20:19 $ 00008 Version: $Revision: 1.15 $ 00009 00010 Copyright (c) 2007 INRIA - Asclepios Project. All rights reserved. 00011 See Copyright.txt for details. 00012 00013 This software is distributed WITHOUT ANY WARRANTY; without even 00014 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00015 PURPOSE. See the above copyright notices for more information. 00016 00017 =========================================================================*/ 00018 #include "NIREPvtkViewImage2D.h" 00019 00020 #include "vtkInteractorObserver.h" 00021 #include "vtkInteractorStyleSwitch.h" 00022 #include "vtkRenderer.h" 00023 #include "vtkRenderWindow.h" 00024 #include "vtkRenderWindowInteractor.h" 00025 #include "vtkRendererCollection.h" 00026 #include "vtkProp.h" 00027 #include "vtkTextActor.h" 00028 #include "vtkCoordinate.h" 00029 #include "vtkProperty.h" 00030 #include "vtkProperty2D.h" 00031 #include "vtkTextProperty.h" 00032 #include <vtkCornerAnnotation.h> 00033 #include <vtkLightCollection.h> 00034 #include <vtkLight.h> 00035 #include <vtkOrientationAnnotation.h> 00036 00037 #include "assert.h" 00038 #include <iostream> 00039 #include <sstream> 00040 #include <cmath> 00041 00042 #include <NIREPvtkViewImage2DCommand.h> 00043 #include <vtkRenderingAddOn/vtkViewImage2DFullCommand.h> 00044 #include <NIREPvtkInteractorStyleImage2D.h> 00045 #include "vtkCamera.h" 00046 #include "vtkImageReslice.h" 00047 #include "vtkRenderWindow.h" 00048 #include "vtkTransform.h" 00049 #include "vtkImageMapToWindowLevelColors.h" 00050 #include "vtkImageMapToColors.h" 00051 #include "vtkImageActor.h" 00052 #include "vtkImageData.h" 00053 #include "vtkActor.h" 00054 #include "vtkPolyDataMapper.h" 00055 #include "vtkLineSource.h" 00056 #include "vtkLookupTable.h" 00057 #include <vtkRenderingAddOn/vtkImageBlendWithMask.h> 00058 #include "vtkImageBlend.h" 00059 #include <vtkPolyDataMapper2D.h> 00060 #include <vtkActor2D.h> 00061 #include <vtkMatrix4x4.h> 00062 00063 #include <vtkColorTransferFunction.h> 00064 #include <vtkDataArray.h> 00065 #include <vtkPointData.h> 00066 #include <vtkCellData.h> 00067 #include <vtkExtractGeometry.h> 00068 #include <vtkDataSet.h> 00069 #include <vtkUnstructuredGrid.h> 00070 #include <vtkDataSetMapper.h> 00071 #include <vtkPlane.h> 00072 #include <vtkPlaneCollection.h> 00073 #include <vtkPolyDataMapper2D.h> 00074 #include <vtkActor2D.h> 00075 #include <vtkClipDataSet.h> 00076 #include <vtkCutter.h> 00077 #include <vtkBox.h> 00078 #include <vtkPolyDataWriter.h> 00079 #include <vtkPolyDataNormals.h> 00080 #include <vtkTransform.h> 00081 #include <vtkMath.h> 00082 #include <vtkRulerWidget.h> 00083 00084 00085 vtkCxxRevisionMacro(NIREPvtkViewImage2D, "$Revision: 1.15 $"); 00086 vtkStandardNewMacro(NIREPvtkViewImage2D); 00087 00088 // Initialize static member that controls display convention (0: radiologic, 1: neurologic) 00089 static int vtkViewImage2DDisplayConventions = 0; 00090 00091 00092 void NIREPvtkViewImage2D::SetViewImage2DDisplayConventions(int val) 00093 { 00094 vtkViewImage2DDisplayConventions = val; 00095 } 00096 00097 00098 int NIREPvtkViewImage2D::GetViewImage2DDisplayConventions() 00099 { 00100 return vtkViewImage2DDisplayConventions; 00101 } 00102 00103 00104 NIREPvtkViewImage2D::NIREPvtkViewImage2D() 00105 { 00106 this->FirstRender = 1; 00107 this->ShowSliceNumber = 1; 00108 this->InteractionStyle = SELECT_INTERACTION; 00109 this->LeftButtonInteractionStyle = SELECT_INTERACTION; 00110 this->MiddleButtonInteractionStyle = SELECT_INTERACTION; 00111 this->RightButtonInteractionStyle = SELECT_INTERACTION; 00112 this->WheelInteractionStyle = SELECT_INTERACTION; 00113 this->Show2DAxis = 1; 00114 this->RulerWidgetVisibility = 0; 00115 00116 this->Conventions = RADIOLOGIC; 00117 00118 this->InitialParallelScale = 1.0; 00119 00120 00121 this->ImageReslice = vtkImageReslice::New(); 00122 this->ImageActor = vtkImageActor::New(); 00123 this->WindowLevelForCorner = vtkImageMapToWindowLevelColors::New(); 00124 this->WindowLevel = vtkImageMapToColors::New(); 00125 this->MaskFilter = vtkImageBlendWithMask::New(); 00126 this->Blender = vtkImageBlend::New(); 00127 00128 this->WindowLevel->SetOutputFormatToRGB(); 00129 00130 00131 this->OrientationMatrix = vtkMatrix4x4::New(); 00132 this->OrientationMatrix->Identity(); 00133 this->ScreenToRealWorldMatrix = vtkMatrix4x4::New(); 00134 this->ScreenToRealWorldMatrix->Zero(); 00135 this->ScreenToRealWorldMatrix->SetElement (2, 2, 1.0); 00136 00137 00138 /* 00139 this->BGActor = vtkImageActor::New(); 00140 this->BGWindowLevel = vtkImageMapToColors::New(); 00141 this->BGImage = vtkImageData::New(); 00142 */ 00143 this->BGActor = 0; 00144 this->BGWindowLevel = 0; 00145 this->BGImage = 0; 00146 00147 this->HorizontalLineSource = vtkLineSource::New(); 00148 this->VerticalLineSource = vtkLineSource::New(); 00149 this->HorizontalLineActor = vtkActor::New(); 00150 this->VerticalLineActor = vtkActor::New(); 00151 00152 this->DataSetCutPlane = vtkPlane::New(); 00153 this->DataSetCutBox = vtkBox::New(); 00154 00155 00156 this->DataSetCutPlane->SetOrigin (0,0,0); 00157 this->DataSetCutPlane->SetNormal (0,0,1); 00158 this->DataSetCutBox->SetBounds (0,0,0,0,0,0); 00159 this->BoxThickness = 2; 00160 00161 00162 // set the filters properties 00163 this->Blender->SetBlendModeToNormal(); 00164 //this->Blender->SetOpacity (0,0.25 ); GEC 7/10/2010 changed to 50% opacity 00165 //this->Blender->SetOpacity (1, 0.75); 00166 this->Blender->SetOpacity (0,0.5); 00167 this->Blender->SetOpacity (1,0.5); 00168 00169 00170 // set up the vtk pipeline 00171 this->ImageReslice->SetOutputDimensionality(2); 00172 this->ImageReslice->InterpolateOff(); 00173 this->ImageReslice->SetInputConnection( this->WindowLevel->GetOutputPort() ); 00174 00175 00176 this->AuxInput = this->WindowLevel->GetOutput(); 00177 this->ResliceInput = this->WindowLevel->GetOutput(); 00178 00179 00180 // Interactor Style 00181 this->SetInteractionStyle( NIREPvtkViewImage2D::SELECT_INTERACTION ); 00182 00183 00184 // Initialize cursor lines 00185 vtkPolyDataMapper* mapper = vtkPolyDataMapper::New(); 00186 mapper->SetInputConnection( this->HorizontalLineSource->GetOutputPort() ); 00187 00188 this->HorizontalLineActor->SetMapper(mapper); 00189 this->HorizontalLineActor->GetProperty()->SetColor (1.0,0.0,0.0); 00190 mapper->Delete(); 00191 this->HorizontalLineActor->SetVisibility (0); 00192 this->HorizontalLineActor->PickableOff(); 00193 this->HorizontalLineActor->DragableOff(); 00194 00195 00196 00197 vtkPolyDataMapper* mapper2 = vtkPolyDataMapper::New(); 00198 mapper2->SetInputConnection( this->VerticalLineSource->GetOutputPort() ); 00199 this->VerticalLineActor->SetMapper(mapper2); 00200 this->VerticalLineActor->GetProperty()->SetColor (1.0,0.0,0.0); 00201 mapper2->Delete(); 00202 this->VerticalLineActor->SetVisibility (0); 00203 this->VerticalLineActor->PickableOff(); 00204 this->VerticalLineActor->DragableOff(); 00205 00206 this->GetCornerAnnotation()->SetWindowLevel ( this->WindowLevelForCorner ); 00207 00208 this->SetOrientation ( NIREPvtkViewImage::AXIAL_ID ); 00209 00210 if( NIREPvtkViewImage2D::GetViewImage2DDisplayConventions()==0 ) 00211 { 00212 this->SetConventionsToRadiological(); 00213 } 00214 else 00215 { 00216 this->SetConventionsToNeurological(); 00217 } 00218 00219 this->RulerWidget = vtkRulerWidget::New(); 00220 this->RulerWidget->KeyPressActivationOff(); 00221 00222 //this->GetCornerAnnotation()->SetLinearFontScaleFactor(15); 00223 00224 } 00225 00226 00227 00228 NIREPvtkViewImage2D::~NIREPvtkViewImage2D() 00229 { 00230 if(this->ImageActor != NULL) { 00231 this->ImageActor->Delete(); 00232 } 00233 this->WindowLevel->Delete(); 00234 this->WindowLevelForCorner->Delete(); 00235 this->ImageReslice->Delete(); 00236 this->MaskFilter->Delete(); 00237 this->Blender->Delete(); 00238 00239 //this->BGActor->Delete(); 00240 //this->BGWindowLevel->Delete(); 00241 /* 00242 if( this->BGImage ) 00243 { 00244 this->BGImage->Delete(); 00245 } 00246 */ 00247 00248 this->OrientationMatrix->Delete(); 00249 this->ScreenToRealWorldMatrix->Delete(); 00250 00251 this->HorizontalLineSource->Delete(); 00252 this->HorizontalLineActor->Delete(); 00253 00254 this->VerticalLineSource->Delete(); 00255 this->VerticalLineActor->Delete(); 00256 00257 this->DataSetCutPlane->Delete(); 00258 this->DataSetCutBox->Delete(); 00259 00260 this->RulerWidget->Delete(); 00261 } 00262 00263 00264 void NIREPvtkViewImage2D::InternalUpdate() 00265 { 00266 this->UpdateImageActor(); 00267 // this->UpdatePosition(); 00268 this->InitializeImagePositionAndSize(); 00269 } 00270 00271 00272 void NIREPvtkViewImage2D::Initialize() 00273 { 00274 this->Superclass::Initialize(); 00275 00276 if (this->GetRenderer()) 00277 { 00278 this->GetRenderer()->TwoSidedLightingOff(); 00279 } 00280 00281 if( this->GetRenderWindowInteractor() ) 00282 { 00283 NIREPvtkInteractorStyleImage2D *interactor = NIREPvtkInteractorStyleImage2D::New(); 00284 interactor->SetView(this); 00285 00286 NIREPvtkViewImage2DCommand *cbk = NIREPvtkViewImage2DCommand::New(); 00287 cbk->SetView(this); 00288 00289 interactor->AddObserver(vtkCommand::KeyPressEvent, cbk); 00290 interactor->AddObserver(vtkCommand::WindowLevelEvent, cbk); 00291 interactor->AddObserver(vtkCommand::StartWindowLevelEvent, cbk); 00292 interactor->AddObserver(vtkCommand::ResetWindowLevelEvent, cbk); 00293 interactor->AddObserver(vtkCommand::EndWindowLevelEvent, cbk); 00294 interactor->AddObserver(vtkCommand::PickEvent, cbk); 00295 interactor->AddObserver(vtkCommand::StartPickEvent, cbk); 00296 interactor->AddObserver(vtkCommand::EndPickEvent, cbk); 00297 interactor->AddObserver(NIREPvtkViewImage2DCommand::ResetZoomEvent, cbk); 00298 interactor->AddObserver(NIREPvtkViewImage2DCommand::ResetPositionEvent, cbk); 00299 interactor->AddObserver(NIREPvtkViewImage2DCommand::StartZSliceMoveEvent, cbk); 00300 interactor->AddObserver(NIREPvtkViewImage2DCommand::ZSliceMoveEvent, cbk); 00301 interactor->AddObserver(NIREPvtkViewImage2DCommand::EndZSliceMoveEvent, cbk); 00302 interactor->AddObserver(NIREPvtkViewImage2DCommand::StartMeasureEvent, cbk); 00303 interactor->AddObserver(NIREPvtkViewImage2DCommand::MeasureEvent, cbk); 00304 interactor->AddObserver(NIREPvtkViewImage2DCommand::EndMeasureEvent, cbk); 00305 interactor->AddObserver(NIREPvtkViewImage2DCommand::FullPageEvent, cbk); 00306 interactor->AddObserver(NIREPvtkViewImage2DCommand::ZoomEvent, cbk); 00307 interactor->AddObserver(NIREPvtkViewImage2DCommand::DefaultMoveEvent, cbk); 00308 00309 this->GetRenderWindowInteractor()->SetInteractorStyle( interactor ); 00310 00311 this->RulerWidget->SetInteractor ( this->GetRenderWindowInteractor() ); 00312 00313 interactor->Delete(); 00314 cbk->Delete(); 00315 } 00316 00317 } 00318 00319 00320 void NIREPvtkViewImage2D::Uninitialize() 00321 { 00322 this->RemoveActor( this->HorizontalLineActor ); 00323 this->RemoveActor( this->VerticalLineActor ); 00324 if(this->ImageActor != NULL) { 00325 this->RemoveActor( this->ImageActor ); 00326 } 00327 for( unsigned int i=0; i<this->DataSetActorList.size(); i++) 00328 this->RemoveActor( this->DataSetActorList[i] ); 00329 00330 if ( this->GetRenderWindowInteractor() ) 00331 { 00332 this->GetRenderWindowInteractor()->SetInteractorStyle( NULL ); 00333 } 00334 this->RulerWidget->SetInteractor ( NULL ); 00335 00336 NIREPvtkViewImage::Uninitialize(); 00337 } 00338 00339 00340 void NIREPvtkViewImage2D::SetVisibility (int state) 00341 { 00342 NIREPvtkViewImage::SetVisibility ( state ); 00343 if(this->ImageActor != NULL) { 00344 this->ImageActor->SetVisibility ( state ); 00345 } 00346 } 00347 00348 00349 void NIREPvtkViewImage2D::UpdateImageActor() 00350 { 00351 if( !this->GetImage() ) 00352 { 00353 return; 00354 } 00355 if(this->ImageActor == NULL) { 00356 return; 00357 } 00358 00359 this->ImageReslice->GetOutput()->UpdateInformation(); 00360 this->ImageActor->GetInput()->SetUpdateExtent( this->ImageReslice->GetOutput()->GetWholeExtent() ); 00361 this->ImageActor->SetDisplayExtent( this->ImageReslice->GetOutput()->GetWholeExtent() ); 00362 this->FirstRender = 1; 00363 } 00364 00365 00366 void NIREPvtkViewImage2D::InitializeImagePositionAndSize() 00367 { 00368 if( !this->GetImage() ) 00369 { 00370 return; 00371 } 00372 00373 00374 if (this->FirstRender) 00375 { 00376 // make sur the input is up-to-date 00377 00378 this->GetRenderer()->GetActiveCamera()->OrthogonalizeViewUp(); 00379 this->GetRenderer()->GetActiveCamera()->ParallelProjectionOn(); 00380 00381 if(this->ImageActor != NULL) { 00382 this->ImageActor->GetInput()->Update(); 00383 00384 00385 00386 00387 00388 // Get the current position of the camera: 00389 //double Pos[3]; 00390 //this->GetRenderer()->GetActiveCamera()->GetPosition(Pos); 00391 00392 00393 // Get the bounds of the image: coordinates in the real world 00394 double bnds[6]; 00395 this->ImageActor->GetBounds(bnds); 00396 00397 00398 // extension of the image: 00399 double xs = (bnds[1] - bnds[0]); 00400 double ys = (bnds[3] - bnds[2]); 00401 00402 double bnds_x = xs/2.0; 00403 double bnds_y = ys/2.0; 00404 00405 //this->GetRenderer()->GetActiveCamera()->SetParallelScale(xs < ys ? bnds_y:bnds_x); 00406 //this->InitialParallelScale = this->GetRenderer()->GetActiveCamera()->GetParallelScale(); 00407 this->InitialParallelScale = xs < ys ? bnds_y:bnds_x; 00408 } 00409 00416 this->VerticalLineActor->SetVisibility (0); 00417 this->HorizontalLineActor->SetVisibility (0); 00418 00419 double zoom = this->GetZoom(); 00420 this->ResetZoom(); 00421 this->SetZoom (zoom); 00422 00423 if( this->Show2DAxis ){ 00424 this->VerticalLineActor->SetVisibility (1); 00425 this->HorizontalLineActor->SetVisibility (1); 00426 } 00427 00428 00429 this->FirstRender = 0; 00430 00431 } 00432 } 00433 00434 00435 /* 00436 void NIREPvtkViewImage2D::SetFullInteraction() 00437 { 00438 vtkInteractorStyleImage *interactor = vtkInteractorStyleImage::New(); 00441 vtkViewImage2DFullCommand *cbk = vtkViewImage2DFullCommand::New(); 00442 cbk->IV = this; 00443 interactor->AddObserver(vtkCommand::WindowLevelEvent, cbk); 00444 interactor->AddObserver(vtkCommand::StartWindowLevelEvent, cbk); 00445 interactor->AddObserver(vtkCommand::ResetWindowLevelEvent, cbk); 00446 interactor->AddObserver(vtkCommand::EndWindowLevelEvent, cbk); 00447 interactor->AddObserver(vtkCommand::KeyPressEvent, cbk); 00448 interactor->AddObserver(vtkCommand::EnterEvent, cbk); 00449 interactor->AddObserver(vtkCommand::LeaveEvent, cbk); 00450 cbk->Delete(); 00451 this->SetInteractorStyle(interactor); 00452 interactor->Delete(); 00453 } 00454 */ 00455 00456 00457 /* 00458 void NIREPvtkViewImage2D::SetShowDirections(int p_showDirections) 00459 { 00460 this->ShowDirections = p_showDirections; 00461 00462 if (this->ShowDirections) 00463 { 00464 switch(this->Orientation) 00465 { 00466 case NIREPvtkViewImage::AXIAL_ID: 00467 00468 this->SetNorthAnnotation("A"); 00469 this->SetSouthAnnotation("P"); 00470 if( this->Conventions == RADIOLOGIC ) 00471 { 00472 this->SetEastAnnotation ("L"); 00473 this->SetWestAnnotation("R"); 00474 } 00475 else 00476 { 00477 this->SetEastAnnotation ("R"); 00478 this->SetWestAnnotation("L"); 00479 } 00480 break; 00481 00482 case NIREPvtkViewImage::SAGITTAL_ID: 00483 00484 this->SetNorthAnnotation("S"); 00485 this->SetSouthAnnotation("I"); 00486 this->SetEastAnnotation ("P"); 00487 this->SetWestAnnotation("A"); 00488 break; 00489 00490 case NIREPvtkViewImage::CORONAL_ID: 00491 00492 this->SetNorthAnnotation("S"); 00493 this->SetSouthAnnotation("I"); 00494 00495 if( this->Conventions == RADIOLOGIC) 00496 { 00497 this->SetEastAnnotation ("L"); 00498 this->SetWestAnnotation("R"); 00499 } 00500 else 00501 { 00502 this->SetEastAnnotation ("R"); 00503 this->SetWestAnnotation("L"); 00504 } 00505 break; 00506 } 00507 } 00508 00509 else 00510 { 00511 this->SetNorthAnnotation(""); 00512 this->SetSouthAnnotation(""); 00513 this->SetEastAnnotation (""); 00514 this->SetWestAnnotation(""); 00515 } 00516 this->Modified(); 00517 } 00518 */ 00519 00520 00521 void NIREPvtkViewImage2D::SetShowSliceNumber(int p_showSliceNumber) 00522 { 00523 this->ShowSliceNumber = p_showSliceNumber; 00524 00525 if (!this->ShowSliceNumber) 00526 { 00527 this->SetUpRightAnnotation(""); 00528 } 00529 00530 this->Modified(); 00531 } 00532 00533 00534 int NIREPvtkViewImage2D::GetWholeZMin() 00535 { 00536 return 0; 00537 } 00538 00539 00540 int NIREPvtkViewImage2D::GetWholeZMax() 00541 { 00542 if(!this->GetImage()) 00543 { 00544 return 0; 00545 } 00546 00547 int* ext = this->GetImage()->GetWholeExtent(); 00548 00549 assert(this->Orientation<NIREPvtkViewImage::NB_DIRECTION_IDS); 00550 00551 int axis = this->GetOrthogonalAxis(this->Orientation); 00552 return ext[2*axis+1]; 00553 } 00554 00555 00556 int NIREPvtkViewImage2D::GetZSlice() 00557 { 00558 return this->GetSlice(this->Orientation); 00559 } 00560 00561 00562 void NIREPvtkViewImage2D::SetZSlice(int p_zslice) 00563 { 00564 this->SetSlice(this->Orientation, p_zslice); 00565 this->Modified(); 00566 } 00567 00568 00569 void NIREPvtkViewImage2D::UpdatePosition () 00570 { 00571 if( !this->GetImage() ) 00572 { 00573 return; 00574 } 00575 00576 double x=0; 00577 double y=0; 00578 double max_x=0; 00579 double max_y=0; 00580 double min_x=0; 00581 double min_y=0; 00582 double pos[4]; 00583 00584 this->GetCurrentPoint(pos); 00585 pos[3] = 0.0; 00586 00587 double* spacing = this->GetImage()->GetSpacing(); 00588 double* origin = this->GetImage()->GetOrigin(); 00589 00590 // check if pos lies inside image bounds 00591 /* 00592 double *imBounds = this->GetImage()->GetBounds(); 00593 if( pos[0]<imBounds[0] || pos[0]>imBounds[1] || 00594 pos[1]<imBounds[2] || pos[1]>imBounds[3] || 00595 pos[2]<imBounds[4] || pos[2]>imBounds[5]) 00596 { 00597 // we are outside image bounds 00598 return; 00599 } 00600 */ 00601 00602 // round to the nearest integer slice 00603 pos[0] = vtkMath::Round ((pos[0]-origin[0])/spacing[0] )*spacing[0]+origin[0]; 00604 pos[1] = vtkMath::Round ((pos[1]-origin[1])/spacing[1] )*spacing[1]+origin[1]; 00605 pos[2] = vtkMath::Round ((pos[2]-origin[2])/spacing[2] )*spacing[2]+origin[2]; 00606 00607 /* 00608 double *bounds = this->ImageActor->GetBounds(); 00609 min_x = bounds[0]; 00610 max_x = bounds[1]; 00611 min_y = bounds[2]; 00612 max_y = bounds[3]; 00613 */ 00614 00615 double min_bounds[4] = { this->GetWholeMinPosition(0), 00616 this->GetWholeMinPosition(1), 00617 this->GetWholeMinPosition(2), 00618 0.0 }; 00619 00620 double max_bounds[4] = { this->GetWholeMaxPosition(0), 00621 this->GetWholeMaxPosition(1), 00622 this->GetWholeMaxPosition(2), 00623 0.0 }; 00624 00625 00626 // new efficient way to get the reslice origin and the axis coordinates. 00627 double reslice[4], pos2[4]; 00628 this->ScreenToRealWorldMatrix->MultiplyPoint (pos, reslice); 00629 this->ImageReslice->SetResliceAxesOrigin(reslice[0], reslice[1], reslice[2]); 00630 00631 00632 vtkMatrix4x4* mat = vtkMatrix4x4::New(); 00633 vtkMatrix4x4::Transpose (this->OrientationMatrix, mat); 00634 mat->MultiplyPoint (pos, pos2); 00635 mat->MultiplyPoint (min_bounds, min_bounds); 00636 mat->MultiplyPoint (max_bounds, max_bounds); 00637 mat->Delete(); 00638 00639 x = pos2[0]; 00640 y = pos2[1]; 00641 00642 max_x = max_bounds[0]; 00643 max_y = max_bounds[1]; 00644 00645 min_x = min_bounds[0]; 00646 min_y = min_bounds[1]; 00647 00648 /* 00649 switch (this->Orientation) 00650 { 00651 case NIREPvtkViewImage::SAGITTAL_ID: 00652 00653 this->ImageReslice->SetResliceAxesOrigin(pos[0],0,0); 00654 x = (double)pos[1]; 00655 y = (double)pos[2]; 00656 max_x = bounds[3]; 00657 max_y = bounds[5]; 00658 min_x = bounds[2]; 00659 min_y = bounds[4]; 00660 break; 00661 00662 case NIREPvtkViewImage::CORONAL_ID: 00663 00664 this->ImageReslice->SetResliceAxesOrigin(0,pos[1],0); 00665 if( this->Conventions==RADIOLOGIC ) 00666 { 00667 x = (double)pos[0]; 00668 max_x = bounds[1]; 00669 min_x = bounds[0]; 00670 } 00671 else 00672 { 00673 x = (double)pos[0]*-1.0; 00674 max_x = bounds[1]*-1.0; 00675 min_x = bounds[0]*-1.0; 00676 } 00677 y = (double)pos[2]; 00678 max_y = bounds[5]; 00679 min_y = bounds[4]; 00680 break; 00681 00682 00683 case NIREPvtkViewImage::AXIAL_ID: 00684 00685 this->ImageReslice->SetResliceAxesOrigin(0,0,pos[2]); 00686 00687 if( this->Conventions==RADIOLOGIC ) 00688 { 00689 x = (double)pos[0]; 00690 max_x = bounds[1]; 00691 min_x = bounds[0]; 00692 } 00693 else 00694 { 00695 x = (double)pos[0]*-1.0; 00696 max_x = bounds[1]*-1.0; 00697 min_x = bounds[0]*-1.0; 00698 } 00699 y = (double)pos[1]*-1.0; 00700 max_y = bounds[3]*-1.0; 00701 min_y = bounds[2]*-1.0; 00702 break; 00703 } 00704 */ 00705 00706 00707 this->HorizontalLineSource->SetPoint1(min_x, y, 0.001); 00708 this->HorizontalLineSource->SetPoint2(max_x, y, 0.001); 00709 this->VerticalLineSource->SetPoint1(x, min_y, 0.001); 00710 this->VerticalLineSource->SetPoint2(x, max_y, 0.001); 00711 00712 00713 this->ImageReslice->Update(); // needed to update input Extent 00714 00715 00716 int imCoor[3]; 00717 this->GetCurrentVoxelCoordinates(imCoor); 00718 int dims[3]; 00719 this->GetImage()->GetDimensions (dims); 00720 00721 std::ostringstream os2; 00722 std::ostringstream os; 00723 //os << "Slice: "; 00724 00725 os2 << "Zoom: " << this->GetZoom()*100.0 << " \%\n"; 00726 00727 switch( this->Orientation ) 00728 { 00729 case NIREPvtkViewImage::AXIAL_ID : 00730 os << "Image size: " << dims[0] << " x " << dims[1] << "\n"; 00731 os << "Voxel size: " << spacing[0] << " x " << spacing[1] << "\n"; 00732 //os << imCoor[2] << " / " << dims[2]-1 << std::endl; 00733 os << "X: " << imCoor[0] << " px Y: " << imCoor[1] << " px Value: " 00734 << this->GetCurrentPointDoubleValue() << std::endl; 00735 os << "X: " << pos[0] << " mm Y: " << pos[1] << " mm\n"; 00736 if ( this->ShowSliceNumber ) 00737 os2 << "Slice: " << imCoor[2] << " / " << dims[2]-1 << std::endl; 00738 os2 << "Location: " << pos[2] << " mm"; 00739 break; 00740 00741 00742 case NIREPvtkViewImage::CORONAL_ID : 00743 os << "Image size: " << dims[0] << " x " << dims[2] << "\n"; 00744 os << "Voxel size: " << spacing[0] << " x " << spacing[2] << "\n"; 00745 //os << imCoor[1] << " / " << dims[1]-1 << std::endl; 00746 os << "X: " << imCoor[0] << " px Z: " << imCoor[2] << " px Value: " 00747 << this->GetCurrentPointDoubleValue() << std::endl; 00748 os << "X: " << pos[0] << " mm Z: " << pos[2] << " mm\n"; 00749 if ( this->ShowSliceNumber ) 00750 os2 << "Slice: " << imCoor[1] << " / " << dims[1]-1 << std::endl; 00751 os2 << "Location: " << pos[1] << " mm"; 00752 break; 00753 00754 00755 case NIREPvtkViewImage::SAGITTAL_ID : 00756 os << "Image size: " << dims[1] << " x " << dims[2] << "\n"; 00757 os << "Voxel size: " << spacing[1] << " x " << spacing[2] << "\n"; 00758 //os << imCoor[0] << " / " << dims[0]-1 << std::endl; 00759 os << "Y: " << imCoor[1] << " px Z: " << imCoor[2] << " px Value: " 00760 << this->GetCurrentPointDoubleValue() << std::endl; 00761 os << "Y: " << pos[1] << " mm Z: " << pos[2] << " mm\n"; 00762 if ( this->ShowSliceNumber ) 00763 os2 << "Slice: " << imCoor[0] << " / " << dims[0]-1 << std::endl; 00764 os2 << "Location: " << pos[0] << " mm"; 00765 break; 00766 } 00767 os << "<window_level>"; 00768 00769 this->SetUpLeftAnnotation( os.str().c_str() ); 00770 this->SetDownLeftAnnotation( os2.str().c_str() ); 00771 // } 00772 // else 00773 // this->SetUpRightAnnotation(""); 00774 00775 unsigned int direction = this->GetOrthogonalAxis (this->GetOrientation()); 00776 this->DataSetCutPlane->SetOrigin (reslice[0], reslice[1], reslice[2]); 00777 00778 switch(direction) 00779 { 00780 case X_ID : 00781 //this->DataSetCutPlane->SetNormal (1,0,0); 00782 this->DataSetCutBox->SetBounds (this->DataSetCutPlane->GetOrigin()[0],this->DataSetCutPlane->GetOrigin()[0]+this->BoxThickness, 00783 this->GetWholeMinPosition(1),this->GetWholeMaxPosition(1), 00784 this->GetWholeMinPosition(2),this->GetWholeMaxPosition(2)); 00785 00786 break; 00787 case Y_ID : 00788 //this->DataSetCutPlane->SetNormal (0,1,0); 00789 this->DataSetCutBox->SetBounds (this->GetWholeMinPosition(0),this->GetWholeMaxPosition(0), 00790 this->DataSetCutPlane->GetOrigin()[1],this->DataSetCutPlane->GetOrigin()[1]+this->BoxThickness, 00791 this->GetWholeMinPosition(2),this->GetWholeMaxPosition(2)); 00792 break; 00793 case Z_ID : 00794 //this->DataSetCutPlane->SetNormal (0,0,1); 00795 this->DataSetCutBox->SetBounds (this->GetWholeMinPosition(0),this->GetWholeMaxPosition(0), 00796 this->GetWholeMinPosition(1),this->GetWholeMaxPosition(1), 00797 this->DataSetCutPlane->GetOrigin()[2],this->DataSetCutPlane->GetOrigin()[2]+this->BoxThickness); 00798 break; 00799 } 00800 00801 00802 if( this->DataSetList.size() ) 00803 { 00804 00805 this->ResetAndRestablishZoomAndCamera(); 00806 00807 /* 00808 We need to correct for the origin of the actor. Indeed, the ImageActor 00809 has always position 0 in Z in axial view, in X in sagittal view and 00810 in Y in coronal view. The projected dataset have an origin that depends 00811 on the required slice and can be negative. In that case, the projected 00812 data are behind the image actor and thus not visible. Here, we correct 00813 this by translating the actor so that it becomes visible. 00814 */ 00815 for( unsigned int i=0; i<this->DataSetActorList.size(); i++) 00816 { 00817 double Pos[3]; 00818 this->DataSetActorList[i]->GetPosition (Pos); 00819 00820 switch(direction) 00821 { 00822 case X_ID : 00823 Pos[0] = -1.0*reslice[0] + 1.0; 00824 break; 00825 00826 case Y_ID: 00827 Pos[1] = -1.0*reslice[1] + 1.0; 00828 break; 00829 00830 case Z_ID: 00831 Pos[2] = -1.0*reslice[2] + 1.0; 00832 break; 00833 } 00834 00835 this->DataSetActorList[i]->SetPosition (Pos); 00836 } 00837 00838 } 00839 00840 this->Modified(); 00841 } 00842 00843 00844 void NIREPvtkViewImage2D::SetWindow (double w) 00845 { 00846 00847 if( w<0.0 ) 00848 { 00849 w = 0.0; 00850 } 00851 00852 double shiftScaleWindow = this->GetShift() + w*this->GetScale(); 00853 00854 NIREPvtkViewImage::SetWindow ( shiftScaleWindow ); 00855 this->WindowLevelForCorner->SetWindow( shiftScaleWindow ); 00856 00857 double v_min = this->GetLevel() - 0.5*this->GetWindow(); 00858 double v_max = this->GetLevel() + 0.5*this->GetWindow(); 00859 00860 if( this->GetLookupTable() && this->WindowLevel->GetLookupTable()) 00861 { 00862 00863 this->GetLookupTable()->SetRange ( (v_min-0.5*this->GetShift())/this->GetScale(), 00864 (v_max-1.5*this->GetShift())/this->GetScale()); 00865 this->WindowLevel->GetLookupTable()->SetRange (v_min, v_max); 00866 } 00867 00868 if (this->BGWindowLevel && this->BGWindowLevel->GetLookupTable()) 00869 this->BGWindowLevel->GetLookupTable()->SetRange (v_min, v_max); 00870 00871 00872 } 00873 00874 00875 void NIREPvtkViewImage2D::SetLevel (double l) 00876 { 00877 00878 double shiftScaleLevel = this->GetShift() + l*this->GetScale(); 00879 00880 NIREPvtkViewImage::SetLevel ( shiftScaleLevel ); 00881 this->WindowLevelForCorner->SetLevel( shiftScaleLevel ); 00882 00883 double v_min = this->GetLevel() - 0.5*this->GetWindow(); 00884 double v_max = this->GetLevel() + 0.5*this->GetWindow(); 00885 00886 if( this->GetLookupTable() && this->WindowLevel->GetLookupTable()) 00887 { 00888 this->GetLookupTable()->SetRange ( (v_min-0.5*this->GetShift())/this->GetScale(), 00889 (v_max-1.5*this->GetShift())/this->GetScale()); 00890 this->WindowLevel->GetLookupTable()->SetRange (v_min, v_max); 00891 } 00892 } 00893 00894 00895 double NIREPvtkViewImage2D::GetColorWindow() 00896 { 00897 return this->GetWindow(); 00898 } 00899 00900 00901 double NIREPvtkViewImage2D::GetColorLevel() 00902 { 00903 return this->GetLevel(); 00904 } 00905 00906 00907 void NIREPvtkViewImage2D::SetTransform(vtkTransform* p_transform) 00908 { 00909 this->ImageReslice->SetResliceTransform(p_transform); 00910 this->Modified(); 00911 } 00912 00913 00914 void NIREPvtkViewImage2D::SetMatrix(vtkMatrix4x4* p_matrix, bool centered) 00915 { 00916 if(!p_matrix) 00917 return; 00918 00919 if(this->ImageActor) { 00920 if(centered) { 00921 //we need to decompose the matrix.: 00922 //1. move the image to the center 00923 //2. rotate the image with rotation in p_matrix 00924 //3. move the image back to its place 00925 //4. apply the translation contained in p_matrix 00926 00927 double *propCenter = 0; 00928 double *propPosition = 0; 00929 00930 propCenter = this->ImageActor->GetCenter(); 00931 propPosition = this->ImageActor->GetPosition(); 00932 00933 vtkMatrix4x4 *finalMat = vtkMatrix4x4::New(); 00934 00935 vtkMatrix4x4 *toCenterMat = vtkMatrix4x4::New(); 00936 toCenterMat->Identity(); 00937 (*toCenterMat)[0][3] = - ( propCenter[0] - propPosition[0] ); 00938 (*toCenterMat)[1][3] = - ( propCenter[1] - propPosition[1] ); 00939 (*toCenterMat)[2][3] = - ( propCenter[2] - propPosition[2] ); 00940 00941 vtkMatrix4x4 *rotationMat = vtkMatrix4x4::New(); 00942 rotationMat->Identity(); 00943 (*rotationMat)[0][0] = (*p_matrix)[0][0]; 00944 (*rotationMat)[0][1] = (*p_matrix)[0][1]; 00945 (*rotationMat)[0][2] = (*p_matrix)[0][2]; 00946 00947 (*rotationMat)[1][0] = (*p_matrix)[1][0]; 00948 (*rotationMat)[1][1] = (*p_matrix)[1][1]; 00949 (*rotationMat)[1][2] = (*p_matrix)[1][2]; 00950 00951 (*rotationMat)[2][0] = (*p_matrix)[2][0]; 00952 (*rotationMat)[2][1] = (*p_matrix)[2][1]; 00953 (*rotationMat)[2][2] = (*p_matrix)[2][2]; 00954 00955 vtkMatrix4x4 *fromCenterMat = vtkMatrix4x4::New(); 00956 fromCenterMat->Identity(); 00957 (*fromCenterMat)[0][3] = ( propCenter[0] - propPosition[0] ); 00958 (*fromCenterMat)[1][3] = ( propCenter[1] - propPosition[1] ); 00959 (*fromCenterMat)[2][3] = ( propCenter[2] - propPosition[2] ); 00960 00961 vtkMatrix4x4 *translationMat = vtkMatrix4x4::New(); 00962 translationMat->Identity(); 00963 (*translationMat)[0][3] = (*p_matrix)[0][3]; 00964 (*translationMat)[1][3] = (*p_matrix)[1][3]; 00965 (*translationMat)[2][3] = (*p_matrix)[2][3]; 00966 00967 vtkMatrix4x4::Multiply4x4(rotationMat, toCenterMat, finalMat); 00968 vtkMatrix4x4::Multiply4x4(fromCenterMat, finalMat, finalMat); 00969 vtkMatrix4x4::Multiply4x4(translationMat, finalMat, finalMat); 00970 00971 this->ImageActor->SetUserMatrix(finalMat); 00972 finalMat->Delete(); 00973 toCenterMat->Delete(); 00974 rotationMat->Delete(); 00975 translationMat->Delete(); 00976 } 00977 else { 00978 this->ImageActor->SetUserMatrix(p_matrix); 00979 } 00980 this->ImageActor->GetUserMatrix()->PrintSelf(std::cout, vtkIndent()); 00981 } 00982 00983 this->Modified(); 00984 } 00985 00986 00987 void NIREPvtkViewImage2D::SetImage(vtkImageData* image) 00988 { 00989 if(!image) 00990 { 00991 return; 00992 } 00993 00994 int* extent = image->GetExtent(); 00995 if( extent[1]<extent[0] || extent[3]<extent[2] || extent[5]<extent[4] ) 00996 { 00997 vtkErrorMacro ( << "Image extent is not valid: " << extent[0] << " " 00998 << extent[1] << " " 00999 << extent[2] << " " 01000 << extent[3] << " " 01001 << extent[4] << " " 01002 << extent[5]); 01003 return; 01004 } 01005 01006 NIREPvtkViewImage::SetImage( image ); 01007 01008 // check if there is a mask image. If yes, then we check 01009 // if the new image size and spacing agrees with the mask image. 01010 // If not, we remove the mask image 01011 if( this->GetMaskImage() ) 01012 { 01013 int* dims = image->GetDimensions(); 01014 double* spacing = image->GetSpacing(); 01015 int* maskDims = this->GetMaskImage()->GetDimensions(); 01016 double* maskSpacing = this->GetMaskImage()->GetSpacing(); 01017 01018 if( dims[0]!=maskDims[0] || dims[1]!=maskDims[1] || dims[2]!=maskDims[2] || 01019 spacing[0]!=maskSpacing[0] || spacing[1]!=maskSpacing[1] || spacing[2]!=maskSpacing[2] ) 01020 { 01021 this->RemoveMaskImage(); 01022 } 01023 } 01024 01025 // should check also the overlapping image 01026 01027 if( image->GetScalarType() == VTK_UNSIGNED_CHAR && (image->GetNumberOfScalarComponents()==3 || image->GetNumberOfScalarComponents()==4) ) 01028 { 01029 this->AuxInput = image; 01030 } 01031 else 01032 { 01033 this->AuxInput = this->WindowLevel->GetOutput(); 01034 01035 this->WindowLevel->SetInput (image); 01036 double range[2]; 01037 image->GetScalarRange (range); 01038 if ( this->WindowLevel->GetLookupTable() ) 01039 { 01040 this->WindowLevel->GetLookupTable()->SetRange (range); 01041 } 01042 } 01043 01044 01045 if( this->GetOverlappingImage() ) 01046 { 01047 this->Blender->SetInput (0, this->AuxInput ); 01048 } 01049 else 01050 { 01051 if( this->GetMaskImage() ) 01052 { 01053 this->MaskFilter->SetImageInput ( this->AuxInput ); 01054 } 01055 else 01056 { 01057 this->ImageReslice->SetInput ( this->AuxInput ); 01058 this->ResliceInput = this->AuxInput; 01059 } 01060 } 01061 01062 this->ImageActor->SetInput( this->ImageReslice->GetOutput() ); 01063 01064 this->AddActor(this->HorizontalLineActor); 01065 this->AddActor(this->VerticalLineActor); 01066 01067 this->AddActor(this->ImageActor); 01068 01069 01070 01071 // Save the camera focal and position, and zoom, before calling InternalUpdate() 01072 double focal[3], pos[3], zoom; 01073 this->GetCameraFocalAndPosition (focal, pos); 01074 zoom = this->GetZoom(); 01075 01076 01077 this->SetupAnnotations(); 01078 this->InternalUpdate(); 01079 01080 01081 // Check that the current displayed point lies within the bounds of the image. If not, 01082 // we camp it to the nearest acceptable position. 01083 double *wextent = image->GetBounds(); 01084 double position[3]; 01085 this->GetCurrentPoint ( position ); 01086 position[0]<wextent[0]?position[0]=wextent[0]:position[0]; 01087 position[0]>wextent[1]?position[0]=wextent[1]:position[0]; 01088 position[1]<wextent[2]?position[1]=wextent[2]:position[1]; 01089 position[1]>wextent[3]?position[1]=wextent[3]:position[1]; 01090 position[2]<wextent[4]?position[2]=wextent[4]:position[2]; 01091 position[2]>wextent[5]?position[2]=wextent[5]:position[2]; 01092 this->SetCurrentPoint ( position ); 01093 01094 01095 01096 //this->SetWindow( this->GetWindow() ); 01097 //this->SetLevel( this->GetLevel() ); 01098 01099 01100 // restore the zoom and focal in case this is not the first time we render the image. 01101 if( !this->GetFirstImage() ) 01102 { 01103 this->SetZoom ( zoom ); 01104 this->SetCameraFocalAndPosition (focal, pos); 01105 this->SetFirstImage (0); 01106 } 01107 01108 if( this->RulerWidgetVisibility ) 01109 this->RulerWidget->On(); 01110 01111 } 01112 01113 01114 void NIREPvtkViewImage2D::SetLookupTable (vtkScalarsToColors* lut) 01115 { 01116 01117 if( !lut ) 01118 { 01119 return; 01120 } 01121 01122 NIREPvtkViewImage::SetLookupTable (lut); 01123 01124 double v_min = this->GetLevel() - 0.5*this->GetWindow(); 01125 double v_max = this->GetLevel() + 0.5*this->GetWindow(); 01126 01132 lut->SetRange ( (v_min-0.5*this->GetShift())/this->GetScale(), 01133 (v_max-1.5*this->GetShift())/this->GetScale() ); 01134 01135 01136 vtkLookupTable* realLut = vtkLookupTable::SafeDownCast (lut); 01137 01138 if( !realLut ) 01139 { 01140 std::cerr << "Error: Cannot cast vtkScalarsToColors to vtkLookupTable." << std::endl; 01141 return; 01142 } 01143 01148 vtkLookupTable* newLut = vtkLookupTable::New(); 01149 newLut->DeepCopy (realLut); 01150 newLut->SetRange (v_min, v_max); 01151 this->WindowLevel->SetLookupTable (newLut); 01152 newLut->Delete(); 01153 } 01154 01155 01156 void NIREPvtkViewImage2D::SetBGLookupTable (vtkScalarsToColors* lut) 01157 { 01158 this->BGLookupTable = lut; 01159 double v_min = this->GetLevel() - 0.5*this->GetWindow(); 01160 double v_max = this->GetLevel() + 0.5*this->GetWindow(); 01161 01167 lut->SetRange ( (v_min-0.5*this->GetShift())/this->GetScale(), 01168 (v_max-1.5*this->GetShift())/this->GetScale() ); 01169 01170 01171 vtkLookupTable* realLut = vtkLookupTable::SafeDownCast (lut); 01172 01173 if( !realLut ) 01174 { 01175 std::cerr << "Error: Cannot cast vtkScalarsToColors to vtkLookupTable." << std::endl; 01176 return; 01177 } 01178 01183 vtkLookupTable* newLut = vtkLookupTable::New(); 01184 newLut->DeepCopy (realLut); 01185 newLut->SetRange (v_min, v_max); 01186 this->BGWindowLevel->SetLookupTable (newLut); 01187 newLut->Delete(); 01188 01189 this->Modified(); 01190 } 01191 01192 01193 vtkScalarsToColors* NIREPvtkViewImage2D::GetBGLookupTable (void) const 01194 { 01195 return this->BGLookupTable; 01196 } 01197 01198 01199 void NIREPvtkViewImage2D::SetOrientation(unsigned int p_orientation) 01200 { 01201 if( (p_orientation > NIREPvtkViewImage::NB_PLAN_IDS - 1) || (this->Orientation == p_orientation) ) 01202 { 01203 return; 01204 } 01205 01206 this->Orientation = p_orientation; 01207 01208 01209 // setup the OrientationMatrix and the ScreenToRealWorldMatrix. Then, we have no 01210 // need to check the view's orientation to determine what slice to display: a 01211 // simple matrix multiplication will tell it for us. 01212 this->OrientationMatrix->Zero(); 01213 this->ScreenToRealWorldMatrix->Zero(); 01214 01215 01216 if( this->Orientation == NIREPvtkViewImage::SAGITTAL_ID ) 01217 { 01218 this->ImageReslice->SetResliceAxesDirectionCosines( 0, -1, 0, 01219 0, 0, 1, 01220 1, 0, 0); 01221 this->OrientationMatrix->SetElement (0, 2, 0.0); 01222 this->OrientationMatrix->SetElement (1, 0, -1.0); 01223 this->OrientationMatrix->SetElement (2, 1, 1.0); 01224 01225 this->ScreenToRealWorldMatrix->SetElement (0, 0, 1.0); 01226 } 01227 01228 01229 if( this->Orientation == NIREPvtkViewImage::CORONAL_ID ) 01230 { 01231 if( this->Conventions == RADIOLOGIC ) 01232 { 01233 this->OrientationMatrix->SetElement(0, 0, 1.0); 01234 this->ImageReslice->SetResliceAxesDirectionCosines(1, 0, 0, 01235 0, 0, 1, 01236 0, 1, 0); 01237 } 01238 else 01239 { 01240 this->OrientationMatrix->SetElement(0, 0, -1.0); 01241 this->ImageReslice->SetResliceAxesDirectionCosines(-1, 0, 0, 01242 0, 0, 1, 01243 0, 1, 0); 01244 } 01245 01246 this->OrientationMatrix->SetElement(2, 1, 1.0); 01247 this->ScreenToRealWorldMatrix->SetElement (1, 1, 1.0); 01248 } 01249 01250 01251 if( this->Orientation == NIREPvtkViewImage::AXIAL_ID ) 01252 { 01253 01254 01255 if( this->Conventions == RADIOLOGIC ) 01256 { 01257 this->OrientationMatrix->SetElement(0, 0, 1.0 ); 01258 this->ImageReslice->SetResliceAxesDirectionCosines(1, 0, 0, 01259 0, 1, 0, 01260 0, 0, 1); 01261 } 01262 else 01263 { 01264 this->OrientationMatrix->SetElement(0, 0, -1.0 ); 01265 this->ImageReslice->SetResliceAxesDirectionCosines(-1, 0, 0, 01266 0, 1, 0, 01267 0, 0, 1); 01268 } 01269 01270 01271 01272 this->OrientationMatrix->SetElement(1, 1, 1.0 ); 01273 this->ScreenToRealWorldMatrix->SetElement (2, 2, 1.0); 01274 } 01275 01276 unsigned int direction = this->GetOrthogonalAxis (this->GetOrientation()); 01277 switch(direction) 01278 { 01279 case X_ID : 01280 this->DataSetCutPlane->SetNormal (1,0,0); 01281 break; 01282 case Y_ID : 01283 this->DataSetCutPlane->SetNormal (0,1,0); 01284 break; 01285 case Z_ID : 01286 this->DataSetCutPlane->SetNormal (0,0,1); 01287 break; 01288 } 01289 01290 //this->ImageReslice->Modified(); 01291 01292 this->UpdateImageActor(); // make sure update extent are up to date 01293 this->UpdatePosition(); // make sure reslicer origin are ok 01294 this->InitializeImagePositionAndSize(); // reset and center the view 01295 this->SetupAnnotations(); // make sure annotations are ok 01296 01297 this->Modified(); 01298 } 01299 01300 01301 void NIREPvtkViewImage2D::SetupAnnotations() 01302 { 01303 if( !this->GetImage() ) 01304 { 01305 return; 01306 } 01307 01308 // int *dims = this->GetImage()->GetDimensions(); 01309 // double *spacing = this->GetImage()->GetSpacing(); 01310 01311 // std::ostringstream os; 01312 // os << "Image Size: "; 01313 01314 std::ostringstream os; 01315 01316 if( strcmp (this->GetPatientNameData(),"")!=0 ) 01317 os << this->GetPatientNameData() << "\n"; 01318 else 01319 os << "No Patient Name\n"; 01320 01321 if( strcmp (this->GetStudyNameData(),"")!=0 ) 01322 os << this->GetStudyNameData() << "\n"; 01323 else 01324 os << "No Study Name\n"; 01325 01326 if( strcmp (this->GetSerieNameData(),"")!=0 ) 01327 os << this->GetSerieNameData() << "\n"; 01328 else 01329 os << "No Serie Name\n"; 01330 01331 this->SetUpRightAnnotation ( os.str().c_str() ); 01332 01333 if( this->Orientation == NIREPvtkViewImage::SAGITTAL_ID ) 01334 { 01335 // os << dims[1] << " x " << dims[2] << std::endl; 01336 // os << "Voxel Size: " << spacing[1] << " x " << spacing[2] << " mm"; 01337 01338 this->SetNorthAnnotation("S"); 01339 this->SetSouthAnnotation("I"); 01340 this->SetEastAnnotation ("P"); 01341 this->SetWestAnnotation("A"); 01342 01343 this->HorizontalLineActor->GetProperty()->SetColor (1.0,0.0,0.0); 01344 this->VerticalLineActor->GetProperty()->SetColor (0.0,1.0,0.0); 01345 } 01346 01347 01348 if( this->Orientation == NIREPvtkViewImage::CORONAL_ID ) 01349 { 01350 // os << dims[0] << " x " << dims[2] << std::endl; 01351 // os << "Voxel Size: " << spacing[0] << " x " << spacing[2] << " mm"; 01352 01353 this->HorizontalLineActor->GetProperty()->SetColor (1.0,0.0,0.0); 01354 this->VerticalLineActor->GetProperty()->SetColor (0.0,0.0,1.0); 01355 01356 this->SetNorthAnnotation("S"); 01357 this->SetSouthAnnotation("I"); 01358 if( this->Conventions == RADIOLOGIC) 01359 { 01360 this->SetEastAnnotation ("L"); 01361 this->SetWestAnnotation("R"); 01362 } 01363 else 01364 { 01365 this->SetEastAnnotation ("R"); 01366 this->SetWestAnnotation("L"); 01367 } 01368 } 01369 01370 if( this->Orientation == NIREPvtkViewImage::AXIAL_ID ) 01371 { 01372 // os << dims[0] << " x " << dims[1] << std::endl; 01373 // os << "Voxel Size: " << spacing[0] << " x " << spacing[1] << " mm"; 01374 01375 this->SetNorthAnnotation("A"); 01376 this->SetSouthAnnotation("P"); 01377 if( this->Conventions == RADIOLOGIC ) 01378 { 01379 this->SetEastAnnotation ("L"); 01380 this->SetWestAnnotation("R"); 01381 } 01382 else 01383 { 01384 this->SetEastAnnotation ("R"); 01385 this->SetWestAnnotation("L"); 01386 } 01387 01388 this->HorizontalLineActor->GetProperty()->SetColor (0.0,1.0,0.0); 01389 this->VerticalLineActor->GetProperty()->SetColor (0.0,0.0,1.0); 01390 } 01391 01392 // this->SetSizeData ( os.str().c_str() ); 01393 this->Modified(); 01394 } 01395 01396 01397 void NIREPvtkViewImage2D::ScreenCoordinatesToPosition (double sc[2], double pos[3] ) 01398 { 01399 double p_sc[4]; 01400 p_sc[0] = sc[0]; 01401 p_sc[1] = sc[1]; 01402 p_sc[2] = 0.0; 01403 p_sc[3] = 0.0; 01404 01405 double p_pos[4]; 01406 this->GetCurrentPoint (p_pos); 01407 p_pos[3] = 0.0; 01408 01409 this->OrientationMatrix->MultiplyPoint (p_sc, p_sc); 01410 this->ScreenToRealWorldMatrix->MultiplyPoint (p_pos, p_pos); 01411 01412 for( int i=0; i<3; i++) 01413 pos[i] = p_sc[i] + p_pos[i]; 01414 } 01415 01416 01417 void NIREPvtkViewImage2D::SetInterpolationMode(int i) 01418 { 01419 this->ImageActor->SetInterpolate(i); 01420 this->Modified(); 01421 } 01422 01423 01424 int NIREPvtkViewImage2D::GetInterpolationMode(void) 01425 { 01426 return this->ImageActor->GetInterpolate(); 01427 } 01428 01429 01430 void NIREPvtkViewImage2D::SetRulerWidgetVisibility (int val) 01431 { 01432 this->RulerWidgetVisibility = val; 01433 if( this->RulerWidgetVisibility ) 01434 { 01435 this->RulerWidget->On(); 01436 } 01437 else 01438 { 01439 this->RulerWidget->Off(); 01440 } 01441 } 01442 01443 01444 void NIREPvtkViewImage2D::SetMaskImage (vtkImageData* mask, vtkLookupTable* lut) 01445 { 01446 01447 if( !this->GetImage() || !mask || !lut) 01448 { 01449 return; 01450 } 01451 01452 01453 NIREPvtkViewImage::SetMaskImage (mask, lut); 01454 01455 01456 // check if the mask dimensions match the image dimensions 01457 int dim1[3], dim2[3]; 01458 this->GetImage()->GetDimensions (dim1); 01459 mask->GetDimensions (dim2); 01460 if ( (dim1[0] != dim2[0]) || 01461 (dim1[1] != dim2[1]) || 01462 (dim1[2] != dim2[2]) ) 01463 { 01464 vtkErrorMacro("Dimensions of the mask image do not match"); 01465 return; 01466 } 01467 01468 01469 // check if the scalar range match the number of entries in the LUT 01470 double range[2]; 01471 mask->GetScalarRange (range); 01472 int numLUT = lut->GetNumberOfTableValues(); 01473 if( numLUT<(int)(range[1])+1 ) 01474 { 01475 vtkErrorMacro("The number of LUT entries is less than the range of the mask."); 01476 return; 01477 } 01478 01479 if( this->GetOverlappingImage() ) 01480 { 01481 this->MaskFilter->SetImageInput ( this->Blender->GetOutput() ); 01482 } 01483 else 01484 { 01485 this->MaskFilter->SetImageInput ( this->AuxInput ); 01486 } 01487 this->MaskFilter->SetMaskInput (mask); 01488 this->MaskFilter->SetLookupTable (lut); 01489 this->MaskFilter->Update(); 01490 01491 01492 this->ImageReslice->SetInputConnection( this->MaskFilter->GetOutputPort() ); 01493 this->ResliceInput = this->MaskFilter->GetOutput(); 01494 01495 } 01496 01497 01498 void NIREPvtkViewImage2D::RemoveMaskImage() 01499 { 01500 01501 if( this->GetOverlappingImage() ) 01502 { 01503 this->ImageReslice->SetInputConnection( this->Blender->GetOutputPort() ); 01504 this->ResliceInput = this->Blender->GetOutput(); 01505 } 01506 else 01507 { 01508 this->ImageReslice->SetInput( this->AuxInput ); 01509 this->ResliceInput = this->AuxInput; 01510 } 01511 01512 NIREPvtkViewImage::SetMaskImage (0,0); 01513 } 01514 01515 01516 void NIREPvtkViewImage2D::SetOverlappingImage (vtkImageData* image) 01517 { 01518 NIREPvtkViewImage::SetOverlappingImage ( image ); 01519 01520 if( !this->GetImage() || !image ) 01521 { 01522 return; 01523 } 01524 01525 this->Blender->RemoveAllInputs(); 01526 this->Blender->AddInput ( this->AuxInput ); 01527 this->Blender->AddInput ( image ); 01528 01529 if( this->GetMaskImage() ) 01530 { 01531 this->MaskFilter->SetInputConnection ( this->Blender->GetOutputPort() ); 01532 } 01533 else 01534 { 01535 this->ImageReslice->SetInputConnection ( this->Blender->GetOutputPort() ); 01536 this->ResliceInput = this->Blender->GetOutput(); 01537 } 01538 } 01539 01540 01541 void NIREPvtkViewImage2D::RemoveOverlappingImage() 01542 { 01543 01544 if( this->GetMaskImage() ) 01545 { 01546 this->MaskFilter->SetInput (this->AuxInput); 01547 } 01548 else 01549 { 01550 this->ImageReslice->SetInput (this->AuxInput); 01551 this->ResliceInput = this->AuxInput; 01552 } 01553 01554 NIREPvtkViewImage::SetOverlappingImage ( 0 ); 01555 } 01556 01557 01558 vtkActor* NIREPvtkViewImage2D::AddDataSet (vtkDataSet* dataset, vtkProperty* property) 01559 { 01560 01561 bool doit = true; 01562 01563 if (!dataset) 01564 doit = false; 01565 01566 if( this->HasDataSet (dataset) ) 01567 { 01568 doit = false; 01569 } 01570 01571 01572 vtkImageData* imagedata = vtkImageData::SafeDownCast(dataset); 01573 01574 if (imagedata) 01575 { 01576 this->SetImage(imagedata); 01577 } 01578 else 01579 { 01580 if ( !this->GetImage() && !this->GetBGImage() ) 01581 { 01582 doit = false; 01583 } 01584 // don't constrain the memory of input datasets anymore. 01595 if (doit) 01596 { 01597 01598 vtkMatrix4x4* matrix = vtkMatrix4x4::New(); 01599 for (unsigned int i=0; i<3; i++) 01600 { 01601 for (unsigned int j=0; j<3; j++) 01602 { 01603 matrix->SetElement(i,j,this->ImageReslice->GetResliceAxes()->GetElement(j,i)); 01604 } 01605 matrix->SetElement(i,3,0); 01606 } 01607 matrix->SetElement(3,3,1); 01608 01609 vtkCutter* cutter = vtkCutter::New(); 01610 cutter->SetCutFunction ( this->DataSetCutPlane ); 01611 01612 // Very strangely in some cases (ex : landmarks) 01613 // the cutter increments the RefCount of the input dataset by 2 01614 // making some memory leek... 01615 // I could not manage to know what is wrong here 01616 cutter->SetInput (dataset); 01617 cutter->Update(); 01618 01619 if (!cutter->GetOutput()) 01620 { 01621 vtkWarningMacro(<< "Unable to cut this dataset..."); 01622 matrix->Delete(); 01623 cutter->Delete(); 01624 return NULL; 01625 } 01626 01627 vtkPolyDataMapper* mapper = vtkPolyDataMapper::New(); 01628 mapper->SetInput (cutter->GetOutput()); 01629 01630 vtkActor* actor = vtkActor::New(); 01631 actor->SetUserMatrix (matrix); 01632 actor->SetMapper (mapper); 01633 if (property) 01634 { 01635 actor->SetProperty (property); 01636 } 01637 01638 //actor->PickableOff(); 01639 01640 this->AddActor (actor); 01641 this->DataSetList.push_back (dataset); 01642 this->DataSetActorList.push_back (actor); 01643 01644 this->ResetAndRestablishZoomAndCamera(); 01645 01646 actor->Delete(); 01647 mapper->Delete(); 01648 matrix->Delete(); 01649 cutter->Delete(); 01650 } 01651 } 01652 01653 return this->GetDataSetActor(dataset); 01654 01655 } 01656 01657 01658 vtkActor* NIREPvtkViewImage2D::AddPolyData (vtkPolyData* polydata, vtkProperty* property, double thickness) 01659 { 01660 01661 bool doit = true; 01662 if (!polydata || this->HasDataSet (polydata) || !this->GetImage()) 01663 { 01664 doit = false; 01665 } 01666 01667 01668 if (doit) 01669 { 01670 01671 if (thickness) 01672 { 01673 this->BoxThickness = thickness; 01674 } 01675 01676 01677 vtkClipDataSet* clipper = vtkClipDataSet::New(); 01678 clipper->GenerateClippedOutputOff(); 01679 clipper->InsideOutOn (); 01680 clipper->SetInput (polydata); 01681 01682 /* 01683 unsigned int direction = this->GetOrthogonalAxis (this->GetOrientation()); 01684 switch(direction) 01685 { 01686 01687 case X_ID : 01688 this->DataSetCutBox->SetBounds (this->DataSetCutPlane->GetOrigin()[0]-0.5*this->BoxThickness,this->DataSetCutPlane->GetOrigin()[0]+0.5*this->BoxThickness, 01689 this->GetWholeMinPosition(1),this->GetWholeMaxPosition(1), 01690 this->GetWholeMinPosition(2),this->GetWholeMaxPosition(2)); 01691 01692 break; 01693 case Y_ID : 01694 this->DataSetCutBox->SetBounds (this->GetWholeMinPosition(0),this->GetWholeMaxPosition(0), 01695 this->DataSetCutPlane->GetOrigin()[1]-0.5*this->BoxThickness,this->DataSetCutPlane->GetOrigin()[1]+0.5*this->BoxThickness, 01696 this->GetWholeMinPosition(2),this->GetWholeMaxPosition(2)); 01697 break; 01698 case Z_ID : 01699 this->DataSetCutBox->SetBounds (this->GetWholeMinPosition(0),this->GetWholeMaxPosition(0), 01700 this->GetWholeMinPosition(1),this->GetWholeMaxPosition(1), 01701 this->DataSetCutPlane->GetOrigin()[2]-0.5*this->BoxThickness,this->DataSetCutPlane->GetOrigin()[2]+0.5*this->BoxThickness); 01702 break; 01703 } 01704 */ // -> already done in SetOrientation() 01705 01706 clipper->SetClipFunction ( this->DataSetCutBox ); 01707 clipper->Update(); 01708 01709 01710 vtkMatrix4x4* matrix = vtkMatrix4x4::New(); 01711 for (unsigned int i=0; i<3; i++) 01712 { 01713 for (unsigned int j=0; j<3; j++) 01714 { 01715 matrix->SetElement(i, j, this->ImageReslice->GetResliceAxes()->GetElement(j,i)); 01716 } 01717 } 01718 matrix->SetElement(3,3,1); 01719 01720 01721 01722 vtkDataSetMapper* mapper = vtkDataSetMapper::New(); 01723 mapper->SetInput (clipper->GetOutput()); 01724 01725 vtkActor* actor = vtkActor::New(); 01726 actor->SetMapper (mapper); 01727 actor->SetUserMatrix (matrix); 01728 if (property) 01729 { 01730 actor->SetProperty (property); 01731 } 01732 01733 01734 this->AddActor (actor); 01735 this->DataSetList.push_back (polydata); 01736 this->DataSetActorList.push_back (actor); 01737 01738 this->ResetAndRestablishZoomAndCamera(); 01739 01740 actor->Delete(); 01741 mapper->Delete(); 01742 matrix->Delete(); 01743 clipper->Delete(); 01744 } 01745 01746 return this->GetDataSetActor(polydata); 01747 01748 } 01749 01750 01751 vtkActor* NIREPvtkViewImage2D::SyncAddPolyData (vtkPolyData* polydata, vtkProperty* property, double thickness) 01752 { 01753 01754 if( this->IsLocked() ) 01755 { 01756 return NULL; 01757 } 01758 01759 vtkActor* actor = this->AddPolyData (polydata, property, thickness); 01760 01761 this->Lock(); 01762 for( unsigned int i=0; i<this->Children.size(); i++) 01763 { 01764 NIREPvtkViewImage2D* view = NIREPvtkViewImage2D::SafeDownCast (this->Children[i]); 01765 if( view ) 01766 { 01767 view->SyncAddPolyData (polydata, property, thickness); 01768 } 01769 } 01770 this->UnLock(); 01771 01772 return actor; 01773 } 01774 01775 01776 void NIREPvtkViewImage2D::ResetZoom() 01777 { 01778 NIREPvtkViewImage::ResetZoom(); 01779 this->SetZoom ( 1.0 ); 01780 } 01781 01782 01783 void NIREPvtkViewImage2D::SetShow2DAxis(int show) 01784 { 01785 this->Show2DAxis = show; 01786 this->HorizontalLineActor->SetVisibility(show); 01787 this->VerticalLineActor->SetVisibility(show); 01788 this->Modified(); 01789 } 01790 01791 01792 void NIREPvtkViewImage2D::SetZoom (double factor) 01793 { 01794 01795 if ( !this->GetRenderer() ) 01796 { 01797 return; 01798 } 01799 01800 NIREPvtkViewImage::SetZoom ( factor ); //this->GetZoom() ); //*factor ); 01801 01802 01803 vtkCamera *camera = this->GetRenderer()->GetActiveCamera(); 01804 01805 01806 camera->SetParallelScale(this->InitialParallelScale / this->GetZoom() ); 01807 //camera->GetParallelScale() / factor ); 01808 01809 01810 if ( this->GetRenderWindowInteractor()->GetLightFollowCamera() ) 01811 { 01812 this->GetRenderer()->UpdateLightsGeometryToFollowCamera(); 01813 } 01814 01815 01816 if( this->GetImage() ) 01817 { 01818 int imCoor[3]; 01819 this->GetCurrentVoxelCoordinates(imCoor); 01820 double pos[3]; 01821 this->GetCurrentPoint (pos); 01822 int* dims = this->GetImage()->GetDimensions(); 01823 std::ostringstream os; 01824 os << "Zoom: " << this->GetZoom()*100.0 << " \%\n"; 01825 switch( this->Orientation ) 01826 { 01827 case NIREPvtkViewImage::AXIAL_ID : 01828 if ( this->ShowSliceNumber ) 01829 os << "Slice: " << imCoor[2] << " / " << dims[2]-1 << std::endl; 01830 os << "Location: " << pos[2] << " mm"; 01831 break; 01832 01833 case NIREPvtkViewImage::CORONAL_ID : 01834 if ( this->ShowSliceNumber ) 01835 os << "Slice: " << imCoor[1] << " / " << dims[1]-1 << std::endl; 01836 os << "Location: " << pos[1] << " mm"; 01837 break; 01838 01839 case NIREPvtkViewImage::SAGITTAL_ID : 01840 if ( this->ShowSliceNumber ) 01841 os << "Slice: " << imCoor[0] << " / " << dims[0]-1 << std::endl; 01842 os << "Location: " << pos[0] << " mm"; 01843 break; 01844 } 01845 01846 this->SetDownLeftAnnotation( os.str().c_str() ); 01847 } 01848 01849 } 01850 01851 01852 void NIREPvtkViewImage2D::SetConventions (int val) 01853 { 01854 if( val==NIREPvtkViewImage2D::RADIOLOGIC ) 01855 this->SetConventionsToRadiological(); 01856 else if( val==NIREPvtkViewImage2D::NEUROLOGIC ) 01857 this->SetConventionsToNeurological(); 01858 else 01859 vtkErrorMacro ( << "Conventions not supported."); 01860 } 01861 01862 01863 void NIREPvtkViewImage2D::SetConventionsToRadiological() 01864 { 01865 this->Conventions = RADIOLOGIC; 01866 01867 unsigned int orientation = this->GetOrientation(); 01868 this->Orientation = NIREPvtkViewImage::NB_PLAN_IDS; 01869 this->SetOrientation ( orientation ); 01870 01871 this->ResetAndRestablishZoomAndCamera(); 01872 this->Modified(); 01873 } 01874 01875 01876 void NIREPvtkViewImage2D::SetConventionsToNeurological() 01877 { 01878 this->Conventions = NEUROLOGIC; 01879 01880 unsigned int orientation = this->GetOrientation(); 01881 this->Orientation = NIREPvtkViewImage::NB_PLAN_IDS; 01882 this->SetOrientation ( orientation ); 01883 01884 this->ResetAndRestablishZoomAndCamera(); 01885 this->Modified(); 01886 } 01887 01888 01889 void NIREPvtkViewImage2D::ResetAndRestablishZoomAndCamera() 01890 { 01891 01892 if( !this->GetRenderer() ) 01893 { 01894 return; 01895 } 01896 01897 double zoom = this->GetZoom(); 01898 vtkCamera *camera = this->GetRenderer()->GetActiveCamera(); 01899 double c_position[3], focal[3]; 01900 camera->GetPosition(c_position); 01901 camera->GetFocalPoint (focal); 01902 01903 this->ResetZoom(); 01904 double focal2[3], pos2[3]; 01905 camera->GetFocalPoint (focal2); 01906 camera->GetPosition (pos2); 01907 01908 camera->SetFocalPoint (focal[0], focal[1], focal2[2]); 01909 camera->SetPosition (c_position[0], c_position[1], pos2[2]); 01910 01911 this->SetZoom ( zoom/this->GetZoom() ); 01912 01913 } 01914 01915 01916 void NIREPvtkViewImage2D::PrintSelf(ostream& os, vtkIndent indent) 01917 { 01918 this->Superclass::PrintSelf(os, indent); 01919 os << indent << "Orientation = " << this->Orientation << "\n"; 01920 double* bounds = 0; 01921 double* spacing = 0; 01922 double* origin = 0; 01923 int* extent = 0; 01924 int* wextent = 0; 01925 int* uextent = 0; 01926 01927 if( !this->GetImage() ) 01928 { 01929 return; 01930 } 01931 01932 01933 this->GetImage()->Update(); 01934 this->ImageReslice->GetOutput()->Update(); 01935 this->WindowLevel->GetOutput()->Update(); 01936 01937 this->GetImage()->GetBounds(); 01938 this->ImageReslice->GetOutput()->GetBounds(); 01939 this->WindowLevel->GetOutput()->GetBounds(); 01940 this->ImageActor->GetBounds(); 01941 01942 extent = this->GetImage()->GetExtent(); 01943 uextent = this->GetImage()->GetUpdateExtent(); 01944 wextent = this->GetImage()->GetWholeExtent(); 01945 origin = this->GetImage()->GetOrigin(); 01946 spacing = this->GetImage()->GetSpacing(); 01947 os << indent << "InputImage - "<<this->GetImage()->GetNumberOfPoints()<<" points.\n" 01948 << " extent : (" 01949 << extent[0] << "/" << extent[1] << " ; " 01950 << extent[2] << "/" << extent[3] << " ; " 01951 << extent[4] << "/" << extent[5] << ") \n" 01952 << " uextent : (" 01953 << uextent[0] << "/" << uextent[1] << " ; " 01954 << uextent[2] << "/" << uextent[3] << " ; " 01955 << uextent[4] << "/" << uextent[5] << ") \n" 01956 << " wextent : (" 01957 << wextent[0] << "/" << wextent[1] << " ; " 01958 << wextent[2] << "/" << wextent[3] << " ; " 01959 << wextent[4] << "/" << wextent[5] << ") \n" 01960 << " origin : (" 01961 << origin[0] << " , " << origin[1] << " , " << origin[2] << ")\n" 01962 << " spacing : (" 01963 << spacing[0] << " , " << spacing[1] << " , " << spacing[2] << ")\n"; 01964 01965 extent = this->ImageReslice->GetOutput()->GetExtent(); 01966 uextent = this->ImageReslice->GetOutput()->GetUpdateExtent(); 01967 wextent = this->ImageReslice->GetOutput()->GetWholeExtent(); 01968 origin = this->ImageReslice->GetOutput()->GetOrigin(); 01969 spacing = this->ImageReslice->GetOutput()->GetSpacing(); 01970 os << indent << "Resliced Image - "<<this->ImageReslice->GetOutput()->GetNumberOfPoints()<<" points.\n" 01971 << " extent : (" 01972 << extent[0] << "/" << extent[1] << " ; " 01973 << extent[2] << "/" << extent[3] << " ; " 01974 << extent[4] << "/" << extent[5] << ") \n" 01975 << " uextent : (" 01976 << uextent[0] << "/" << uextent[1] << " ; " 01977 << uextent[2] << "/" << uextent[3] << " ; " 01978 << uextent[4] << "/" << uextent[5] << ") \n" 01979 << " wextent : (" 01980 << wextent[0] << "/" << wextent[1] << " ; " 01981 << wextent[2] << "/" << wextent[3] << " ; " 01982 << wextent[4] << "/" << wextent[5] << ") \n" 01983 << " origin : (" 01984 << origin[0] << " , " << origin[1] << " , " << origin[2] << ")\n" 01985 << " spacing : (" 01986 << spacing[0] << " , " << spacing[1] << " , " << spacing[2] << ")\n"; 01987 01988 extent = this->WindowLevel->GetOutput()->GetExtent(); 01989 uextent = this->WindowLevel->GetOutput()->GetUpdateExtent(); 01990 wextent = this->WindowLevel->GetOutput()->GetWholeExtent(); 01991 origin = this->WindowLevel->GetOutput()->GetOrigin(); 01992 spacing = this->WindowLevel->GetOutput()->GetSpacing(); 01993 os << indent << "WindowLevel Image - "<<this->WindowLevel->GetOutput()->GetNumberOfPoints()<<" points.\n" 01994 << " extent : (" 01995 << extent[0] << "/" << extent[1] << " ; " 01996 << extent[2] << "/" << extent[3] << " ; " 01997 << extent[4] << "/" << extent[5] << ") \n" 01998 << " uextent : (" 01999 << uextent[0] << "/" << uextent[1] << " ; " 02000 << uextent[2] << "/" << uextent[3] << " ; " 02001 << uextent[4] << "/" << uextent[5] << ") \n" 02002 << " wextent : (" 02003 << wextent[0] << "/" << wextent[1] << " ; " 02004 << wextent[2] << "/" << wextent[3] << " ; " 02005 << wextent[4] << "/" << wextent[5] << ") \n" 02006 << " origin : (" 02007 << origin[0] << " , " << origin[1] << " , " << origin[2] << ")\n" 02008 << " spacing : (" 02009 << spacing[0] << " , " << spacing[1] << " , " << spacing[2] << ")\n"; 02010 02011 bounds = this->GetImage()->GetBounds(); 02012 os << indent << "InputImage \n" 02013 << " bounds : (" 02014 << bounds[0] << "/" << bounds[1] << " ; " 02015 << bounds[2] << "/" << bounds[3] << " ; " 02016 << bounds[4] << "/" << bounds[5] << ") \n"; 02017 bounds = this->ImageReslice->GetOutput()->GetBounds(); 02018 os << indent << "Resliced Image \n" 02019 << " bounds : (" 02020 << bounds[0] << "/" << bounds[1] << " ; " 02021 << bounds[2] << "/" << bounds[3] << " ; " 02022 << bounds[4] << "/" << bounds[5] << ") \n"; 02023 bounds = this->WindowLevel->GetOutput()->GetBounds(); 02024 os << indent << "WindowLevel Image \n" 02025 << " bounds : (" 02026 << bounds[0] << "/" << bounds[1] << " ; " 02027 << bounds[2] << "/" << bounds[3] << " ; " 02028 << bounds[4] << "/" << bounds[5] << ") \n"; 02029 bounds = this->ImageActor->GetBounds(); 02030 os << indent << "Image Actor bounds : (" 02031 << bounds[0] << "/" << bounds[1] << " ; " 02032 << bounds[2] << "/" << bounds[3] << " ; " 02033 << bounds[4] << "/" << bounds[5] << ") \n"; 02034 02035 } 02036 02037 02038 void NIREPvtkViewImage2D::SetBGImage (vtkImageData *image, int slice, vtkTransform* transform) 02039 { 02040 if (!this->GetRenderer() || !image || slice < 0) 02041 return; 02042 02043 int dim = image->GetDataDimension(); 02044 vtkImageActor* actor = vtkImageActor::New(); 02045 vtkImageMapToColors* windowLevel = vtkImageMapToColors::New(); 02046 int* w_ext = image->GetWholeExtent(); 02047 vtkLookupTable* lut = vtkLookupTable::New(); 02048 02049 02050 // vtkImageData * input = vtkImageData::New(); 02051 // case image->GetScalarTypr() == VTK_UNSIGNED_CHAR? 02052 02053 vtkLookupTable* imgLut = vtkLookupTable::SafeDownCast (this->WindowLevel->GetLookupTable()); 02054 if(imgLut) 02055 { 02056 lut->DeepCopy(imgLut); 02057 windowLevel->SetLookupTable(lut); 02058 } 02059 02060 double range[2]; 02061 image->GetScalarRange (range); 02062 if ( windowLevel->GetLookupTable() ) 02063 { 02064 windowLevel->GetLookupTable()->SetRange (range); 02065 } 02066 02067 02068 windowLevel->SetInput(image); 02069 actor->SetInput(windowLevel->GetOutput()); 02070 02071 if (dim==3) 02072 { 02073 int nbSl; 02074 switch (this->Orientation) 02075 { 02076 case NIREPvtkViewImage::AXIAL_ID: 02077 nbSl = w_ext[5] - w_ext[4] + 1; 02078 if (slice > nbSl) 02079 { 02080 std::cout<<"Error: cannot add a background image, the slice number is too high "<<std::endl; 02081 return; 02082 } 02083 else 02084 actor->SetDisplayExtent( w_ext[0], w_ext[1], w_ext[2], w_ext[3], slice, slice); 02085 break; 02086 02087 02088 case NIREPvtkViewImage::CORONAL_ID: 02089 nbSl = w_ext[3] - w_ext[2] + 1; 02090 if (slice > nbSl) 02091 { 02092 std::cout<<"Error: can't add a background image, the slice number is too high "<<std::endl; 02093 return; 02094 } 02095 else 02096 actor->SetDisplayExtent( w_ext[0], w_ext[1], slice ,slice, w_ext[4], w_ext[5]); 02097 break; 02098 02099 02100 case NIREPvtkViewImage::SAGITTAL_ID: 02101 nbSl = w_ext[1] - w_ext[0] + 1; 02102 if (slice > nbSl) 02103 { 02104 std::cout<<"Error: can't add a background image, the slice number is too high "<<std::endl; 02105 return; 02106 } 02107 else 02108 actor->SetDisplayExtent( slice, slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5]); 02109 break; 02110 } 02111 } 02112 else 02113 { 02114 slice = 0; 02115 actor->SetDisplayExtent( w_ext[0], w_ext[1], w_ext[2], w_ext[3], 0, 0); 02116 } 02117 02118 if (transform) 02119 { 02120 actor->SetUserTransform(transform); 02121 } 02122 02123 vtkTransform * transform2 = vtkTransform::New(); 02124 transform2->RotateX(180); 02125 actor->SetUserTransform(transform2); 02126 02127 actor->PickableOff(); 02128 actor->DragableOff(); 02129 02130 if (this->BGActor && this->GetRenderer()->HasViewProp(this->BGActor) ) 02131 { 02132 this->GetRenderer()->RemoveActor(BGActor); 02133 } 02134 02135 this->BGActor = actor; 02136 this->BGWindowLevel = windowLevel; 02137 this->BGImage = image; 02138 02139 if (this->ImageActor) 02140 { 02141 this->GetRenderer()->RemoveActor(ImageActor); 02142 this->GetRenderer()->AddViewProp(this->BGActor); 02143 this->GetRenderer()->AddViewProp(ImageActor); 02144 } 02145 else 02146 this->GetRenderer()->AddViewProp(this->BGActor); 02147 02148 02149 actor->Delete(); 02150 windowLevel->Delete(); 02151 lut->Delete(); 02152 transform2->Delete(); 02153 02154 } 02155 02156 02157 void NIREPvtkViewImage2D::RemoveBGImage() 02158 { 02159 02160 if (this->BGActor && this->GetRenderer()->HasViewProp(this->BGActor)) 02161 { 02162 this->GetRenderer()->RemoveActor(this->BGActor); 02163 } 02164 02165 this->BGImage = 0; 02166 this->BGWindowLevel = 0; 02167 02168 } 02169 02170 02171 void NIREPvtkViewImage2D::SetBGImageOpacity(double opacity) 02172 { 02173 if (!this->BGActor) 02174 return; 02175 this->BGActor->SetOpacity(opacity); 02176 } 02177 02178 02179 double NIREPvtkViewImage2D::GetBGImageOpacity() const 02180 { 02181 if (!this->BGActor) 02182 return -1.0; 02183 return this->BGActor->GetOpacity(); 02184 } 02185 02186 02187 void NIREPvtkViewImage2D::SetOpacity(double opacity) 02188 { 02189 this->ImageActor->SetOpacity(opacity); 02190 } 02191 02192 double NIREPvtkViewImage2D::GetOpacity() const 02193 { 02194 return this->ImageActor->GetOpacity(); 02195 } 02196 02197 02198 void NIREPvtkViewImage2D::Clear(void) 02199 { 02200 // maybe containing some bugs or missing process 02201 this->Reset(); 02202 this->FirstRender = 1; 02203 this->SetFirstImage (1); 02204 02205 this->RemoveBGImage(); 02206 02207 if (this->ImageActor && this->GetRenderer()->HasViewProp(this->ImageActor) ) 02208 { 02209 this->ImageActor->SetPosition(0.0, 0.0, 0.0); 02210 this->ImageActor->SetScale(1.0); 02211 this->ImageActor->SetOrientation( this->ImageActor->GetOrientation()[0], 02212 this->ImageActor->GetOrientation()[0], 02213 0); 02214 02215 this->ImageActor->SetUserMatrix(vtkMatrix4x4::New()); 02216 this->GetRenderer()->RemoveActor(this->ImageActor); 02217 } 02218 this->RemoveActor( this->HorizontalLineActor ); 02219 this->RemoveActor( this->VerticalLineActor ); 02220 02221 if ( this->GetImage() ) 02222 { 02223 NIREPvtkViewImage::SetImage( 0 ); 02224 } 02225 02226 int NumberOfRenderers = this->GetRenderWindow()->GetRenderers()->GetNumberOfItems(); 02227 this->GetRenderWindow()->RemoveRenderer(this->GetRenderWindow()->GetRenderers()->GetFirstRenderer()); 02228 int NumberOfRenderersTwo = this->GetRenderWindow()->GetRenderers()->GetNumberOfItems(); 02229 02230 int tempStop = 1; 02232 // useful? 02233 02234 //this->RemoveAllDataSet(); 02235 // this->ImageReslice->RemoveAllInputs(); 02236 // this->WindowLevel->RemoveAllInputs(); 02237 // this->Blender->RemoveAllInputs(); 02238 // this->MaskFilter->RemoveAllInputs(); 02239 // this->ImageActor = vtkImageActor::New(); // remove inputs? 02240 // this->BGActor = vtkImageActor::New(); 02241 // this->BGWindowLevel->RemoveAllInputs(); 02242 02243 // this->AuxInput = this->WindowLevel->GetOutput(); 02244 // this->ResliceInput = this->WindowLevel->GetOutput(); 02245 // this->RemoveAllDataSet(); 02246 // this->InternalUpdate(); 02247 }