NIREP

NIREPvtkViewImage2D.cxx

Go to the documentation of this file.
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 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines