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 "vtkVolumeMapper.h"
68 
69 #define VTKKW_FP_SHIFT 15
70 #define VTKKW_FPMM_SHIFT 17
71 #define VTKKW_FP_MASK 0x7fff
72 #define VTKKW_FP_SCALE 32767.0
73 
74 class vtkMatrix4x4;
75 class vtkMultiThreader;
76 class vtkPlaneCollection;
77 class vtkRenderer;
78 class vtkTimerLog;
79 class vtkVolume;
80 class vtkTransform;
81 class vtkRenderWindow;
95 class vtkDataArray;
96 
97 //BTX
98 // Forward declaration needed for use by friend declaration below.
101 //ETX
102 
104 {
105 public:
108  void PrintSelf( ostream& os, vtkIndent indent );
109 
111 
114  vtkSetMacro( SampleDistance, float );
115  vtkGetMacro( SampleDistance, float );
117 
119 
125  vtkSetMacro( InteractiveSampleDistance, float );
126  vtkGetMacro( InteractiveSampleDistance, float );
128 
130 
135  vtkSetClampMacro( ImageSampleDistance, float, 0.1f, 100.0f );
136  vtkGetMacro( ImageSampleDistance, float );
138 
140 
142  vtkSetClampMacro( MinimumImageSampleDistance, float, 0.1f, 100.0f );
143  vtkGetMacro( MinimumImageSampleDistance, float );
145 
147 
149  vtkSetClampMacro( MaximumImageSampleDistance, float, 0.1f, 100.0f );
150  vtkGetMacro( MaximumImageSampleDistance, float );
152 
154 
161  vtkSetClampMacro( AutoAdjustSampleDistances, int, 0, 1 );
162  vtkGetMacro( AutoAdjustSampleDistances, int );
163  vtkBooleanMacro( AutoAdjustSampleDistances, int );
165 
167 
174  vtkSetClampMacro( LockSampleDistanceToInputSpacing, int, 0, 1 );
175  vtkGetMacro( LockSampleDistanceToInputSpacing, int );
176  vtkBooleanMacro( LockSampleDistanceToInputSpacing, int );
178 
180 
182  void SetNumberOfThreads( int num );
183  int GetNumberOfThreads();
185 
187 
189  vtkSetClampMacro( IntermixIntersectingGeometry, int, 0, 1 );
190  vtkGetMacro( IntermixIntersectingGeometry, int );
191  vtkBooleanMacro( IntermixIntersectingGeometry, int );
193 
195 
201  float ComputeRequiredImageSampleDistance( float desiredTime,
202  vtkRenderer *ren );
203  float ComputeRequiredImageSampleDistance( float desiredTime,
204  vtkRenderer *ren,
205  vtkVolume *vol );
207 
208 //BTX
211  void Render( vtkRenderer *, vtkVolume * );
212 
213  unsigned int ToFixedPointPosition( float val );
214  void ToFixedPointPosition( float in[3], unsigned int out[3] );
215  unsigned int ToFixedPointDirection( float dir );
216  void ToFixedPointDirection( float in[3], unsigned int out[3] );
217  void FixedPointIncrement( unsigned int position[3], unsigned int increment[3] );
218  void GetFloatTripleFromPointer( float v[3], float *ptr );
219  void GetUIntTripleFromPointer( unsigned int v[3], unsigned int *ptr );
220  void ShiftVectorDown( unsigned int in[3], unsigned int out[3] );
221  int CheckMinMaxVolumeFlag( unsigned int pos[3], int c );
222  int CheckMIPMinMaxVolumeFlag( unsigned int pos[3], int c, unsigned short maxIdx, int flip );
223 
224  void LookupColorUC( unsigned short *colorTable,
225  unsigned short *scalarOpacityTable,
226  unsigned short index,
227  unsigned char color[4] );
228  void LookupDependentColorUC( unsigned short *colorTable,
229  unsigned short *scalarOpacityTable,
230  unsigned short index[4],
231  int components,
232  unsigned char color[4] );
233  void LookupAndCombineIndependentColorsUC(
234  unsigned short *colorTable[4],
235  unsigned short *scalarOpacityTable[4],
236  unsigned short index[4],
237  float weights[4],
238  int components,
239  unsigned char color[4] );
240  int CheckIfCropped( unsigned int pos[3] );
241 
242 //ETX
243 
244  vtkGetObjectMacro( RenderWindow, vtkRenderWindow );
245  vtkGetObjectMacro( MIPHelper, vtkFixedPointVolumeRayCastMIPHelper );
246  vtkGetObjectMacro( CompositeHelper, vtkFixedPointVolumeRayCastCompositeHelper );
247  vtkGetObjectMacro( CompositeGOHelper, vtkFixedPointVolumeRayCastCompositeGOHelper );
248  vtkGetObjectMacro( CompositeGOShadeHelper, vtkFixedPointVolumeRayCastCompositeGOShadeHelper );
249  vtkGetObjectMacro( CompositeShadeHelper, vtkFixedPointVolumeRayCastCompositeShadeHelper );
250  vtkGetVectorMacro( TableShift, float, 4 );
251  vtkGetVectorMacro( TableScale, float, 4 );
252  vtkGetMacro( ShadingRequired, int );
253  vtkGetMacro( GradientOpacityRequired, int );
254 
255  vtkGetObjectMacro( CurrentScalars, vtkDataArray );
256  vtkGetObjectMacro( PreviousScalars, vtkDataArray );
257 
258 
259  int *GetRowBounds() {return this->RowBounds;}
260  unsigned short *GetColorTable(int c) {return this->ColorTable[c];}
261  unsigned short *GetScalarOpacityTable(int c) {return this->ScalarOpacityTable[c];}
262  unsigned short *GetGradientOpacityTable(int c) {return this->GradientOpacityTable[c];}
263  vtkVolume *GetVolume() {return this->Volume;}
264  unsigned short **GetGradientNormal() {return this->GradientNormal;}
265  unsigned char **GetGradientMagnitude() {return this->GradientMagnitude;}
266  unsigned short *GetDiffuseShadingTable(int c) {return this->DiffuseShadingTable[c];}
267  unsigned short *GetSpecularShadingTable(int c) {return this->SpecularShadingTable[c];}
268 
269  void ComputeRayInfo( int x, int y,
270  unsigned int pos[3],
271  unsigned int dir[3],
272  unsigned int *numSteps );
273 
274  void InitializeRayInfo( vtkVolume *vol );
275 
276  int ShouldUseNearestNeighborInterpolation( vtkVolume *vol );
277 
279 
282  void SetRayCastImage( vtkFixedPointRayCastImage * );
283  vtkGetObjectMacro( RayCastImage, vtkFixedPointRayCastImage );
285 
286  int PerImageInitialization( vtkRenderer *, vtkVolume *, int,
287  double *, double *, int * );
288  void PerVolumeInitialization( vtkRenderer *, vtkVolume * );
289  void PerSubVolumeInitialization( vtkRenderer *, vtkVolume *, int );
290  void RenderSubVolume();
291  void DisplayRenderedImage( vtkRenderer *, vtkVolume * );
292  void AbortRender();
293 
294  void CreateCanonicalView( vtkVolume *volume,
296  int blend_mode,
297  double viewDirection[3],
298  double viewUp[3] );
299 
301 
306  vtkVolume *vol )
307  { return this->RetrieveRenderTime( ren, vol ); }
309  { return this->RetrieveRenderTime( ren ); }
311 
312 
314 
320  vtkSetMacro( FinalColorWindow, float );
321  vtkGetMacro( FinalColorWindow, float );
322  vtkSetMacro( FinalColorLevel, float );
323  vtkGetMacro( FinalColorLevel, float );
325 
326 
327  // Here to be used by the mapper to tell the helper
328  // to flip the MIP comparison in order to support
329  // minimum intensity blending
330  vtkGetMacro( FlipMIPComparison, int );
331 
332 protected:
335 
336  // The helper class that displays the image
338 
339  // The distance between sample points along the ray
342 
343  // The distance between rays in the image
349 
350  // Saved values used to restore
353 
354  // Internal method for computing matrices needed during
355  // ray casting
356  void ComputeMatrices( double volumeOrigin[3],
357  double volumeSpacing[3],
358  int volumeExtent[6],
359  vtkRenderer *ren,
360  vtkVolume *vol );
361 
362  int ComputeRowBounds( vtkRenderer *ren,
363  int imageFlag, int rowBoundsFlag,
364  int volumeExtent[6]);
365 
366  void CaptureZBuffer( vtkRenderer *ren );
367 
370 
372 
379 
381 
385 
386  // This object encapsulated the image and all related information
388 
389  int *RowBounds;
391 
397 
398  void StoreRenderTime( vtkRenderer *ren, vtkVolume *vol, float t );
399  float RetrieveRenderTime( vtkRenderer *ren, vtkVolume *vol );
400  float RetrieveRenderTime( vtkRenderer *ren );
401 
403 
405 
406  vtkColorTransferFunction *SavedRGBFunction[4];
407  vtkPiecewiseFunction *SavedGrayFunction[4];
408  vtkPiecewiseFunction *SavedScalarOpacityFunction[4];
409  vtkPiecewiseFunction *SavedGradientOpacityFunction[4];
410  int SavedColorChannels[4];
411  float SavedScalarOpacityDistance[4];
415 
418 
420 
421 
422  unsigned short ColorTable[4][32768*3];
423  unsigned short ScalarOpacityTable[4][32768];
424  unsigned short GradientOpacityTable[4][256];
425  int TableSize[4];
426  float TableScale[4];
427  float TableShift[4];
428 
429  float GradientMagnitudeScale[4];
430  float GradientMagnitudeShift[4];
431 
432  unsigned short **GradientNormal;
433  unsigned char **GradientMagnitude;
434  unsigned short *ContiguousGradientNormal;
436 
438 
440 
442 
444 
445  unsigned short DiffuseShadingTable [4][65536*3];
446  unsigned short SpecularShadingTable[4][65536*3];
447 
450 
453 
456 
457  int ClipRayAgainstVolume( float rayStart[3],
458  float rayEnd[3],
459  float rayDirection[3],
460  double bounds[6] );
461 
462  int UpdateColorTable( vtkVolume *vol );
463  int UpdateGradients( vtkVolume *vol );
464  int UpdateShadingTable( vtkRenderer *ren,
465  vtkVolume *vol );
466  void UpdateCroppingRegions();
467 
468  void ComputeGradients( vtkVolume *vol );
469 
470  int ClipRayAgainstClippingPlanes( float rayStart[3],
471  float rayEnd[3],
472  int numClippingPlanes,
473  float *clippingPlanes );
474 
475  unsigned int FixedPointCroppingRegionPlanes[6];
476  unsigned int CroppingRegionMask[27];
477 
478  // Get the ZBuffer value corresponding to location (x,y) where (x,y)
479  // are indexing into the ImageInUse image. This must be converted to
480  // the zbuffer image coordinates. Nearest neighbor value is returned.
481  float GetZBufferValue( int x, int y );
482 
488 
489  // Some variables used for ray computation
490  float ViewToVoxelsArray[16];
491  float WorldToVoxelsArray[16];
492  float VoxelsToWorldArray[16];
493 
494  double CroppingBounds[6];
495 
498 
499  double SavedSpacing[3];
500 
501 
502  // Min Max structure used to do space leaping
503  unsigned short *MinMaxVolume;
504  int MinMaxVolumeSize[4];
508 
509  void UpdateMinMaxVolume( vtkVolume *vol );
510  void FillInMaxGradientMagnitudes( int fullDim[3],
511  int smallDim[3] );
512 
515 
517 
518  void ApplyFinalColorWindowLevel();
519 
520 private:
522  void operator=(const vtkFixedPointVolumeRayCastMapper&); // Not implemented.
523 };
524 
525 
527 {
528  return static_cast<unsigned int>(val * VTKKW_FP_SCALE + 0.5);
529 }
530 
531 inline void vtkFixedPointVolumeRayCastMapper::ToFixedPointPosition( float in[3], unsigned int out[3] )
532 {
533  out[0] = static_cast<unsigned int>(in[0] * VTKKW_FP_SCALE + 0.5);
534  out[1] = static_cast<unsigned int>(in[1] * VTKKW_FP_SCALE + 0.5);
535  out[2] = static_cast<unsigned int>(in[2] * VTKKW_FP_SCALE + 0.5);
536 }
537 
539 {
540  return ((dir<0.0)?
541  (static_cast<unsigned int>(-dir * VTKKW_FP_SCALE + 0.5)):
542  (0x80000000+static_cast<unsigned int>(dir*VTKKW_FP_SCALE + 0.5)));
543 }
544 
545 inline void vtkFixedPointVolumeRayCastMapper::ToFixedPointDirection( float in[3], unsigned int out[3] )
546 {
547  out[0] = ((in[0]<0.0)?
548  (static_cast<unsigned int>(-in[0] * VTKKW_FP_SCALE + 0.5)):
549  (0x80000000+
550  static_cast<unsigned int>(in[0]*VTKKW_FP_SCALE + 0.5)));
551  out[1] = ((in[1]<0.0)?
552  (static_cast<unsigned int>(-in[1] * VTKKW_FP_SCALE + 0.5)):
553  (0x80000000+
554  static_cast<unsigned int>(in[1]*VTKKW_FP_SCALE + 0.5)));
555  out[2] = ((in[2]<0.0)?
556  (static_cast<unsigned int>(-in[2] * VTKKW_FP_SCALE + 0.5)):
557  (0x80000000+
558  static_cast<unsigned int>(in[2]*VTKKW_FP_SCALE + 0.5)));
559 }
560 
561 inline void vtkFixedPointVolumeRayCastMapper::FixedPointIncrement( unsigned int position[3], unsigned int increment[3] )
562 {
563  if ( increment[0]&0x80000000 )
564  {
565  position[0] += (increment[0]&0x7fffffff);
566  }
567  else
568  {
569  position[0] -= increment[0];
570  }
571  if ( increment[1]&0x80000000 )
572  {
573  position[1] += (increment[1]&0x7fffffff);
574  }
575  else
576  {
577  position[1] -= increment[1];
578  }
579  if ( increment[2]&0x80000000 )
580  {
581  position[2] += (increment[2]&0x7fffffff);
582  }
583  else
584  {
585  position[2] -= increment[2];
586  }
587 }
588 
589 
591 {
592  v[0] = *(ptr);
593  v[1] = *(ptr+1);
594  v[2] = *(ptr+2);
595 }
596 
597 inline void vtkFixedPointVolumeRayCastMapper::GetUIntTripleFromPointer( unsigned int v[3], unsigned int *ptr )
598 {
599  v[0] = *(ptr);
600  v[1] = *(ptr+1);
601  v[2] = *(ptr+2);
602 }
603 
605  unsigned int out[3] )
606 {
607  out[0] = in[0] >> VTKKW_FP_SHIFT;
608  out[1] = in[1] >> VTKKW_FP_SHIFT;
609  out[2] = in[2] >> VTKKW_FP_SHIFT;
610 }
611 
612 inline int vtkFixedPointVolumeRayCastMapper::CheckMinMaxVolumeFlag( unsigned int mmpos[3], int c )
613 {
614  unsigned int offset =
615  static_cast<unsigned int>(this->MinMaxVolumeSize[3]) *
616  ( mmpos[2]*static_cast<unsigned int>(
617  this->MinMaxVolumeSize[0]*this->MinMaxVolumeSize[1]) +
618  mmpos[1]*static_cast<unsigned int>(this->MinMaxVolumeSize[0]) +
619  mmpos[0] ) + static_cast<unsigned int>(c);
620 
621  return ((*(this->MinMaxVolume + 3*offset + 2))&0x00ff);
622 }
623 
624 inline int vtkFixedPointVolumeRayCastMapper::CheckMIPMinMaxVolumeFlag( unsigned int mmpos[3], int c,
625  unsigned short maxIdx, int flip )
626 {
627  unsigned int offset =
628  static_cast<unsigned int>(this->MinMaxVolumeSize[3]) *
629  ( mmpos[2]*static_cast<unsigned int>(
630  this->MinMaxVolumeSize[0]*this->MinMaxVolumeSize[1]) +
631  mmpos[1]*static_cast<unsigned int>(this->MinMaxVolumeSize[0]) +
632  mmpos[0] ) + static_cast<unsigned int>(c);
633 
634  if ( (*(this->MinMaxVolume + 3*offset + 2)&0x00ff) )
635  {
636  if (flip)
637  {
638  return ( *(this->MinMaxVolume + 3*offset) < maxIdx );
639  }
640  else
641  {
642  return ( *(this->MinMaxVolume + 3*offset + 1) > maxIdx );
643  }
644  }
645  else
646  {
647  return 0;
648  }
649 }
650 
651 inline void vtkFixedPointVolumeRayCastMapper::LookupColorUC( unsigned short *colorTable,
652  unsigned short *scalarOpacityTable,
653  unsigned short index,
654  unsigned char color[4] )
655 {
656  unsigned short alpha = scalarOpacityTable[index];
657  color[0] = static_cast<unsigned char>
658  ((colorTable[3*index ]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
659  color[1] = static_cast<unsigned char>
660  ((colorTable[3*index+1]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
661  color[2] = static_cast<unsigned char>
662  ((colorTable[3*index+2]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
663  color[3] = static_cast<unsigned char>(alpha>>(VTKKW_FP_SHIFT - 8));
664 }
665 
666 inline void vtkFixedPointVolumeRayCastMapper::LookupDependentColorUC( unsigned short *colorTable,
667  unsigned short *scalarOpacityTable,
668  unsigned short index[4],
669  int components,
670  unsigned char color[4] )
671 {
672  unsigned short alpha;
673  switch ( components )
674  {
675  case 2:
676  alpha = scalarOpacityTable[index[1]];
677  color[0] = static_cast<unsigned char>
678  ((colorTable[3*index[0] ]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
679  color[1] = static_cast<unsigned char>
680  ((colorTable[3*index[0]+1]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
681  color[2] = static_cast<unsigned char>
682  ((colorTable[3*index[0]+2]*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
683  color[3] = static_cast<unsigned char>(alpha>>(VTKKW_FP_SHIFT - 8));
684  break;
685  case 4:
686  alpha = scalarOpacityTable[index[3]];
687  color[0] = static_cast<unsigned char>((index[0]*alpha + 0x7fff)>>VTKKW_FP_SHIFT );
688  color[1] = static_cast<unsigned char>((index[1]*alpha + 0x7fff)>>VTKKW_FP_SHIFT );
689  color[2] = static_cast<unsigned char>((index[2]*alpha + 0x7fff)>>VTKKW_FP_SHIFT );
690  color[3] = static_cast<unsigned char>(alpha>>(VTKKW_FP_SHIFT - 8));
691  break;
692  }
693 }
694 
695 
697  unsigned short *scalarOpacityTable[4],
698  unsigned short index[4],
699  float weights[4],
700  int components,
701  unsigned char color[4] )
702 {
703  unsigned int tmp[4] = {0,0,0,0};
704 
705  for ( int i = 0; i < components; i++ )
706  {
707  unsigned short alpha = static_cast<unsigned short>(static_cast<float>(scalarOpacityTable[i][index[i]])*weights[i]);
708  tmp[0] += static_cast<unsigned char>(((colorTable[i][3*index[i] ])*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
709  tmp[1] += static_cast<unsigned char>(((colorTable[i][3*index[i]+1])*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
710  tmp[2] += static_cast<unsigned char>(((colorTable[i][3*index[i]+2])*alpha + 0x7fff)>>(2*VTKKW_FP_SHIFT - 8));
711  tmp[3] += static_cast<unsigned char>(alpha>>(VTKKW_FP_SHIFT - 8));
712  }
713 
714  color[0] = static_cast<unsigned char>((tmp[0]>255)?(255):(tmp[0]));
715  color[1] = static_cast<unsigned char>((tmp[1]>255)?(255):(tmp[1]));
716  color[2] = static_cast<unsigned char>((tmp[2]>255)?(255):(tmp[2]));
717  color[3] = static_cast<unsigned char>((tmp[3]>255)?(255):(tmp[3]));
718 
719 }
720 
721 inline int vtkFixedPointVolumeRayCastMapper::CheckIfCropped( unsigned int pos[3] )
722 {
723  int idx;
724 
725  if ( pos[2] < this->FixedPointCroppingRegionPlanes[4] )
726  {
727  idx = 0;
728  }
729  else if ( pos[2] > this->FixedPointCroppingRegionPlanes[5] )
730  {
731  idx = 18;
732  }
733  else
734  {
735  idx = 9;
736  }
737 
738  if ( pos[1] >= this->FixedPointCroppingRegionPlanes[2] )
739  {
740  if ( pos[1] > this->FixedPointCroppingRegionPlanes[3] )
741  {
742  idx += 6;
743  }
744  else
745  {
746  idx += 3;
747  }
748  }
749 
750  if ( pos[0] >= this->FixedPointCroppingRegionPlanes[0] )
751  {
752  if ( pos[0] > this->FixedPointCroppingRegionPlanes[1] )
753  {
754  idx += 2;
755  }
756  else
757  {
758  idx += 1;
759  }
760  }
761 
762  return !(static_cast<unsigned int>(this->CroppingRegionFlags)
763  &this->CroppingRegionMask[idx]);
764 }
765 
766 #endif