|
Slicer 4.2
Slicer is a multi-platform, free and open source software package for visualization and medical image computing
|
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
1.7.4