NIREP

VectorField.cpp

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003 Program:   vtkINRIA3D
00004 Module:    $Id: VectorField.cpp,v 1.6 2011/01/25 23:48:18 hawle Exp $
00005 Language:  C++
00006 Author:    $Author: hawle $
00007 Date:      $Date: 2011/01/25 23:48:18 $
00008 Version:   $Revision: 1.6 $
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 "VectorField.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 "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 "vtkImageBlendWithMask.h"
00058 #include "vtkImageBlend.h"
00059 #include <vtkPolyDataMapper2D.h>
00060 #include <vtkActor2D.h>
00061 
00062 #include <vtkColorTransferFunction.h>
00063 #include <vtkDataArray.h>
00064 #include <vtkPointData.h>
00065 #include <vtkCellData.h>
00066 #include <vtkExtractGeometry.h>
00067 #include <vtkDataSet.h>
00068 #include <vtkUnstructuredGrid.h>
00069 #include <vtkDataSetMapper.h>
00070 #include <vtkPlane.h>
00071 #include <vtkPlaneCollection.h>
00072 #include <vtkPolyDataMapper2D.h>
00073 #include <vtkActor2D.h>
00074 #include <vtkClipDataSet.h>
00075 #include <vtkCutter.h>
00076 #include <vtkBox.h>
00077 #include <vtkPolyDataWriter.h>
00078 #include <vtkPolyDataNormals.h>
00079 #include <vtkTransform.h>
00080 #include <vtkMath.h>
00081 #include <vtkRulerWidget.h>
00082 
00083 //Jeffrey Hawley added this
00084 #include <vtkArrowSource.h>
00085 #include <vtkGlyph3D.h>
00086 #include <vtkVertex.h>
00087 #include <vtkPoints.h>
00088 #include <vtkStructuredGridReader.h>
00089 #include <vtkVoxel.h>
00090 #include <vtkCellArray.h>
00091 #include <vtkDataArray.h>
00092 #include <vtkFloatArray.h>
00093 #include <vtkDoubleArray.h>
00094 #include <vtkStructuredGrid.h>
00095 #include <vtkGlyph2D.h>
00096 #include <vtkLookupTableManager.h>
00097 //end of addition
00098 
00099 vtkCxxRevisionMacro(VectorField, "$Revision: 1.6 $");
00100 vtkStandardNewMacro(VectorField);
00101 
00102 
00103 VectorField::VectorField():NIREPvtkViewImage2D()
00104 {
00105   //Jeffrey Hawley added this
00106   m_vectorActor = vtkActor::New();
00107 //  InitializeArrays();
00108   //end of addition
00109 
00110   this->FirstRender = 1;
00111   this->ShowSliceNumber  = 1;
00112   this->InteractionStyle = SELECT_INTERACTION;
00113   this->LeftButtonInteractionStyle = SELECT_INTERACTION;
00114   this->MiddleButtonInteractionStyle = SELECT_INTERACTION;
00115   this->RightButtonInteractionStyle = SELECT_INTERACTION;
00116   this->WheelInteractionStyle = SELECT_INTERACTION;
00117   this->RulerWidgetVisibility = 0;
00118   this->Show2DAxis = 1;
00119 
00120   this->Conventions = RADIOLOGIC;
00121   
00122   this->InitialParallelScale = 1.0;
00123 
00124 
00125   this->ImageReslice     = vtkImageReslice::New();
00126   this->ImageActor       = NULL;
00127 
00128   vtkRenderer *rend = this->GetRenderer();
00129 
00130   this->WindowLevelForCorner = vtkImageMapToWindowLevelColors::New();
00131   this->WindowLevel      = vtkImageMapToColors::New();
00132   this->MaskFilter       = vtkImageBlendWithMask::New();
00133   this->Blender          = vtkImageBlend::New();
00134 
00135   this->OrientationMatrix = vtkMatrix4x4::New();
00136   this->OrientationMatrix->Identity();
00137   this->ScreenToRealWorldMatrix = vtkMatrix4x4::New();
00138   this->ScreenToRealWorldMatrix->Zero();
00139   this->ScreenToRealWorldMatrix->SetElement (2, 2, 1.0);
00140 
00141   this->BGActor          = 0;
00142   this->BGWindowLevel    = 0;
00143   this->BGImage = 0;
00144 
00145   
00146   this->HorizontalLineSource = vtkLineSource::New();
00147   this->VerticalLineSource   = vtkLineSource::New();
00148   this->HorizontalLineActor  = vtkActor::New();
00149   this->VerticalLineActor    = vtkActor::New();
00150   
00151   this->DataSetCutPlane      = vtkPlane::New();
00152   this->DataSetCutBox        = vtkBox::New();
00153   
00154 
00155   this->DataSetCutPlane->SetOrigin (0,0,0);
00156   this->DataSetCutPlane->SetNormal (0,0,1);
00157   this->DataSetCutBox->SetBounds (0,0,0,0,0,0);
00158   this->BoxThickness = 2;
00159 
00160   // set the filters properties
00161   this->Blender->SetBlendModeToNormal();
00162   //this->Blender->SetOpacity (0,0.25 ); GEC 7/10/2010 changed to 50% opacity
00163   //this->Blender->SetOpacity (1, 0.75);
00164   this->Blender->SetOpacity (0,0.5);
00165   this->Blender->SetOpacity (1,0.5);
00166  
00167   
00168   
00169   // set up the vtk pipeline  
00170   this->ImageReslice->SetOutputDimensionality(2);
00171   this->ImageReslice->InterpolateOff();
00172   this->ImageReslice->SetInputConnection( this->WindowLevel->GetOutputPort() );
00173   
00174 
00175   this->AuxInput     = this->WindowLevel->GetOutput();
00176   this->ResliceInput = this->WindowLevel->GetOutput();
00177 
00178  
00179   // Interactor Style
00180   //this->InitInteractorStyle(VectorField::SELECT_INTERACTION);
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 }
00223 
00224 
00225 VectorField::~VectorField()
00226 {
00227 }
00228 
00229 //void VectorField::InternalUpdate()
00230 //{
00231 //  this->UpdateImageActor();
00232 //  //this->UpdatePosition();
00233 //  this->InitializeImagePositionAndSize();
00234 //  
00235 //  //  this->UpdatePosition();
00236 //  
00237 //}
00238 
00239 
00245 //void VectorField::Initialize()
00246 //{
00247 //  this->Superclass::Initialize();
00248 //
00249 //  if (this->GetRenderer())
00250 //  {
00251 //    this->GetRenderer()->TwoSidedLightingOff();
00252 //  }
00253 //  
00254 //
00255 //}
00256 
00257 
00258 void VectorField::UpdateImageActor()
00259 {
00260   if( !this->GetImage()  )
00261   {
00262     return;
00263   }
00264   //vtkPolyData *pd = vtkPolyData::New();
00265   //int * dimensions = this->ImageReslice->GetOutput()->GetDimensions();
00266   //this->ImageReslice->GetOutput()->SetScalarTypeToDouble();
00267   //double *scalarPointer = (double*)this->ImageReslice->GetOutput()->GetScalarPointer();
00268   //vtkPoints *points = vtkPoints::New();
00269   //for(int i=0; i<dimensions[0]*dimensions[1]*dimensions[2]; i=i+3) {
00270   //    points->InsertNextPoint(scalarPointer[i],scalarPointer[i+1],scalarPointer[i+2]);
00271   //}
00272 
00273   //pd->SetPoints(points);
00274   //
00275   //vtkArrowSource* as = vtkArrowSource::New();
00276   //vtkGlyph3D* gl = vtkGlyph3D::New();
00277   //gl->SetInput(pd);
00278   //gl->SetSource(as->GetOutput());
00279   //gl->SetScaleModeToScaleByVector();
00280   //gl->SetScaleFactor(0.1);
00281   //vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
00282   //mapper->SetInputConnection(gl->GetOutputPort());
00283   //    
00284   //m_vectorActor->SetMapper(mapper);
00285   this->FirstRender = 1;
00286 }
00287 
00288 
00289 
00290 //Changes:
00291 //-Will need to do two ImagesReslices
00292 void VectorField::UpdatePosition ()
00293 {
00294   if( !this->GetImage() )
00295   {
00296     return;
00297   }
00298   
00299   double x=0;
00300   double y=0;
00301   double max_x=0;
00302   double max_y=0;
00303   double min_x=0;
00304   double min_y=0;
00305   double pos[4];
00306 
00307   this->GetCurrentPoint(pos);
00308   pos[3] = 0.0;
00309 
00310   double* spacing = this->GetImage()->GetSpacing();
00311   double* origin  = this->GetImage()->GetOrigin();
00312 
00313   // check if pos lies inside image bounds
00314   //if( pos[0]<imBounds[0] || pos[0]>imBounds[1] ||
00315   //    pos[1]<imBounds[2] || pos[1]>imBounds[3] ||
00316   //    pos[2]<imBounds[4] || pos[2]>imBounds[5])
00317   //{
00318   //  // we are outside image bounds
00319   //  return;
00320   //}
00321 
00322 // round to the nearest integer slice
00323   pos[0] = vtkMath::Round ((pos[0]-origin[0])/spacing[0] )*spacing[0]+origin[0];
00324   pos[1] = vtkMath::Round ((pos[1]-origin[1])/spacing[1] )*spacing[1]+origin[1];
00325   pos[2] = vtkMath::Round ((pos[2]-origin[2])/spacing[2] )*spacing[2]+origin[2];
00326 
00327   /*
00328     double *bounds = this->ImageActor->GetBounds();
00329     min_x = bounds[0];
00330     max_x = bounds[1];
00331     min_y = bounds[2];
00332     max_y = bounds[3];
00333   */
00334 
00335   double min_bounds[4] = { this->GetWholeMinPosition(0),
00336                            this->GetWholeMinPosition(1),
00337                            this->GetWholeMinPosition(2),
00338                            0.0 };
00339 
00340   double max_bounds[4] = { this->GetWholeMaxPosition(0),
00341                            this->GetWholeMaxPosition(1),
00342                            this->GetWholeMaxPosition(2),
00343                            0.0 };
00344   
00345 
00346   // new efficient way to get the reslice origin and the axis coordinates.
00347   double reslice[4], pos2[4];
00348   this->ScreenToRealWorldMatrix->MultiplyPoint (pos, reslice);
00349   this->ImageReslice->SetResliceAxesOrigin(reslice[0], reslice[1], reslice[2]);
00350 
00351 
00352   vtkMatrix4x4* mat = vtkMatrix4x4::New();
00353   vtkMatrix4x4::Transpose (this->OrientationMatrix, mat);
00354   mat->MultiplyPoint (pos, pos2);
00355   mat->MultiplyPoint (min_bounds, min_bounds);
00356   mat->MultiplyPoint (max_bounds, max_bounds);
00357   mat->Delete();
00358 
00359   x = pos2[0];
00360   y = pos2[1];
00361 
00362   max_x = max_bounds[0];
00363   max_y = max_bounds[1];
00364   
00365   min_x = min_bounds[0];
00366   min_y = min_bounds[1];
00367 
00368   this->HorizontalLineSource->SetPoint1(min_x, y, 0.001);
00369   this->HorizontalLineSource->SetPoint2(max_x, y, 0.001);   
00370   this->VerticalLineSource->SetPoint1(x, min_y, 0.001);   
00371   this->VerticalLineSource->SetPoint2(x, max_y, 0.001);
00372 
00373   this->ImageReslice->Update(); // needed to update input Extent
00374  
00375   int imCoor[3];
00376   this->GetCurrentVoxelCoordinates(imCoor);
00377   int dims[3];
00378   this->GetImage()->GetDimensions (dims);
00379       
00380   std::ostringstream os2;
00381   std::ostringstream os;
00382   //os << "Slice: ";
00383 
00384   os2 << "Zoom: " << this->GetZoom()*100.0 << " \%\n";
00385     
00386   switch( this->Orientation )
00387   {
00388       case NIREPvtkViewImage::AXIAL_ID :
00389         os << "Image size: " << dims[0] << " x " << dims[1] << "\n";
00390         os << "Voxel size: " << spacing[0] << " x " << spacing[1] << "\n";
00391         //os << imCoor[2] << " / " << dims[2]-1 << std::endl;
00392         os << "X: " << imCoor[0] << " px Y: " << imCoor[1] << " px Value: "
00393            << this->GetCurrentPointDoubleValue() << std::endl;
00394         os << "X: " << pos[0] << " mm Y: " << pos[1] << " mm\n";
00395         if ( this->ShowSliceNumber )
00396           os2 << "Slice: " << imCoor[2] << " / " << dims[2]-1 << std::endl;
00397         os2 << "Location: " << pos[2] << " mm";
00398         break;
00399           
00400         
00401       case NIREPvtkViewImage::CORONAL_ID :
00402         os << "Image size: " << dims[0] << " x " << dims[2] << "\n";
00403         os << "Voxel size: " << spacing[0] << " x " << spacing[2] << "\n";
00404         //os << imCoor[1] << " / " << dims[1]-1 << std::endl;
00405         os << "X: " << imCoor[0] << " px Z: " << imCoor[2] << " px Value: "
00406            << this->GetCurrentPointDoubleValue() << std::endl;
00407         os << "X: " << pos[0] << " mm Z: " << pos[2] << " mm\n";
00408         if ( this->ShowSliceNumber )
00409           os2 << "Slice: " << imCoor[1] << " / " << dims[1]-1 << std::endl;
00410         os2 << "Location: " << pos[1] << " mm";
00411         break;
00412         
00413         
00414       case NIREPvtkViewImage::SAGITTAL_ID :
00415         os << "Image size: " << dims[1] << " x " << dims[2] << "\n";
00416         os << "Voxel size: " << spacing[1] << " x " << spacing[2] << "\n";
00417         //os << imCoor[0] << " / " << dims[0]-1 << std::endl;
00418         os << "Y: " << imCoor[1] << " px Z: " << imCoor[2] << " px Value: "
00419            << this->GetCurrentPointDoubleValue() << std::endl;
00420         os << "Y: " << pos[1] << " mm Z: " << pos[2] << " mm\n";
00421         if ( this->ShowSliceNumber )
00422           os2 << "Slice: " << imCoor[0] << " / " << dims[0]-1 << std::endl;
00423         os2 << "Location: " << pos[0] << " mm";
00424         break;
00425   }
00426   os << "<window_level>";
00427   
00428   this->SetUpLeftAnnotation( os.str().c_str() );
00429   this->SetDownLeftAnnotation( os2.str().c_str() );
00430   //  }
00431   //  else
00432   //    this->SetUpRightAnnotation("");
00433   
00434   unsigned int direction = this->GetOrthogonalAxis (this->GetOrientation());
00435   this->DataSetCutPlane->SetOrigin (reslice[0], reslice[1], reslice[2]);
00436   
00437   switch(direction)
00438   {
00439       case X_ID :
00440         //this->DataSetCutPlane->SetNormal (1,0,0);
00441         this->DataSetCutBox->SetBounds (this->DataSetCutPlane->GetOrigin()[0],this->DataSetCutPlane->GetOrigin()[0]+this->BoxThickness,
00442                                         this->GetWholeMinPosition(1),this->GetWholeMaxPosition(1),
00443                                         this->GetWholeMinPosition(2),this->GetWholeMaxPosition(2));
00444 
00445         break;
00446       case Y_ID :
00447         //this->DataSetCutPlane->SetNormal (0,1,0);
00448         this->DataSetCutBox->SetBounds (this->GetWholeMinPosition(0),this->GetWholeMaxPosition(0),
00449                                         this->DataSetCutPlane->GetOrigin()[1],this->DataSetCutPlane->GetOrigin()[1]+this->BoxThickness,
00450                                         this->GetWholeMinPosition(2),this->GetWholeMaxPosition(2));
00451         break;
00452       case Z_ID :
00453         //this->DataSetCutPlane->SetNormal (0,0,1);
00454         this->DataSetCutBox->SetBounds (this->GetWholeMinPosition(0),this->GetWholeMaxPosition(0),
00455                                         this->GetWholeMinPosition(1),this->GetWholeMaxPosition(1),
00456                                         this->DataSetCutPlane->GetOrigin()[2],this->DataSetCutPlane->GetOrigin()[2]+this->BoxThickness);
00457         break;
00458   }
00459 
00460 
00461   if( this->DataSetList.size() )
00462   {
00463 
00464     this->ResetAndRestablishZoomAndCamera();
00465 
00466     /*
00467       We need to correct for the origin of the actor. Indeed, the ImageActor
00468       has always position 0 in Z in axial view, in X in sagittal view and
00469       in Y in coronal view. The projected dataset have an origin that depends
00470       on the required slice and can be negative. In that case, the projected
00471       data are behind the image actor and thus not visible. Here, we correct
00472       this by translating the actor so that it becomes visible.
00473      */
00474     for( unsigned int i=0; i<this->DataSetActorList.size(); i++)
00475     {
00476       double Pos[3];
00477       this->DataSetActorList[i]->GetPosition (Pos);
00478 
00479       switch(direction)
00480       {
00481           case X_ID :
00482             Pos[0] = -1.0*reslice[0] + 1.0;
00483             break;
00484 
00485           case Y_ID:
00486             Pos[1] = -1.0*reslice[1] + 1.0;
00487             break;
00488 
00489           case Z_ID:
00490             Pos[2] = -1.0*reslice[2] + 1.0;
00491             break;
00492       }
00493 
00494       this->DataSetActorList[i]->SetPosition (Pos);
00495     }
00496 
00497   }
00498 
00499   this->Modified();
00500 }
00501 
00502 
00503 
00504 void VectorField::SetWindow (double w)
00505 {
00506 
00507   if( w<0.0 )
00508   {
00509     w = 0.0;
00510   }
00511 
00512   double shiftScaleWindow = this->GetShift() + w*this->GetScale();
00513   
00514   NIREPvtkViewImage::SetWindow ( shiftScaleWindow );
00515   this->WindowLevelForCorner->SetWindow( shiftScaleWindow );
00516   
00517   double v_min = this->GetLevel() - 0.5*this->GetWindow();
00518   double v_max = this->GetLevel() + 0.5*this->GetWindow();
00519 
00520   if( this->GetLookupTable() && this->WindowLevel->GetLookupTable())
00521   {
00522   
00523     this->GetLookupTable()->SetRange ( (v_min-0.5*this->GetShift())/this->GetScale(),
00524                                        (v_max-1.5*this->GetShift())/this->GetScale());
00525     this->WindowLevel->GetLookupTable()->SetRange (v_min, v_max);
00526   }
00527 
00528   if(this->BGWindowLevel && this->BGWindowLevel->GetLookupTable())
00529     this->BGWindowLevel->GetLookupTable()->SetRange( v_min, v_max);
00530 }
00531 
00532 
00533 
00534 void VectorField::SetLevel (double l)
00535 {
00536 
00537   double shiftScaleLevel = this->GetShift() + l*this->GetScale();
00538 
00539   NIREPvtkViewImage::SetLevel ( shiftScaleLevel );
00540   this->WindowLevelForCorner->SetLevel( shiftScaleLevel );
00541     
00542   double v_min = this->GetLevel() - 0.5*this->GetWindow();
00543   double v_max = this->GetLevel() + 0.5*this->GetWindow();
00544   
00545   if( this->GetLookupTable() )
00546   {
00547     this->GetLookupTable()->SetRange ( (v_min-0.5*this->GetShift())/this->GetScale(),
00548                                        (v_max-1.5*this->GetShift())/this->GetScale());
00549     this->WindowLevel->GetLookupTable()->SetRange (v_min, v_max);
00550   }
00551 }
00552 
00553 
00554 
00555 //Changes:
00556 //-Either need to create another SetImage, or have this SetImage place the images into an array
00557 //-Look into RegisterImage, I might have to do something else.
00558 //-I think I should create another SetImage
00559 void VectorField::SetImage(vtkImageData* image)
00560 {
00561   //vtkStructuredGridReader *reader = vtkStructuredGridReader::New();
00562   //reader->SetFileName("subset.vtk");
00563   //reader->Update();
00564 
00565   //vtkArrowSource* as = vtkArrowSource::New();
00566   //vtkGlyph3D* gl = vtkGlyph3D::New();
00567   //gl->SetInputConnection(reader->GetOutputPort());
00568   //gl->SetSource(as->GetOutput());
00569   //gl->SetScaleModeToScaleByVector();
00570   //gl->SetScaleFactor(0.1);
00571 
00572   //vtkLookupTable* lu = vtkLookupTable::New();
00573   //lu->SetNumberOfTableValues(256);
00574   //lu->SetHueRange(0.6667, 0);
00575   //lu->SetTableRange(0, 5);
00576   //lu->SetVectorMode(vtkScalarsToColors::MAGNITUDE);
00577   //lu->Build();
00578 
00579   //vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
00580   //mapper->SetInputConnection(gl->GetOutputPort());
00581   //mapper->SetLookupTable(lu);
00582   //gl->Update();
00583   //m_vectorActor->SetMapper(mapper);
00584 
00585   //this->AddActor(m_vectorActor);
00586 
00587   //NIREPvtkViewImage::SetImage( image );
00588   if(!image)
00589   {
00590     return;
00591   }
00592 
00593   int* extent = image->GetExtent();
00594   if( extent[1]<extent[0] || extent[3]<extent[2] || extent[5]<extent[4] )
00595   {
00596     vtkErrorMacro ( << "Image extent is not valid: " << extent[0] << " "
00597                     << extent[1] << " "
00598                     << extent[2] << " "
00599                     << extent[3] << " "
00600                     << extent[4] << " "
00601                     << extent[5]);
00602     return;
00603   }
00604 
00605   
00606 
00607   NIREPvtkViewImage::SetImage( image );
00608 
00609   // check if there is a mask image. If yes, then we check
00610   // if the new image size and spacing agrees with the mask image.
00611   // If not, we remove the mask image
00612   if( this->GetMaskImage() )
00613   {
00614     int*    dims        = image->GetDimensions();
00615     double* spacing     = image->GetSpacing();
00616     int*    maskDims    = this->GetMaskImage()->GetDimensions();
00617     double* maskSpacing = this->GetMaskImage()->GetSpacing();
00618 
00619     if( dims[0]!=maskDims[0] || dims[1]!=maskDims[1] || dims[2]!=maskDims[2] ||
00620         spacing[0]!=maskSpacing[0] || spacing[1]!=maskSpacing[1] || spacing[2]!=maskSpacing[2] )
00621     {
00622       this->RemoveMaskImage();
00623     }
00624   }
00625 
00626   // should check also the overlapping image
00627   int type = image->GetScalarType();
00628   int components = image->GetNumberOfScalarComponents();
00629   if( image->GetScalarType() == VTK_UNSIGNED_CHAR  && (image->GetNumberOfScalarComponents()==3 || image->GetNumberOfScalarComponents()==4) )
00630   {
00631     this->AuxInput = image;
00632   }
00633   else if(image->GetScalarType() == VTK_FLOAT && image->GetNumberOfScalarComponents()==3) {
00634     this->AuxInput = image;
00635   }
00636   else
00637   {
00638     this->AuxInput = this->WindowLevel->GetOutput();
00639 
00640     this->WindowLevel->SetInput (image);
00641     double range[2];
00642     image->GetScalarRange (range);
00643     if ( this->WindowLevel->GetLookupTable() )
00644     {
00645       this->WindowLevel->GetLookupTable()->SetRange (range);
00646     }
00647   }
00648 
00649 
00650   if( this->GetOverlappingImage() )
00651   {
00652     this->Blender->SetInput (0, this->AuxInput );
00653   }
00654   else
00655   {
00656     if( this->GetMaskImage() )
00657     {
00658       this->MaskFilter->SetImageInput ( this->AuxInput );
00659     }
00660     else
00661     {
00662       this->ImageReslice->SetInput ( this->AuxInput );
00663       this->ResliceInput = this->AuxInput;
00664     }
00665   }
00666 
00667   //this->ImageActor->SetInput( this->ImageReslice->GetOutput() );
00668 
00669   if(this->GetImage())
00670   {
00671       this->AddActor(this->HorizontalLineActor);
00672       this->AddActor(this->VerticalLineActor);
00673 
00674       //this->AddActor(this->ImageActor);
00675       vtkStructuredGrid *pd = vtkStructuredGrid::New();
00676       //vtkPolyData *pd = vtkPolyData::New();
00677       this->ImageReslice->Update();
00678       int * dimensions = this->ImageReslice->GetOutput()->GetDimensions();
00679 
00680       int numberOfTuples = dimensions[0]*dimensions[1]*dimensions[2] /3;
00681       this->ImageReslice->GetOutput()->SetScalarTypeToDouble();
00682       double *scalarPointer = (double*)this->ImageReslice->GetOutput()->GetScalarPointer();
00683       vtkPoints *vtkpoints = vtkPoints::New();
00684       vtkpoints->SetNumberOfPoints(numberOfTuples);
00685       //vtkpoints->SetNumberOfPoints(7);
00686       vtkCellArray *vertices = vtkCellArray::New();
00687       vtkIdType pid;
00688 
00689 
00690       vtkDoubleArray *dataArray = vtkDoubleArray::New();
00691       dataArray->SetNumberOfComponents(3);
00692       dataArray->Allocate(numberOfTuples);
00693       dataArray->SetName("Momentum");
00694 
00695       vtkDoubleArray *dataArrayTwo = vtkDoubleArray::New();
00696       dataArrayTwo->SetNumberOfComponents(1);
00697       dataArrayTwo->Allocate(numberOfTuples);
00698       dataArrayTwo->SetName("default");
00699 
00700       vtkDoubleArray *dataArrayThree = vtkDoubleArray::New();
00701       dataArrayThree->SetNumberOfComponents(3);
00702       dataArrayThree->Allocate(numberOfTuples);
00703 
00704       
00705       int numberOfComponents = 3;
00706       double *ptrThree = dataArrayThree->WritePointer(0,numberOfTuples*numberOfComponents);
00707 
00708       int dim0,dim1,dim2;
00709       dim0=dim1=dim2=0;
00710 
00711 
00712 
00713       for (int i=0; i<numberOfTuples; i = i++) {
00714         for (int j=0; j<numberOfComponents; j++) {
00715           dim0+=50;
00716           if(dim0 > dimensions[0]*50) {
00717             dim0 = 0;
00718             dim1+=50;
00719           }
00720           if(dim1 >dimensions[1]*50) {
00721             dim1 = 0;
00722             dim2+=50;
00723           }
00724           if(dim2 > dimensions[2]*50) {
00725             dim2 = 0;
00726           }
00727           if(j == 0) {
00728             *ptrThree = dim0;
00729           }
00730           else if(j == 1) {
00731             *ptrThree = dim1;
00732           }
00733           else {
00734             *ptrThree = dim2;
00735           }
00736             ptrThree++;
00737         }
00738       }
00739 
00740 
00741       vtkpoints->SetData(dataArrayThree);
00742 
00743       
00744       numberOfComponents = 3;
00745       double *ptr = dataArray->WritePointer(0,numberOfTuples*numberOfComponents);
00746       for (int i=0; i<numberOfTuples; i = i++) {
00747         for (int j=0; j<numberOfComponents; j++) {
00748           *ptr = scalarPointer[(i*numberOfComponents)+j];
00749           ptr++;
00750         }
00751       }
00752 
00753       numberOfComponents = 1;
00754       double *ptrTwo = dataArrayTwo->WritePointer(0,numberOfTuples*numberOfComponents);
00755       for (int i=0; i<numberOfTuples; i = i++) {
00756         for (int j=0; j<numberOfComponents; j++) {
00757           //*ptrTwo = scalarPointer[(i*numberOfComponents)+j];
00758           //*ptrTwo = cellScalars[(i*numberOfComponents)+j];
00759           *ptrTwo = 1;
00760           ptrTwo++;
00761         }
00762       }
00763 
00764       pd->SetPoints(vtkpoints);
00765       //pd->InsertNextCell(vertex->GetCellType(),vertex->GetPointIds());
00766       vtkDataSetAttributes *a = pd->GetPointData();
00767       a->SetVectors(dataArray);
00768       vtkDataSetAttributes *a2=pd->GetCellData();
00769       a2->SetScalars(dataArrayTwo);
00770       //pd->SetVerts(vertices);
00771   
00772       vtkArrowSource* as = vtkArrowSource::New();
00773       //vtkGlyph3D* gl = vtkGlyph3D::New();
00774       vtkGlyph2D* gl = vtkGlyph2D::New();
00775       gl->SetInput(pd);
00776       gl->SetSource(as->GetOutput());
00777       gl->SetScaleModeToScaleByVector();
00778       //gl->SetColorModeToColorByVector();
00779       gl->SetScaleFactor(0.1);
00780 
00781       gl->Update();
00782 
00783       //double range[] = {0,0};
00784 
00785       //gl->GetOutput()->GetPointData()->GetScalars()->GetRange(range,2);
00786 
00787       vtkLookupTable* lu = vtkLookupTable::New();
00788       lu->SetNumberOfTableValues(256);
00789       lu->SetHueRange(0.6667, 0);
00790       //lu->SetTableRange(range);
00791       lu->SetVectorMode(vtkScalarsToColors::COMPONENT);
00792       lu->Build();
00793       this->GetWindowLevel()->SetLookupTable(lu);
00794 
00795       //vtkLookupTable *temp = vtkLookupTableManager::GetLookupTable(2);
00796       //temp->SetVectorModeToMagnitude();
00797       //temp->SetRange(range);
00798       //temp->Build();
00799       //this->SetLookupTable(temp);
00800 
00801       vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
00802       mapper->SetInputConnection(gl->GetOutputPort());
00803       mapper->SetLookupTable(lu);
00804       //mapper->SetLookupTable(temp);
00805       //mapper->SelectColorArray("Momentum");
00806       //mapper->SetUseLookupTableScalarRange(1);
00807       mapper->SetScalarMode(VTK_SCALAR_MODE_USE_POINT_FIELD_DATA);
00808       gl->Update();
00809       m_vectorActor->SetMapper(mapper);
00810 
00811       this->AddActor(m_vectorActor);
00812 
00813       // Save the camera focal and position, and zoom, before calling InternalUpdate()
00814       double focal[3], pos[3], zoom;
00815       this->GetCameraFocalAndPosition (focal, pos);
00816       zoom = this->GetZoom();
00817       
00818 
00819       this->SetupAnnotations();
00820       this->InternalUpdate();
00821 
00822       
00823       // Check that the current displayed point lies within the bounds of the image. If not,
00824       // we camp it to the nearest acceptable position.
00825       double *wextent = image->GetBounds();
00826       double position[3];
00827       this->GetCurrentPoint ( position );
00828       position[0]<wextent[0]?position[0]=wextent[0]:position[0];
00829       position[0]>wextent[1]?position[0]=wextent[1]:position[0];
00830       position[1]<wextent[2]?position[1]=wextent[2]:position[1];
00831       position[1]>wextent[3]?position[1]=wextent[3]:position[1];
00832       position[2]<wextent[4]?position[2]=wextent[4]:position[2];
00833       position[2]>wextent[5]?position[2]=wextent[5]:position[2];
00834       this->SetCurrentPoint ( position );
00835 
00836 
00837       // restore the zoom and focal in case this is not the first time we render the image.
00838       if( !this->GetFirstImage() )
00839       {
00840         this->SetZoom ( zoom );
00841         this->SetCameraFocalAndPosition (focal, pos);
00842         this->SetFirstImage (0);
00843       }
00844 
00845       if( this->RulerWidgetVisibility )
00846         this->RulerWidget->On();
00847 
00848   }
00849 }
00850 
00851 void VectorField::SetLookupTable (vtkScalarsToColors* lut)
00852 {
00853     
00854   if( !lut )
00855   {
00856     return;
00857   }
00858     
00859   NIREPvtkViewImage::SetLookupTable (lut);
00860 
00861   double v_min = this->GetLevel() - 0.5*this->GetWindow();
00862   double v_max = this->GetLevel() + 0.5*this->GetWindow();
00863 
00869   lut->SetRange ( (v_min-0.5*this->GetShift())/this->GetScale(),
00870                   (v_max-1.5*this->GetShift())/this->GetScale() );
00871 
00872   
00873   vtkLookupTable* realLut = vtkLookupTable::SafeDownCast (lut);
00874 
00875   if( !realLut )
00876   {
00877     std::cerr << "Error: Cannot cast vtkScalarsToColors to vtkLookupTable." << std::endl;
00878     return;
00879   }
00880   
00885   vtkLookupTable* newLut = vtkLookupTable::New();
00886   newLut->DeepCopy (realLut);
00887   newLut->SetRange (v_min, v_max);
00888   this->WindowLevel->SetLookupTable (newLut);
00889   newLut->Delete();
00890   
00891 }
00892 
00893 
00894 void VectorField::SetOrientation(unsigned int p_orientation)
00895 {
00896   if( (p_orientation > vtkViewImage::NB_PLAN_IDS - 1) || (this->Orientation == p_orientation) )
00897   {
00898     return;
00899   }
00900 
00901   this->Orientation = p_orientation;
00902 
00903   
00904   // setup the OrientationMatrix and the ScreenToRealWorldMatrix. Then, we have no
00905   // need to check the view's orientation to determine what slice to display: a
00906   // simple matrix multiplication will tell it for us.
00907   this->OrientationMatrix->Zero();
00908   this->ScreenToRealWorldMatrix->Zero();
00909 
00910   
00911   if( this->Orientation == vtkViewImage::SAGITTAL_ID )
00912   {
00913     this->ImageReslice->SetResliceAxesDirectionCosines( 0, -1, 0,
00914                                                         0, 0, 1,
00915                                                         1, 0, 0);
00916     this->OrientationMatrix->SetElement (0, 2, 0.0);
00917     this->OrientationMatrix->SetElement (1, 0, -1.0);
00918     this->OrientationMatrix->SetElement (2, 1, 1.0);
00919 
00920     this->ScreenToRealWorldMatrix->SetElement (0, 0, 1.0);
00921   }
00922 
00923   
00924   if( this->Orientation == vtkViewImage::CORONAL_ID )
00925   {
00926     if( this->Conventions == RADIOLOGIC )
00927     {
00928       this->OrientationMatrix->SetElement(0, 0, 1.0);
00929       this->ImageReslice->SetResliceAxesDirectionCosines(1,  0, 0,
00930                                                          0,  0, 1,
00931                                                          0,  1, 0); 
00932     }
00933     else
00934     {  
00935       this->OrientationMatrix->SetElement(0, 0, -1.0);
00936       this->ImageReslice->SetResliceAxesDirectionCosines(-1,  0, 0,
00937                                                          0,  0, 1,
00938                                                          0,  1, 0); 
00939     }
00940     
00941     this->OrientationMatrix->SetElement(2, 1, 1.0);
00942     this->ScreenToRealWorldMatrix->SetElement (1, 1, 1.0);
00943   }
00944 
00945   
00946   if( this->Orientation == vtkViewImage::AXIAL_ID )
00947   {
00948 
00949     
00950     if( this->Conventions == RADIOLOGIC )
00951     {
00952       this->OrientationMatrix->SetElement(0, 0, 1.0 );
00953       this->ImageReslice->SetResliceAxesDirectionCosines(1, 0, 0,
00954                                                          0, 1, 0,
00955                                                          0, 0, 1);
00956     }
00957     else
00958     {  
00959       this->OrientationMatrix->SetElement(0, 0, -1.0 );
00960       this->ImageReslice->SetResliceAxesDirectionCosines(-1, 0, 0,
00961                                                          0, 1, 0,
00962                                                          0, 0, 1);
00963     }
00964 
00965     this->OrientationMatrix->SetElement(1, 1, 1.0 );
00966     this->ScreenToRealWorldMatrix->SetElement (2, 2, 1.0);
00967   }
00968 
00969   unsigned int direction = this->GetOrthogonalAxis (this->GetOrientation());
00970   switch(direction)
00971   {
00972       case X_ID :
00973         this->DataSetCutPlane->SetNormal (1,0,0);
00974         break;
00975       case Y_ID :
00976         this->DataSetCutPlane->SetNormal (0,1,0);
00977         break;
00978       case Z_ID :
00979         this->DataSetCutPlane->SetNormal (0,0,1);
00980         break;
00981   }
00982 
00983   //this->ImageReslice->Modified();
00984 
00985   this->UpdateImageActor(); // make sure update extent are up to date
00986   this->UpdatePosition(); // make sure reslicer origin are ok
00987   this->InitializeImagePositionAndSize(); // reset and center the view
00988   this->SetupAnnotations(); // make sure annotations are ok
00989   
00990   this->Modified();
00991   
00992 }
00993 
00994 
00995 
00996 vtkActor* VectorField::AddDataSet (vtkDataSet* dataset,  vtkProperty* property)
00997 {
00998 
00999   bool doit = true;
01000 
01001   if (!dataset)
01002     doit = false;
01003   
01004   if( this->HasDataSet (dataset) )
01005   {
01006     doit = false;
01007   }
01008   vtkImageData* imagedata = NULL;
01009   imagedata = vtkImageData::SafeDownCast(dataset);
01010   
01011   if (imagedata)
01012   {
01013     this->SetImage(imagedata);
01014   }
01015   else
01016   {
01017     
01018     if ( !this->GetImage() )
01019     {
01020       doit = false;
01021     }
01022     // don't constrain the memory of input datasets anymore.
01033     if (doit)
01034     {
01035       
01036       vtkMatrix4x4* matrix = vtkMatrix4x4::New();
01037       for (unsigned int i=0; i<3; i++)
01038       {
01039         for (unsigned int j=0; j<3; j++)
01040         {
01041           matrix->SetElement(i,j,this->ImageReslice->GetResliceAxes()->GetElement(j,i));
01042         }
01043         matrix->SetElement(i,3,0);
01044       }
01045       matrix->SetElement(3,3,1);
01046       
01047       vtkCutter* cutter = vtkCutter::New();
01048       cutter->SetCutFunction (this->DataSetCutPlane);
01049 
01050       // Very strangely in some cases (ex : landmarks)
01051       // the cutter increments the RefCount of the input dataset by 2
01052       // making some memory leek...
01053       // I could not manage to know what is wrong here
01054       
01055       cutter->SetInput (dataset);
01056       cutter->Update();
01057       
01058       if (!cutter->GetOutput())
01059       {
01060         vtkWarningMacro(<< "Unable to cut this dataset...");
01061         matrix->Delete();
01062         cutter->Delete();
01063         return NULL;
01064       }
01065       
01066       
01067       vtkPolyDataMapper* mapper = vtkPolyDataMapper::New();
01068       mapper->SetInput (cutter->GetOutput());
01069       
01070       vtkActor* actor = vtkActor::New();
01071       actor->SetUserMatrix (matrix);
01072       actor->SetMapper (mapper);
01073       if (property)
01074       {
01075         actor->SetProperty (property);
01076       }
01077 
01078       actor->PickableOff();
01079       
01080       this->AddActor (actor);
01081       this->DataSetList.push_back (dataset);
01082       this->DataSetActorList.push_back (actor);
01083 
01084       this->ResetAndRestablishZoomAndCamera();
01085 
01086       actor->Delete();
01087       mapper->Delete();
01088       matrix->Delete();
01089       cutter->Delete();
01090     }
01091   }
01092 
01093   
01094   return this->GetDataSetActor(dataset);
01095   
01096 }
01097 
01098 
01104 vtkActor* VectorField::SyncAddPolyData (vtkPolyData* polydata,  vtkProperty* property, double thickness)
01105 {
01106 
01107   if( this->IsLocked() )
01108   {
01109     return NULL;
01110   }
01111   
01112 
01113   vtkActor* actor = this->AddPolyData (polydata, property, thickness);
01114   
01115   this->Lock();
01116   for( unsigned int i=0; i<this->Children.size(); i++)
01117   {
01118 //     VectorField* view = dynamic_cast<VectorField*> (this->Children[i]);
01119     VectorField* view = VectorField::SafeDownCast (this->Children[i]);
01120     if( view )
01121     {
01122       view->SyncAddPolyData (polydata, property, thickness);
01123     }
01124   }
01125   this->UnLock();
01126 
01127   return actor;
01128   
01129   
01130 }
01131 
01132 
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines