Slicer 4.2
Slicer is a multi-platform, free and open source software package for visualization and medical image computing
vtkSlicerFixedPointVolumeRayCastMapper.h
Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Visualization Toolkit
00004   Module:    $RCSfile: vtkSlicerFixedPointVolumeRayCastMapper.h,v $
00005 
00006   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00007   All rights reserved.
00008   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
00009 
00010      This software is distributed WITHOUT ANY WARRANTY; without even
00011      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00012      PURPOSE.  See the above copyright notice for more information.
00013 
00014 =========================================================================*/
00015 // .NAME vtkSlicerFixedPointVolumeRayCastMapper - A fixed point mapper for volumes
00016 // .SECTION Description
00017 // This is a software ray caster for rendering volumes in vtkImageData.
00018 // It works with all input data types and up to four components. It performs
00019 // composite or MIP rendering, and can be intermixed with geometric data.
00020 // Space leaping is used to speed up the rendering process. In addition,
00021 // calculation are performed in 15 bit fixed point precision. This mapper
00022 // is threaded, and will interleave scan lines across processors.
00023 //
00024 // This mapper is a good replacement for vtkVolumeRayCastMapper EXCEPT:
00025 //   - it does not do isosurface ray casting
00026 //   - it does only interpolate before classify compositing
00027 //   - it does only maximum scalar value MIP
00028 //
00029 // The vtkVolumeRayCastMapper CANNOT be used in these instances when a
00030 // vtkSlicerFixedPointVolumeRayCastMapper can be used:
00031 //   - if the data is not unsigned char or unsigned short
00032 //   - if the data has more than one component
00033 //
00034 // This mapper handles all data type from unsigned char through double.
00035 // However, some of the internal calcultions are performed in float and
00036 // therefore even the full float range may cause problems for this mapper
00037 // (both in scalar data values and in spacing between samples).
00038 //
00039 // Space leaping is performed by creating a sub-sampled volume. 4x4x4
00040 // cells in the original volume are represented by a min, max, and
00041 // combined gradient and flag value. The min max volume has three
00042 // unsigned shorts per 4x4x4 group of cells from the original volume -
00043 // one reprenting the minumum scalar index (the scalar value adjusted
00044 // to fit in the 15 bit range), the maximum scalar index, and a
00045 // third unsigned short which is both the maximum gradient opacity in
00046 // the neighborhood (an unsigned char) and the flag that is filled
00047 // in for the current lookup tables to indicate whether this region
00048 // can be skipped.
00049 
00050 // .SECTION see also
00051 // vtkVolumeMapper
00052 
00053 #ifndef __vtkSlicerFixedPointVolumeRayCastMapper_h
00054 #define __vtkSlicerFixedPointVolumeRayCastMapper_h
00055 
00056 #include "vtkVolumeMapper.h"
00057 #include "VolumeRenderingReplacementsExport.h"
00058 
00059 
00060 #define VTKKW_FP_SHIFT       15
00061 #define VTKKW_FPMM_SHIFT     17
00062 #define VTKKW_FP_MASK        0x7fff
00063 #define VTKKW_FP_SCALE       32767.0
00064 
00065 class vtkMatrix4x4;
00066 class vtkMultiThreader;
00067 class vtkPlaneCollection;
00068 class vtkRenderer;
00069 class vtkTimerLog;
00070 class vtkVolume;
00071 class vtkTransform;
00072 class vtkRenderWindow;
00073 class vtkColorTransferFunction;
00074 class vtkPiecewiseFunction;
00075 class vtkSlicerFixedPointVolumeRayCastMIPHelper;
00076 class vtkSlicerFixedPointVolumeRayCastCompositeHelper;
00077 class vtkSlicerFixedPointVolumeRayCastCompositeGOHelper;
00078 class vtkSlicerFixedPointVolumeRayCastCompositeGOShadeHelper;
00079 class vtkSlicerFixedPointVolumeRayCastCompositeShadeHelper;
00080 class vtkDirectionEncoder;
00081 class vtkEncodedGradientShader;
00082 class vtkFiniteDifferenceGradientEstimator;
00083 #include "vtkSlicerRayCastImageDisplayHelper.h"
00084 class vtkSlicerFixedPointRayCastImage;
00085 
00086 // Forward declaration needed for use by friend declaration below.
00087 VTK_THREAD_RETURN_TYPE SlicerFixedPointVolumeRayCastMapper_CastRays( void *arg );
00088 
00090 class Q_SLICER_QTMODULES_VOLUMERENDERING_REPLACEMENTS_EXPORT vtkSlicerFixedPointVolumeRayCastMapper : public vtkVolumeMapper
00091 {
00092 public:
00093   //SLICERADD
00094     vtkGetMacro(ManualInteractive,int);
00095     vtkSetMacro(ManualInteractive,int);
00096     vtkBooleanMacro(ManualInteractive,int);
00097     vtkGetMacro(ManualInteractiveRate,double);
00098     vtkSetMacro(ManualInteractiveRate,double);
00099 
00100   //ENDSLICERADD
00101 
00102   static vtkSlicerFixedPointVolumeRayCastMapper *New();
00103   vtkTypeRevisionMacro(vtkSlicerFixedPointVolumeRayCastMapper,vtkVolumeMapper);
00104   void PrintSelf( ostream& os, vtkIndent indent );
00105 
00106   // Description:
00107   // Set/Get the distance between samples used for rendering
00108   // when AutoAdjustSampleDistances is off, or when this mapper
00109   // has more than 1 second allocated to it for rendering.
00110   vtkSetMacro( SampleDistance, float );
00111   vtkGetMacro( SampleDistance, float );
00112 
00113   // Description:
00114   // Set/Get the distance between samples when interactive rendering is happening.
00115   // In this case, interactive is defined as this volume mapper having less than 1
00116   // second allocated for rendering. When AutoAdjustSampleDistance is On, and the
00117   // allocated render time is less than 1 second, then this InteractiveSampleDistance
00118   // will be used instead of the SampleDistance above.
00119   vtkSetMacro( InteractiveSampleDistance, float );
00120   vtkGetMacro( InteractiveSampleDistance, float );
00121 
00122   // Description:
00123   // Sampling distance in the XY image dimensions. Default value of 1 meaning
00124   // 1 ray cast per pixel. If set to 0.5, 4 rays will be cast per pixel. If
00125   // set to 2.0, 1 ray will be cast for every 4 (2 by 2) pixels. This value
00126   // will be adjusted to meet a desired frame rate when AutoAdjustSampleDistances
00127   // is on.
00128   vtkSetClampMacro( ImageSampleDistance, float, 0.1f, 100.0f );
00129   vtkGetMacro( ImageSampleDistance, float );
00130 
00131   // Description:
00132   // This is the minimum image sample distance allow when the image
00133   // sample distance is being automatically adjusted.
00134   vtkSetClampMacro( MinimumImageSampleDistance, float, 0.1f, 100.0f );
00135   vtkGetMacro( MinimumImageSampleDistance, float );
00136 
00137   // Description:
00138   // This is the maximum image sample distance allow when the image
00139   // sample distance is being automatically adjusted.
00140   vtkSetClampMacro( MaximumImageSampleDistance, float, 0.1f, 100.0f );
00141   vtkGetMacro( MaximumImageSampleDistance, float );
00142 
00143   // Description:
00144   // If AutoAdjustSampleDistances is on, the the ImageSampleDistance
00145   // and the SampleDistance will be varied to achieve the allocated
00146   // render time of this prop (controlled by the desired update rate
00147   // and any culling in use). If this is an interactive render (more
00148   // than 1 frame per second) the SampleDistance will be increased,
00149   // otherwise it will not be altered (a binary decision, as opposed
00150   // to the ImageSampleDistance which will vary continuously).
00151   vtkSetClampMacro( AutoAdjustSampleDistances, int, 0, 1 );
00152   vtkGetMacro( AutoAdjustSampleDistances, int );
00153   vtkBooleanMacro( AutoAdjustSampleDistances, int );
00154 
00155   // Description:
00156   // Set/Get the number of threads to use. This by default is equal to
00157   // the number of available processors detected.
00158   void SetNumberOfThreads( int num );
00159   int GetNumberOfThreads();
00160 
00161   // Description:
00162   // If IntermixIntersectingGeometry is turned on, the zbuffer will be
00163   // captured and used to limit the traversal of the rays.
00164   vtkSetClampMacro( IntermixIntersectingGeometry, int, 0, 1 );
00165   vtkGetMacro( IntermixIntersectingGeometry, int );
00166   vtkBooleanMacro( IntermixIntersectingGeometry, int );
00167 
00168   // Description:
00169   // What is the image sample distance required to achieve the desired time?
00170   // A version of this method is provided that does not require the volume
00171   // argument since if you are using an LODProp3D you may not know this information.
00172   // If you use this version you must be certain that the ray cast mapper is
00173   // only used for one volume (and not shared among multiple volumes)
00174   float ComputeRequiredImageSampleDistance( float desiredTime,
00175                                             vtkRenderer *ren );
00176   float ComputeRequiredImageSampleDistance( float desiredTime,
00177                                             vtkRenderer *ren,
00178                                             vtkVolume *vol );
00179 
00180   // Description:
00181   // WARNING: INTERNAL METHOD - NOT INTENDED FOR GENERAL USE
00182   // Initialize rendering for this volume.
00183   void Render( vtkRenderer *, vtkVolume * );
00184 
00185   unsigned int ToSlicerFixedPointPosition( float val );
00186   void ToSlicerFixedPointPosition( float in[3], unsigned int out[3] );
00187   unsigned int ToSlicerFixedPointDirection( float dir );
00188   void ToSlicerFixedPointDirection( float in[3], unsigned int out[3] );
00189   void FixedPointIncrement( unsigned int position[3], unsigned int increment[3] );
00190   void GetFloatTripleFromPointer( float v[3], float *ptr );
00191   void GetUIntTripleFromPointer( unsigned int v[3], unsigned int *ptr );
00192   void ShiftVectorDown( unsigned int in[3], unsigned int out[3] );
00193   int CheckMinMaxVolumeFlag( unsigned int pos[3], int c );
00194   int CheckMIPMinMaxVolumeFlag( unsigned int pos[3], int c, unsigned short maxIdx );
00195 
00196   void LookupColorUC( unsigned short *colorTable,
00197                       unsigned short *scalarOpacityTable,
00198                       unsigned short index,
00199                       unsigned char  color[4] );
00200   void LookupDependentColorUC( unsigned short *colorTable,
00201                                unsigned short *scalarOpacityTable,
00202                                unsigned short index[4],
00203                                int            components,
00204                                unsigned char  color[4] );
00205   void LookupAndCombineIndependentColorsUC(
00206     unsigned short *colorTable[4],
00207     unsigned short *scalarOpacityTable[4],
00208     unsigned short index[4],
00209     float          weights[4],
00210     int            components,
00211     unsigned char  color[4] );
00212   int CheckIfCropped( unsigned int pos[3] );
00213 
00214 
00215   vtkGetObjectMacro( RenderWindow, vtkRenderWindow );
00216   vtkGetObjectMacro( MIPHelper, vtkSlicerFixedPointVolumeRayCastMIPHelper );
00217   vtkGetObjectMacro( CompositeHelper, vtkSlicerFixedPointVolumeRayCastCompositeHelper );
00218   vtkGetObjectMacro( CompositeGOHelper, vtkSlicerFixedPointVolumeRayCastCompositeGOHelper );
00219   vtkGetObjectMacro( CompositeGOShadeHelper, vtkSlicerFixedPointVolumeRayCastCompositeGOShadeHelper );
00220   vtkGetObjectMacro( CompositeShadeHelper, vtkSlicerFixedPointVolumeRayCastCompositeShadeHelper );
00221   vtkGetVectorMacro( TableShift, float, 4 );
00222   vtkGetVectorMacro( TableScale, float, 4 );
00223   vtkGetMacro( ShadingRequired, int );
00224   vtkGetMacro( GradientOpacityRequired, int );
00225 
00226   int             *GetRowBounds()                 {return this->RowBounds;}
00227   unsigned short  *GetColorTable(int c)           {return this->ColorTable[c];}
00228   unsigned short  *GetScalarOpacityTable(int c)   {return this->ScalarOpacityTable[c];}
00229   unsigned short  *GetGradientOpacityTable(int c) {return this->GradientOpacityTable[c];}
00230   vtkVolume       *GetVolume()                    {return this->Volume;}
00231   unsigned short **GetGradientNormal()            {return this->GradientNormal;}
00232   unsigned char  **GetGradientMagnitude()         {return this->GradientMagnitude;}
00233   unsigned short  *GetDiffuseShadingTable(int c)  {return this->DiffuseShadingTable[c];}
00234   unsigned short  *GetSpecularShadingTable(int c) {return this->SpecularShadingTable[c];}
00235 
00236   void ComputeRayInfo( int x, int y,
00237                        unsigned int pos[3],
00238                        unsigned int dir[3],
00239                        unsigned int *numSteps );
00240 
00241   void InitializeRayInfo( vtkVolume *vol );
00242 
00243   int ShouldUseNearestNeighborInterpolation( vtkVolume *vol );
00244 
00245   // Description:
00246   // Set / Get the underlying image object. One will be automatically
00247   // created - only need to set it when using from an AMR mapper which
00248   // renders multiple times into the same image.
00249   void SetRayCastImage( vtkSlicerFixedPointRayCastImage * );
00250   vtkGetObjectMacro( RayCastImage, vtkSlicerFixedPointRayCastImage  );
00251 
00252   int PerImageInitialization( vtkRenderer *, vtkVolume *, int,
00253                               double *, double *, int * );
00254   void PerVolumeInitialization( vtkRenderer *, vtkVolume * );
00255   void PerSubVolumeInitialization( vtkRenderer *, vtkVolume *, int );
00256   void RenderSubVolume();
00257   void DisplayRenderedImage( vtkRenderer *, vtkVolume * );
00258   void AbortRender();
00259 
00260 
00261 protected:
00262 
00263     //SLICERADD
00264     int ManualInteractive;
00265     double ManualInteractiveRate;
00266   //ENDSLICERADD
00267 
00268 
00269   vtkSlicerFixedPointVolumeRayCastMapper();
00270   ~vtkSlicerFixedPointVolumeRayCastMapper();
00271 
00272   // The helper class that displays the image
00273   vtkSlicerRayCastImageDisplayHelper *ImageDisplayHelper;
00274 
00275   // The distance between sample points along the ray
00276   float                        SampleDistance;
00277   float                        InteractiveSampleDistance;
00278 
00279   // The distance between rays in the image
00280   float                        ImageSampleDistance;
00281   float                        MinimumImageSampleDistance;
00282   float                        MaximumImageSampleDistance;
00283   int                          AutoAdjustSampleDistances;
00284 
00285   // Saved values used to restore
00286   float                        OldSampleDistance;
00287   float                        OldImageSampleDistance;
00288 
00289   // Internal method for computing matrices needed during
00290   // ray casting
00291   void ComputeMatrices( double volumeOrigin[3],
00292                         double volumeSpacing[3],
00293                         int volumeExtent[6],
00294                         vtkRenderer  *ren,
00295                         vtkVolume    *vol );
00296 
00297   int ComputeRowBounds( vtkRenderer *ren,
00298                         int imageFlag, int rowBoundsFlag,
00299                         int volumeExtent[6]);
00300 
00301   void CaptureZBuffer( vtkRenderer *ren );
00302 
00303   friend VTK_THREAD_RETURN_TYPE SlicerFixedPointVolumeRayCastMapper_CastRays( void *arg );
00304 
00305   vtkMultiThreader  *Threader;
00306 
00307   vtkMatrix4x4   *PerspectiveMatrix;
00308   vtkMatrix4x4   *ViewToWorldMatrix;
00309   vtkMatrix4x4   *ViewToVoxelsMatrix;
00310   vtkMatrix4x4   *VoxelsToViewMatrix;
00311   vtkMatrix4x4   *WorldToVoxelsMatrix;
00312   vtkMatrix4x4   *VoxelsToWorldMatrix;
00313 
00314   vtkMatrix4x4   *VolumeMatrix;
00315 
00316   vtkTransform   *PerspectiveTransform;
00317   vtkTransform   *VoxelsTransform;
00318   vtkTransform   *VoxelsToViewTransform;
00319 
00320   // This object encapsulated the image and all related information
00321   vtkSlicerFixedPointRayCastImage *RayCastImage;
00322 
00323   int             *RowBounds;
00324   int             *OldRowBounds;
00325 
00326   float           *RenderTimeTable;
00327   vtkVolume      **RenderVolumeTable;
00328   vtkRenderer    **RenderRendererTable;
00329   int              RenderTableSize;
00330   int              RenderTableEntries;
00331 
00332   void             StoreRenderTime( vtkRenderer *ren, vtkVolume *vol, float t );
00333   float            RetrieveRenderTime( vtkRenderer *ren, vtkVolume *vol );
00334   float            RetrieveRenderTime( vtkRenderer *ren );
00335 
00336   int              IntermixIntersectingGeometry;
00337 
00338   float            MinimumViewDistance;
00339 
00340   vtkColorTransferFunction *SavedRGBFunction[4];
00341   vtkPiecewiseFunction     *SavedGrayFunction[4];
00342   vtkPiecewiseFunction     *SavedScalarOpacityFunction[4];
00343   vtkPiecewiseFunction     *SavedGradientOpacityFunction[4];
00344   int                       SavedColorChannels[4];
00345   float                     SavedScalarOpacityDistance[4];
00346   int                       SavedBlendMode;
00347   vtkImageData             *SavedParametersInput;
00348   vtkTimeStamp              SavedParametersMTime;
00349 
00350   vtkImageData             *SavedGradientsInput;
00351   vtkTimeStamp              SavedGradientsMTime;
00352 
00353   float                     SavedSampleDistance;
00354 
00355 
00356   unsigned short            ColorTable[4][32768*3];
00357   unsigned short            ScalarOpacityTable[4][32768];
00358   unsigned short            GradientOpacityTable[4][256];
00359   int                       TableSize[4];
00360   float                     TableScale[4];
00361   float                     TableShift[4];
00362 
00363   float                     GradientMagnitudeScale[4];
00364   float                     GradientMagnitudeShift[4];
00365 
00366   unsigned short           **GradientNormal;
00367   unsigned char            **GradientMagnitude;
00368   unsigned short            *ContiguousGradientNormal;
00369   unsigned char             *ContiguousGradientMagnitude;
00370 
00371   int                        NumberOfGradientSlices;
00372 
00373   vtkDirectionEncoder       *DirectionEncoder;
00374 
00375   vtkEncodedGradientShader  *GradientShader;
00376 
00377   vtkFiniteDifferenceGradientEstimator *GradientEstimator;
00378 
00379   unsigned short             DiffuseShadingTable [4][65536*3];
00380   unsigned short             SpecularShadingTable[4][65536*3];
00381 
00382   int                        ShadingRequired;
00383   int                        GradientOpacityRequired;
00384 
00385   vtkRenderWindow           *RenderWindow;
00386   vtkVolume                 *Volume;
00387 
00388   int           ClipRayAgainstVolume( float rayStart[3],
00389                                       float rayEnd[3],
00390                                       float rayDirection[3],
00391                                       double bounds[6] );
00392 
00393   int           UpdateColorTable( vtkVolume *vol );
00394   int           UpdateGradients( vtkVolume *vol );
00395   int           UpdateShadingTable( vtkRenderer *ren,
00396                                     vtkVolume *vol );
00397   void          UpdateCroppingRegions();
00398 
00399   void          ComputeGradients( vtkVolume *vol );
00400 
00401   int           ClipRayAgainstClippingPlanes( float  rayStart[3],
00402                                               float  rayEnd[3],
00403                                               int    numClippingPlanes,
00404                                               float *clippingPlanes );
00405 
00406   unsigned int  SlicerFixedPointCroppingRegionPlanes[6];
00407   unsigned int  CroppingRegionMask[27];
00408 
00409   // Get the ZBuffer value corresponding to location (x,y) where (x,y)
00410   // are indexing into the ImageInUse image. This must be converted to
00411   // the zbuffer image coordinates. Nearest neighbor value is returned.
00412   float         GetZBufferValue( int x, int y );
00413 
00414   vtkSlicerFixedPointVolumeRayCastMIPHelper              *MIPHelper;
00415   vtkSlicerFixedPointVolumeRayCastCompositeHelper        *CompositeHelper;
00416   vtkSlicerFixedPointVolumeRayCastCompositeGOHelper      *CompositeGOHelper;
00417   vtkSlicerFixedPointVolumeRayCastCompositeShadeHelper   *CompositeShadeHelper;
00418   vtkSlicerFixedPointVolumeRayCastCompositeGOShadeHelper *CompositeGOShadeHelper;
00419 
00420   // Some variables used for ray computation
00421   float ViewToVoxelsArray[16];
00422   float WorldToVoxelsArray[16];
00423   float VoxelsToWorldArray[16];
00424 
00425   double CroppingBounds[6];
00426 
00427   int NumTransformedClippingPlanes;
00428   float *TransformedClippingPlanes;
00429 
00430   double SavedSpacing[3];
00431 
00432 
00433   // Min Max structured used to do space leaping
00434   unsigned short *MinMaxVolume;
00435   int             MinMaxVolumeSize[4];
00436   vtkImageData   *SavedMinMaxInput;
00437   vtkTimeStamp    SavedMinMaxBuildTime;
00438   vtkTimeStamp    SavedMinMaxGradientTime;
00439   vtkTimeStamp    SavedMinMaxFlagTime;
00440 
00441   void            UpdateMinMaxVolume( vtkVolume *vol );
00442   void            FillInMaxGradientMagnitudes( int fullDim[3],
00443                                                int smallDim[3] );
00444 
00445 private:
00446   vtkSlicerFixedPointVolumeRayCastMapper(const vtkSlicerFixedPointVolumeRayCastMapper&);  // Not implemented.
00447   void operator=(const vtkSlicerFixedPointVolumeRayCastMapper&);  // Not implemented.
00448 };
00449 
00450 
00451 inline unsigned int vtkSlicerFixedPointVolumeRayCastMapper::ToSlicerFixedPointPosition( float val )
00452 {
00453   return static_cast<unsigned int>(val * VTKKW_FP_SCALE + 0.5);
00454 }
00455 
00456 inline void vtkSlicerFixedPointVolumeRayCastMapper::ToSlicerFixedPointPosition( float in[3], unsigned int out[3] )
00457 {
00458   out[0] = static_cast<unsigned int>(in[0] * VTKKW_FP_SCALE + 0.5);
00459   out[1] = static_cast<unsigned int>(in[1] * VTKKW_FP_SCALE + 0.5);
00460   out[2] = static_cast<unsigned int>(in[2] * VTKKW_FP_SCALE + 0.5);
00461 }
00462 
00463 inline unsigned int vtkSlicerFixedPointVolumeRayCastMapper::ToSlicerFixedPointDirection( float dir )
00464 {
00465   return ((dir<0.0)?
00466           (static_cast<unsigned int>(-dir * VTKKW_FP_SCALE + 0.5)):
00467           (0x80000000+static_cast<unsigned int>(dir*VTKKW_FP_SCALE + 0.5)));
00468 }
00469 
00470 inline void vtkSlicerFixedPointVolumeRayCastMapper::ToSlicerFixedPointDirection( float in[3], unsigned int out[3] )
00471 {
00472   out[0] = ((in[0]<0.0)?
00473             (static_cast<unsigned int>(-in[0] * VTKKW_FP_SCALE + 0.5)):
00474             (0x80000000+
00475              static_cast<unsigned int>(in[0]*VTKKW_FP_SCALE + 0.5)));
00476   out[1] = ((in[1]<0.0)?
00477             (static_cast<unsigned int>(-in[1] * VTKKW_FP_SCALE + 0.5)):
00478             (0x80000000+
00479              static_cast<unsigned int>(in[1]*VTKKW_FP_SCALE + 0.5)));
00480   out[2] = ((in[2]<0.0)?
00481             (static_cast<unsigned int>(-in[2] * VTKKW_FP_SCALE + 0.5)):
00482             (0x80000000+
00483              static_cast<unsigned int>(in[2]*VTKKW_FP_SCALE + 0.5)));
00484 }
00485 
00486 inline void vtkSlicerFixedPointVolumeRayCastMapper::FixedPointIncrement( unsigned int position[3], unsigned int increment[3] )
00487 {
00488   if ( increment[0]&0x80000000 )
00489     {
00490     position[0] += (increment[0]&0x7fffffff);
00491     }
00492   else
00493     {
00494     position[0] -= increment[0];
00495     }
00496   if ( increment[1]&0x80000000 )
00497     {
00498     position[1] += (increment[1]&0x7fffffff);
00499     }
00500   else
00501     {
00502     position[1] -= increment[1];
00503     }
00504   if ( increment[2]&0x80000000 )
00505     {
00506     position[2] += (increment[2]&0x7fffffff);
00507     }
00508   else
00509     {
00510     position[2] -= increment[2];
00511     }
00512 }
00513 
00514 
00515 inline void vtkSlicerFixedPointVolumeRayCastMapper::GetFloatTripleFromPointer( float v[3], float *ptr )
00516 {
00517   v[0] = *(ptr);
00518   v[1] = *(ptr+1);
00519   v[2] = *(ptr+2);
00520 }
00521 
00522 inline void vtkSlicerFixedPointVolumeRayCastMapper::GetUIntTripleFromPointer( unsigned int v[3], unsigned int *ptr )
00523 {
00524   v[0] = *(ptr);
00525   v[1] = *(ptr+1);
00526   v[2] = *(ptr+2);
00527 }
00528 
00529 inline void vtkSlicerFixedPointVolumeRayCastMapper::ShiftVectorDown( unsigned int in[3],
00530                                                        unsigned int out[3] )
00531 {
00532   out[0] = in[0] >> VTKKW_FP_SHIFT;
00533   out[1] = in[1] >> VTKKW_FP_SHIFT;
00534   out[2] = in[2] >> VTKKW_FP_SHIFT;
00535 }
00536 
00537 inline int vtkSlicerFixedPointVolumeRayCastMapper::CheckMinMaxVolumeFlag( unsigned int mmpos[3], int c )
00538 {
00539   unsigned int offset =
00540     this->MinMaxVolumeSize[3] *
00541     ( mmpos[2]*this->MinMaxVolumeSize[0]*this->MinMaxVolumeSize[1] +
00542       mmpos[1]*this->MinMaxVolumeSize[0] +
00543       mmpos[0] ) + c;
00544 
00545   return ((*(this->MinMaxVolume + 3*offset + 2))&0x00ff);
00546 }
00547 
00548 inline int vtkSlicerFixedPointVolumeRayCastMapper::CheckMIPMinMaxVolumeFlag( unsigned int mmpos[3], int c,
00549                                                                        unsigned short maxIdx )
00550 {
00551   unsigned int offset =
00552     this->MinMaxVolumeSize[3] *
00553     ( mmpos[2]*this->MinMaxVolumeSize[0]*this->MinMaxVolumeSize[1] +
00554       mmpos[1]*this->MinMaxVolumeSize[0] +
00555       mmpos[0] ) + c;
00556 
00557   if ( (*(this->MinMaxVolume + 3*offset + 2)&0x00ff) )
00558     {
00559     return ( *(this->MinMaxVolume + 3*offset + 1) > maxIdx );
00560     }
00561   else
00562     {
00563     return 0;
00564     }
00565 }
00566 
00567 inline void vtkSlicerFixedPointVolumeRayCastMapper::LookupColorUC( unsigned short *colorTable,
00568                                                      unsigned short *scalarOpacityTable,
00569                                                      unsigned short index,
00570                                                      unsigned char  color[4] )
00571 {
00572   unsigned short alpha = scalarOpacityTable[index];
00573   color[0] = static_cast<unsigned char>
00574     ((colorTable[3*index  ]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
00575   color[1] = static_cast<unsigned char>
00576     ((colorTable[3*index+1]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
00577   color[2] = static_cast<unsigned char>
00578     ((colorTable[3*index+2]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
00579   color[3] = static_cast<unsigned char>(alpha>>(VTKKW_FP_SHIFT - 8));
00580 }
00581 
00582 inline void vtkSlicerFixedPointVolumeRayCastMapper::LookupDependentColorUC( unsigned short *colorTable,
00583                                                               unsigned short *scalarOpacityTable,
00584                                                               unsigned short index[4],
00585                                                               int            components,
00586                                                               unsigned char  color[4] )
00587 {
00588   unsigned short alpha;
00589   switch ( components )
00590     {
00591     case 2:
00592       alpha = scalarOpacityTable[index[1]];
00593       color[0] = static_cast<unsigned char>
00594         ((colorTable[3*index[0]  ]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
00595       color[1] = static_cast<unsigned char>
00596         ((colorTable[3*index[0]+1]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
00597       color[2] = static_cast<unsigned char>
00598         ((colorTable[3*index[0]+2]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
00599       color[3] = static_cast<unsigned char>(alpha>>(VTKKW_FP_SHIFT - 8));
00600       break;
00601     case 4:
00602       alpha = scalarOpacityTable[index[3]];
00603       color[0] = static_cast<unsigned char>((index[0]*alpha + 0x7fff)>>VTKKW_FP_SHIFT );
00604       color[1] = static_cast<unsigned char>((index[1]*alpha + 0x7fff)>>VTKKW_FP_SHIFT );
00605       color[2] = static_cast<unsigned char>((index[2]*alpha + 0x7fff)>>VTKKW_FP_SHIFT );
00606       color[3] = static_cast<unsigned char>(alpha>>(VTKKW_FP_SHIFT - 8));
00607       break;
00608     }
00609 }
00610 
00611 
00612 inline void vtkSlicerFixedPointVolumeRayCastMapper::LookupAndCombineIndependentColorsUC( unsigned short *colorTable[4],
00613                                                                            unsigned short *scalarOpacityTable[4],
00614                                                                            unsigned short  index[4],
00615                                                                            float           weights[4],
00616                                                                            int             components,
00617                                                                            unsigned char   color[4] )
00618 {
00619   unsigned int tmp[4] = {0,0,0,0};
00620 
00621   for ( int i = 0; i < components; i++ )
00622     {
00623     unsigned short alpha = static_cast<unsigned short>(scalarOpacityTable[i][index[i]]*weights[i]);
00624     tmp[0] += static_cast<unsigned char>(((colorTable[i][3*index[i]  ])*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
00625     tmp[1] += static_cast<unsigned char>(((colorTable[i][3*index[i]+1])*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
00626     tmp[2] += static_cast<unsigned char>(((colorTable[i][3*index[i]+2])*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
00627     tmp[3] += static_cast<unsigned char>(alpha>>(VTKKW_FP_SHIFT - 8));
00628     }
00629 
00630   color[0] = (tmp[0]>255)?(255):(tmp[0]);
00631   color[1] = (tmp[1]>255)?(255):(tmp[1]);
00632   color[2] = (tmp[2]>255)?(255):(tmp[2]);
00633   color[3] = (tmp[3]>255)?(255):(tmp[3]);
00634 
00635 }
00636 
00637 inline int vtkSlicerFixedPointVolumeRayCastMapper::CheckIfCropped( unsigned int pos[3] )
00638 {
00639   int idx;
00640 
00641   if ( pos[2] < this->SlicerFixedPointCroppingRegionPlanes[4] )
00642     {
00643     idx = 0;
00644     }
00645   else if ( pos[2] > this->SlicerFixedPointCroppingRegionPlanes[5] )
00646     {
00647     idx = 18;
00648     }
00649   else
00650     {
00651     idx = 9;
00652     }
00653 
00654   if ( pos[1] >= this->SlicerFixedPointCroppingRegionPlanes[2] )
00655     {
00656     if ( pos[1] > this->SlicerFixedPointCroppingRegionPlanes[3] )
00657       {
00658       idx += 6;
00659       }
00660     else
00661       {
00662       idx += 3;
00663       }
00664     }
00665 
00666   if ( pos[0] >= this->SlicerFixedPointCroppingRegionPlanes[0] )
00667     {
00668     if ( pos[0] > this->SlicerFixedPointCroppingRegionPlanes[1] )
00669       {
00670       idx += 2;
00671       }
00672     else
00673       {
00674       idx += 1;
00675       }
00676     }
00677 
00678   return !(this->CroppingRegionFlags&this->CroppingRegionMask[idx]);
00679 }
00680 
00681 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines