VTK
vtkFixedPointVolumeRayCastMapper.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkFixedPointVolumeRayCastMapper.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
64 #ifndef __vtkFixedPointVolumeRayCastMapper_h
65 #define __vtkFixedPointVolumeRayCastMapper_h
66 
67 #include "vtkRenderingVolumeModule.h" // For export macro
68 #include "vtkVolumeMapper.h"
69 
70 #define VTKKW_FP_SHIFT 15
71 #define VTKKW_FPMM_SHIFT 17
72 #define VTKKW_FP_MASK 0x7fff
73 #define VTKKW_FP_SCALE 32767.0
74 
75 class vtkMatrix4x4;
76 class vtkMultiThreader;
77 class vtkPlaneCollection;
78 class vtkRenderer;
79 class vtkTimerLog;
80 class vtkVolume;
81 class vtkTransform;
82 class vtkRenderWindow;
96 class vtkDataArray;
97 
98 //BTX
99 // Forward declaration needed for use by friend declaration below.
102 //ETX
103 
104 class VTKRENDERINGVOLUME_EXPORT vtkFixedPointVolumeRayCastMapper : public vtkVolumeMapper
105 {
106 public:
109  void PrintSelf( ostream& os, vtkIndent indent );
110 
112 
115  vtkSetMacro( SampleDistance, float );
116  vtkGetMacro( SampleDistance, float );
118 
120 
126  vtkSetMacro( InteractiveSampleDistance, float );
127  vtkGetMacro( InteractiveSampleDistance, float );
129 
131 
136  vtkSetClampMacro( ImageSampleDistance, float, 0.1f, 100.0f );
137  vtkGetMacro( ImageSampleDistance, float );
139 
141 
143  vtkSetClampMacro( MinimumImageSampleDistance, float, 0.1f, 100.0f );
144  vtkGetMacro( MinimumImageSampleDistance, float );
146 
148 
150  vtkSetClampMacro( MaximumImageSampleDistance, float, 0.1f, 100.0f );
151  vtkGetMacro( MaximumImageSampleDistance, float );
153 
155 
162  vtkSetClampMacro( AutoAdjustSampleDistances, int, 0, 1 );
163  vtkGetMacro( AutoAdjustSampleDistances, int );
164  vtkBooleanMacro( AutoAdjustSampleDistances, int );
166 
168 
175  vtkSetClampMacro( LockSampleDistanceToInputSpacing, int, 0, 1 );
176  vtkGetMacro( LockSampleDistanceToInputSpacing, int );
177  vtkBooleanMacro( LockSampleDistanceToInputSpacing, int );
179 
181 
183  void SetNumberOfThreads( int num );
184  int GetNumberOfThreads();
186 
188 
190  vtkSetClampMacro( IntermixIntersectingGeometry, int, 0, 1 );
191  vtkGetMacro( IntermixIntersectingGeometry, int );
192  vtkBooleanMacro( IntermixIntersectingGeometry, int );
194 
196 
202  float ComputeRequiredImageSampleDistance( float desiredTime,
203  vtkRenderer *ren );
204  float ComputeRequiredImageSampleDistance( float desiredTime,
205  vtkRenderer *ren,
206  vtkVolume *vol );
208 
209 //BTX
212  void Render( vtkRenderer *, vtkVolume * );
213 
214  unsigned int ToFixedPointPosition( float val );
215  void ToFixedPointPosition( float in[3], unsigned int out[3] );
216  unsigned int ToFixedPointDirection( float dir );
217  void ToFixedPointDirection( float in[3], unsigned int out[3] );
218  void FixedPointIncrement( unsigned int position[3], unsigned int increment[3] );
219  void GetFloatTripleFromPointer( float v[3], float *ptr );
220  void GetUIntTripleFromPointer( unsigned int v[3], unsigned int *ptr );
221  void ShiftVectorDown( unsigned int in[3], unsigned int out[3] );
222  int CheckMinMaxVolumeFlag( unsigned int pos[3], int c );
223  int CheckMIPMinMaxVolumeFlag( unsigned int pos[3], int c, unsigned short maxIdx, int flip );
224 
225  void LookupColorUC( unsigned short *colorTable,
226  unsigned short *scalarOpacityTable,
227  unsigned short index,
228  unsigned char color[4] );
229  void LookupDependentColorUC( unsigned short *colorTable,
230  unsigned short *scalarOpacityTable,
231  unsigned short index[4],
232  int components,
233  unsigned char color[4] );
234  void LookupAndCombineIndependentColorsUC(
235  unsigned short *colorTable[4],
236  unsigned short *scalarOpacityTable[4],
237  unsigned short index[4],
238  float weights[4],
239  int components,
240  unsigned char color[4] );
241  int CheckIfCropped( unsigned int pos[3] );
242 
243 //ETX
244 
245  vtkGetObjectMacro( RenderWindow, vtkRenderWindow );
246  vtkGetObjectMacro( MIPHelper, vtkFixedPointVolumeRayCastMIPHelper );
247  vtkGetObjectMacro( CompositeHelper, vtkFixedPointVolumeRayCastCompositeHelper );
248  vtkGetObjectMacro( CompositeGOHelper, vtkFixedPointVolumeRayCastCompositeGOHelper );
249  vtkGetObjectMacro( CompositeGOShadeHelper, vtkFixedPointVolumeRayCastCompositeGOShadeHelper );
250  vtkGetObjectMacro( CompositeShadeHelper, vtkFixedPointVolumeRayCastCompositeShadeHelper );
251  vtkGetVectorMacro( TableShift, float, 4 );
252  vtkGetVectorMacro( TableScale, float, 4 );
253  vtkGetMacro( ShadingRequired, int );
254  vtkGetMacro( GradientOpacityRequired, int );
255 
256  vtkGetObjectMacro( CurrentScalars, vtkDataArray );
257  vtkGetObjectMacro( PreviousScalars, vtkDataArray );
258 
259 
260  int *GetRowBounds() {return this->RowBounds;}
261  unsigned short *GetColorTable(int c) {return this->ColorTable[c];}
262  unsigned short *GetScalarOpacityTable(int c) {return this->ScalarOpacityTable[c];}
263  unsigned short *GetGradientOpacityTable(int c) {return this->GradientOpacityTable[c];}
264  vtkVolume *GetVolume() {return this->Volume;}
265  unsigned short **GetGradientNormal() {return this->GradientNormal;}
266  unsigned char **GetGradientMagnitude() {return this->GradientMagnitude;}
267  unsigned short *GetDiffuseShadingTable(int c) {return this->DiffuseShadingTable[c];}
268  unsigned short *GetSpecularShadingTable(int c) {return this->SpecularShadingTable[c];}
269 
270  void ComputeRayInfo( int x, int y,
271  unsigned int pos[3],
272  unsigned int dir[3],
273  unsigned int *numSteps );
274 
275  void InitializeRayInfo( vtkVolume *vol );
276 
277  int ShouldUseNearestNeighborInterpolation( vtkVolume *vol );
278 
280 
283  void SetRayCastImage( vtkFixedPointRayCastImage * );
284  vtkGetObjectMacro( RayCastImage, vtkFixedPointRayCastImage );
286 
287  int PerImageInitialization( vtkRenderer *, vtkVolume *, int,
288  double *, double *, int * );
289  void PerVolumeInitialization( vtkRenderer *, vtkVolume * );
290  void PerSubVolumeInitialization( vtkRenderer *, vtkVolume *, int );
291  void RenderSubVolume();
292  void DisplayRenderedImage( vtkRenderer *, vtkVolume * );
293  void AbortRender();
294 
295  void CreateCanonicalView( vtkVolume *volume,
297  int blend_mode,
298  double viewDirection[3],
299  double viewUp[3] );
300 
302 
306  float GetEstimatedRenderTime( vtkRenderer *ren,
307  vtkVolume *vol )
308  { return this->RetrieveRenderTime( ren, vol ); }
309  float GetEstimatedRenderTime( vtkRenderer *ren )
310  { return this->RetrieveRenderTime( ren ); }
312 
313 
315 
321  vtkSetMacro( FinalColorWindow, float );
322  vtkGetMacro( FinalColorWindow, float );
323  vtkSetMacro( FinalColorLevel, float );
324  vtkGetMacro( FinalColorLevel, float );
326 
327 
328  // Here to be used by the mapper to tell the helper
329  // to flip the MIP comparison in order to support
330  // minimum intensity blending
331  vtkGetMacro( FlipMIPComparison, int );
332 
333 protected:
336 
337  // The helper class that displays the image
339 
340  // The distance between sample points along the ray
343 
344  // The distance between rays in the image
350 
351  // Saved values used to restore
354 
355  // Internal method for computing matrices needed during
356  // ray casting
357  void ComputeMatrices( double volumeOrigin[3],
358  double volumeSpacing[3],
359  int volumeExtent[6],
360  vtkRenderer *ren,
361  vtkVolume *vol );
362 
363  int ComputeRowBounds( vtkRenderer *ren,
364  int imageFlag, int rowBoundsFlag,
365  int volumeExtent[6]);
366 
367  void CaptureZBuffer( vtkRenderer *ren );
368 
371 
373 
380 
382 
386 
387  // This object encapsulated the image and all related information
389 
390  int *RowBounds;
392 
398 
399  void StoreRenderTime( vtkRenderer *ren, vtkVolume *vol, float t );
400  float RetrieveRenderTime( vtkRenderer *ren, vtkVolume *vol );
401  float RetrieveRenderTime( vtkRenderer *ren );
402 
404 
406 
407  vtkColorTransferFunction *SavedRGBFunction[4];
408  vtkPiecewiseFunction *SavedGrayFunction[4];
409  vtkPiecewiseFunction *SavedScalarOpacityFunction[4];
410  vtkPiecewiseFunction *SavedGradientOpacityFunction[4];
411  int SavedColorChannels[4];
412  float SavedScalarOpacityDistance[4];
416 
419 
421 
422 
423  unsigned short ColorTable[4][32768*3];
424  unsigned short ScalarOpacityTable[4][32768];
425  unsigned short GradientOpacityTable[4][256];
426  int TableSize[4];
427  float TableScale[4];
428  float TableShift[4];
429 
430  float GradientMagnitudeScale[4];
431  float GradientMagnitudeShift[4];
432 
433  unsigned short **GradientNormal;
434  unsigned char **GradientMagnitude;
435  unsigned short *ContiguousGradientNormal;
437 
439 
441 
443 
445 
446  unsigned short DiffuseShadingTable [4][65536*3];
447  unsigned short SpecularShadingTable[4][65536*3];
448 
451 
454 
457 
458  int ClipRayAgainstVolume( float rayStart[3],
459  float rayEnd[3],
460  float rayDirection[3],
461  double bounds[6] );
462 
463  int UpdateColorTable( vtkVolume *vol );
464  int UpdateGradients( vtkVolume *vol );
465  int UpdateShadingTable( vtkRenderer *ren,
466  vtkVolume *vol );
467  void UpdateCroppingRegions();
468 
469  void ComputeGradients( vtkVolume *vol );
470 
471  int ClipRayAgainstClippingPlanes( float rayStart[3],
472  float rayEnd[3],
473  int numClippingPlanes,
474  float *clippingPlanes );
475 
476  unsigned int FixedPointCroppingRegionPlanes[6];
477  unsigned int CroppingRegionMask[27];
478 
479  // Get the ZBuffer value corresponding to location (x,y) where (x,y)
480  // are indexing into the ImageInUse image. This must be converted to
481  // the zbuffer image coordinates. Nearest neighbor value is returned.
482  float GetZBufferValue( int x, int y );
483 
489 
490  // Some variables used for ray computation
491  float ViewToVoxelsArray[16];
492  float WorldToVoxelsArray[16];
493  float VoxelsToWorldArray[16];
494 
495  double CroppingBounds[6];
496 
499 
500  double SavedSpacing[3];
501 
502 
503  // Min Max structure used to do space leaping
504  unsigned short *MinMaxVolume;
505  int MinMaxVolumeSize[4];
509 
510  void UpdateMinMaxVolume( vtkVolume *vol );
511  void FillInMaxGradientMagnitudes( int fullDim[3],
512  int smallDim[3] );
513 
516 
518 
519  void ApplyFinalColorWindowLevel();
520 
521 private:
523  void operator=(const vtkFixedPointVolumeRayCastMapper&); // Not implemented.
524 };
525 
526 
528 {
529  return static_cast<unsigned int>(val * VTKKW_FP_SCALE + 0.5);
530 }
531 
532 inline void vtkFixedPointVolumeRayCastMapper::ToFixedPointPosition( float in[3], unsigned int out[3] )
533 {
534  out[0] = static_cast<unsigned int>(in[0] * VTKKW_FP_SCALE + 0.5);
535  out[1] = static_cast<unsigned int>(in[1] * VTKKW_FP_SCALE + 0.5);
536  out[2] = static_cast<unsigned int>(in[2] * VTKKW_FP_SCALE + 0.5);
537 }
538 
540 {
541  return ((dir<0.0)?
542  (static_cast<unsigned int>(-dir * VTKKW_FP_SCALE + 0.5)):
543  (0x80000000+static_cast<unsigned int>(dir*VTKKW_FP_SCALE + 0.5)));
544 }
545 
546 inline void vtkFixedPointVolumeRayCastMapper::ToFixedPointDirection( float in[3], unsigned int out[3] )
547 {
548  out[0] = ((in[0]<0.0)?
549  (static_cast<unsigned int>(-in[0] * VTKKW_FP_SCALE + 0.5)):
550  (0x80000000+
551  static_cast<unsigned int>(in[0]*VTKKW_FP_SCALE + 0.5)));
552  out[1] = ((in[1]<0.0)?
553  (static_cast<unsigned int>(-in[1] * VTKKW_FP_SCALE + 0.5)):
554  (0x80000000+
555  static_cast<unsigned int>(in[1]*VTKKW_FP_SCALE + 0.5)));
556  out[2] = ((in[2]<0.0)?
557  (static_cast<unsigned int>(-in[2] * VTKKW_FP_SCALE + 0.5)):
558  (0x80000000+
559  static_cast<unsigned int>(in[2]*VTKKW_FP_SCALE + 0.5)));
560 }
561 
562 inline void vtkFixedPointVolumeRayCastMapper::FixedPointIncrement( unsigned int position[3], unsigned int increment[3] )
563 {
564  if ( increment[0]&0x80000000 )
565  {
566  position[0] += (increment[0]&0x7fffffff);
567  }
568  else
569  {
570  position[0] -= increment[0];
571  }
572  if ( increment[1]&0x80000000 )
573  {
574  position[1] += (increment[1]&0x7fffffff);
575  }
576  else
577  {
578  position[1] -= increment[1];
579  }
580  if ( increment[2]&0x80000000 )
581  {
582  position[2] += (increment[2]&0x7fffffff);
583  }
584  else
585  {
586  position[2] -= increment[2];
587  }
588 }
589 
590 
592 {
593  v[0] = *(ptr);
594  v[1] = *(ptr+1);
595  v[2] = *(ptr+2);
596 }
597 
598 inline void vtkFixedPointVolumeRayCastMapper::GetUIntTripleFromPointer( unsigned int v[3], unsigned int *ptr )
599 {
600  v[0] = *(ptr);
601  v[1] = *(ptr+1);
602  v[2] = *(ptr+2);
603 }
604 
606  unsigned int out[3] )
607 {
608  out[0] = in[0] >> VTKKW_FP_SHIFT;
609  out[1] = in[1] >> VTKKW_FP_SHIFT;
610  out[2] = in[2] >> VTKKW_FP_SHIFT;
611 }
612 
613 inline int vtkFixedPointVolumeRayCastMapper::CheckMinMaxVolumeFlag( unsigned int mmpos[3], int c )
614 {
615  vtkIdType offset =
616  static_cast<vtkIdType>(this->MinMaxVolumeSize[3]) *
617  ( mmpos[2]*static_cast<vtkIdType>(
618  this->MinMaxVolumeSize[0]*this->MinMaxVolumeSize[1]) +
619  mmpos[1]*static_cast<vtkIdType>(this->MinMaxVolumeSize[0]) +
620  mmpos[0] ) + static_cast<vtkIdType>(c);
621 
622  return ((*(this->MinMaxVolume + 3*offset + 2))&0x00ff);
623 }
624 
625 inline int vtkFixedPointVolumeRayCastMapper::CheckMIPMinMaxVolumeFlag( unsigned int mmpos[3], int c,
626  unsigned short maxIdx, int flip )
627 {
628  vtkIdType offset =
629  static_cast<vtkIdType>(this->MinMaxVolumeSize[3]) *
630  ( mmpos[2]*static_cast<vtkIdType>(
631  this->MinMaxVolumeSize[0]*this->MinMaxVolumeSize[1]) +
632  mmpos[1]*static_cast<vtkIdType>(this->MinMaxVolumeSize[0]) +
633  mmpos[0] ) + static_cast<vtkIdType>(c);
634 
635  if ( (*(this->MinMaxVolume + 3*offset + 2)&0x00ff) )
636  {
637  if (flip)
638  {
639  return ( *(this->MinMaxVolume + 3*offset) < maxIdx );
640  }
641  else
642  {
643  return ( *(this->MinMaxVolume + 3*offset + 1) > maxIdx );
644  }
645  }
646  else
647  {
648  return 0;
649  }
650 }
651 
652 inline void vtkFixedPointVolumeRayCastMapper::LookupColorUC( unsigned short *colorTable,
653  unsigned short *scalarOpacityTable,
654  unsigned short index,
655  unsigned char color[4] )
656 {
657  unsigned short alpha = scalarOpacityTable[index];
658  color[0] = static_cast<unsigned char>
659  ((colorTable[3*index ]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
660  color[1] = static_cast<unsigned char>
661  ((colorTable[3*index+1]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
662  color[2] = static_cast<unsigned char>
663  ((colorTable[3*index+2]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
664  color[3] = static_cast<unsigned char>(alpha>>(VTKKW_FP_SHIFT - 8));
665 }
666 
667 inline void vtkFixedPointVolumeRayCastMapper::LookupDependentColorUC( unsigned short *colorTable,
668  unsigned short *scalarOpacityTable,
669  unsigned short index[4],
670  int components,
671  unsigned char color[4] )
672 {
673  unsigned short alpha;
674  switch ( components )
675  {
676  case 2:
677  alpha = scalarOpacityTable[index[1]];
678  color[0] = static_cast<unsigned char>
679  ((colorTable[3*index[0] ]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
680  color[1] = static_cast<unsigned char>
681  ((colorTable[3*index[0]+1]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
682  color[2] = static_cast<unsigned char>
683  ((colorTable[3*index[0]+2]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
684  color[3] = static_cast<unsigned char>(alpha>>(VTKKW_FP_SHIFT - 8));
685  break;
686  case 4:
687  alpha = scalarOpacityTable[index[3]];
688  color[0] = static_cast<unsigned char>((index[0]*alpha + 0x7fff)>>VTKKW_FP_SHIFT );
689  color[1] = static_cast<unsigned char>((index[1]*alpha + 0x7fff)>>VTKKW_FP_SHIFT );
690  color[2] = static_cast<unsigned char>((index[2]*alpha + 0x7fff)>>VTKKW_FP_SHIFT );
691  color[3] = static_cast<unsigned char>(alpha>>(VTKKW_FP_SHIFT - 8));
692  break;
693  }
694 }
695 
696 
698  unsigned short *scalarOpacityTable[4],
699  unsigned short index[4],
700  float weights[4],
701  int components,
702  unsigned char color[4] )
703 {
704  unsigned int tmp[4] = {0,0,0,0};
705 
706  for ( int i = 0; i < components; i++ )
707  {
708  unsigned short alpha = static_cast<unsigned short>(static_cast<float>(scalarOpacityTable[i][index[i]])*weights[i]);
709  tmp[0] += static_cast<unsigned char>(((colorTable[i][3*index[i] ])*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
710  tmp[1] += static_cast<unsigned char>(((colorTable[i][3*index[i]+1])*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
711  tmp[2] += static_cast<unsigned char>(((colorTable[i][3*index[i]+2])*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
712  tmp[3] += static_cast<unsigned char>(alpha>>(VTKKW_FP_SHIFT - 8));
713  }
714 
715  color[0] = static_cast<unsigned char>((tmp[0]>255)?(255):(tmp[0]));
716  color[1] = static_cast<unsigned char>((tmp[1]>255)?(255):(tmp[1]));
717  color[2] = static_cast<unsigned char>((tmp[2]>255)?(255):(tmp[2]));
718  color[3] = static_cast<unsigned char>((tmp[3]>255)?(255):(tmp[3]));
719 
720 }
721 
722 inline int vtkFixedPointVolumeRayCastMapper::CheckIfCropped( unsigned int pos[3] )
723 {
724  int idx;
725 
726  if ( pos[2] < this->FixedPointCroppingRegionPlanes[4] )
727  {
728  idx = 0;
729  }
730  else if ( pos[2] > this->FixedPointCroppingRegionPlanes[5] )
731  {
732  idx = 18;
733  }
734  else
735  {
736  idx = 9;
737  }
738 
739  if ( pos[1] >= this->FixedPointCroppingRegionPlanes[2] )
740  {
741  if ( pos[1] > this->FixedPointCroppingRegionPlanes[3] )
742  {
743  idx += 6;
744  }
745  else
746  {
747  idx += 3;
748  }
749  }
750 
751  if ( pos[0] >= this->FixedPointCroppingRegionPlanes[0] )
752  {
753  if ( pos[0] > this->FixedPointCroppingRegionPlanes[1] )
754  {
755  idx += 2;
756  }
757  else
758  {
759  idx += 1;
760  }
761  }
762 
763  return !(static_cast<unsigned int>(this->CroppingRegionFlags)
764  &this->CroppingRegionMask[idx]);
765 }
766 
767 #endif