1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkGPUVolumeRayCastMapper.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 =========================================================================*/
15 /**
16  * @class   vtkGPUVolumeRayCastMapper
17  * @brief   Ray casting performed on the GPU.
18  *
19  * vtkGPUVolumeRayCastMapper is a volume mapper that performs ray casting on
20  * the GPU using fragment programs.
21  *
22  * This mapper supports connections in multiple ports of input 0 (port 0 being
23  * the only required connection). It is up to the concrete implementation
24  * whether additional inputs will be used during rendering. This class maintains
25  * a list of the currently active input ports (Ports) as well as a list of the
26  * ports that have been disconnected (RemovedPorts). RemovedPorts is used the
27  * the concrete implementation to clean up internal structures.
28  *
29  */
30 #ifndef vtkGPUVolumeRayCastMapper_h
31 #define vtkGPUVolumeRayCastMapper_h
32 #include <unordered_map>              // For std::unordered_map
33 #include <vector>                     // For std::vector
34 
35 #include <vtkRenderingVolumeModule.h> // For export macro
36 #include "vtkVolumeMapper.h"
37 
38 
39 class vtkContourValues;
40 class vtkRenderWindow;
41 class vtkVolumeProperty;
42 
43 class VTKRENDERINGVOLUME_EXPORT vtkGPUVolumeRayCastMapper : public vtkVolumeMapper
44 {
45 public:
46   static vtkGPUVolumeRayCastMapper *New();
47   vtkTypeMacro(vtkGPUVolumeRayCastMapper,vtkVolumeMapper);
48   void PrintSelf( ostream& os, vtkIndent indent ) override;
49 
50   //@{
51   /**
52    * If AutoAdjustSampleDistances is on, the ImageSampleDistance
53    * will be varied to achieve the allocated render time of this
54    * prop (controlled by the desired update rate and any culling in
55    * use).
56    */
57   vtkSetClampMacro( AutoAdjustSampleDistances, vtkTypeBool, 0, 1 );
58   vtkGetMacro( AutoAdjustSampleDistances, vtkTypeBool );
59   vtkBooleanMacro( AutoAdjustSampleDistances, vtkTypeBool );
60   //@}
61 
62   //@{
63   /**
64    * Compute the sample distance from the data spacing.  When the number of
65    * voxels is 8, the sample distance will be roughly 1/200 the average voxel
66    * size. The distance will grow proportionally to numVoxels^(1/3). Off by default.
67    */
68   vtkSetClampMacro( LockSampleDistanceToInputSpacing, vtkTypeBool, 0, 1 );
69   vtkGetMacro( LockSampleDistanceToInputSpacing, vtkTypeBool );
70   vtkBooleanMacro( LockSampleDistanceToInputSpacing, vtkTypeBool );
71   //@}
72 
73   //@{
74   /**
75    * If UseJittering is on, each ray traversal direction will be
76    * perturbed slightly using a noise-texture to get rid of wood-grain
77    * effect.
78    */
79   vtkSetClampMacro( UseJittering, vtkTypeBool, 0, 1 );
80   vtkGetMacro( UseJittering, vtkTypeBool );
81   vtkBooleanMacro( UseJittering, vtkTypeBool );
82   //@}
83 
84   //@{
85   /**
86    * If UseDepthPass is on, the mapper will use two passes. In the first
87    * pass, an isocontour depth buffer will be utilized as starting point
88    * for ray-casting hence eliminating traversal on voxels that are
89    * not going to participate in final rendering. UseDepthPass requires
90    * reasonable contour values to be set which can be set by calling
91    * GetDepthPassContourValues() method and using vtkControurValues API.
92    */
93   vtkSetClampMacro( UseDepthPass, vtkTypeBool, 0, 1 );
94   vtkGetMacro( UseDepthPass, vtkTypeBool );
95   vtkBooleanMacro( UseDepthPass, vtkTypeBool );
96   //@}
97 
98   /**
99    * Return handle to contour values container so
100    * that values can be set by the application. Contour values
101    * will be used only when UseDepthPass is on.
102    */
103   vtkContourValues* GetDepthPassContourValues();
104 
105   //@{
106   /**
107    * Set/Get the distance between samples used for rendering
108    * when AutoAdjustSampleDistances is off, or when this mapper
109    * has more than 1 second allocated to it for rendering.
110    * Initial value is 1.0.
111    */
112   vtkSetMacro( SampleDistance, float );
113   vtkGetMacro( SampleDistance, float );
114   //@}
115 
116   //@{
117   /**
118    * Sampling distance in the XY image dimensions. Default value of 1 meaning
119    * 1 ray cast per pixel. If set to 0.5, 4 rays will be cast per pixel. If
120    * set to 2.0, 1 ray will be cast for every 4 (2 by 2) pixels. This value
121    * will be adjusted to meet a desired frame rate when AutoAdjustSampleDistances
122    * is on.
123    */
124   vtkSetClampMacro( ImageSampleDistance, float, 0.1f, 100.0f );
125   vtkGetMacro( ImageSampleDistance, float );
126   //@}
127 
128   //@{
129   /**
130    * This is the minimum image sample distance allow when the image
131    * sample distance is being automatically adjusted.
132    */
133   vtkSetClampMacro( MinimumImageSampleDistance, float, 0.1f, 100.0f );
134   vtkGetMacro( MinimumImageSampleDistance, float );
135   //@}
136 
137   //@{
138   /**
139    * This is the maximum image sample distance allow when the image
140    * sample distance is being automatically adjusted.
141    */
142   vtkSetClampMacro( MaximumImageSampleDistance, float, 0.1f, 100.0f );
143   vtkGetMacro( MaximumImageSampleDistance, float );
144   //@}
145 
146 
147   //@{
148   /**
149    * Set/Get the window / level applied to the final color.
150    * This allows brightness / contrast adjustments on the
151    * final image.
152    * window is the width of the window.
153    * level is the center of the window.
154    * Initial window value is 1.0
155    * Initial level value is 0.5
156    * window cannot be null but can be negative, this way
157    * values will be reversed.
158    * |window| can be larger than 1.0
159    * level can be any real value.
160    */
161   vtkSetMacro( FinalColorWindow, float );
162   vtkGetMacro( FinalColorWindow, float );
163   vtkSetMacro( FinalColorLevel,  float );
164   vtkGetMacro( FinalColorLevel,  float );
165   //@}
166 
167   //@{
168   /**
169    * Maximum size of the 3D texture in GPU memory.
170    * Will default to the size computed from the graphics
171    * card. Can be adjusted by the user.
172    */
173   vtkSetMacro( MaxMemoryInBytes, vtkIdType );
174   vtkGetMacro( MaxMemoryInBytes, vtkIdType );
175   //@}
176 
177   //@{
178   /**
179    * Maximum fraction of the MaxMemoryInBytes that should
180    * be used to hold the texture. Valid values are 0.1 to
181    * 1.0.
182    */
183   vtkSetClampMacro( MaxMemoryFraction, float, 0.1f, 1.0f );
184   vtkGetMacro( MaxMemoryFraction, float );
185   //@}
186 
187   //@{
188   /**
189    * Tells if the mapper will report intermediate progress.
190    * Initial value is true. As the progress works with a GL blocking
191    * call (glFinish()), this can be useful for huge dataset but can
192    * slow down rendering of small dataset. It should be set to true
193    * for big dataset or complex shading and streaming but to false for
194    * small datasets.
195    */
196   vtkSetMacro(ReportProgress,bool);
197   vtkGetMacro(ReportProgress,bool);
198   //@}
199 
200   /**
201    * Based on hardware and properties, we may or may not be able to
202    * render using 3D texture mapping. This indicates if 3D texture
203    * mapping is supported by the hardware, and if the other extensions
204    * necessary to support the specific properties are available.
205    */
IsRenderSupported(vtkRenderWindow * vtkNotUsed (window),vtkVolumeProperty * vtkNotUsed (property))206   virtual int IsRenderSupported(vtkRenderWindow *vtkNotUsed(window),
207                                 vtkVolumeProperty *vtkNotUsed(property))
208   {
209       return 0;
210   }
211 
212   void CreateCanonicalView( vtkRenderer *ren,
213                             vtkVolume *volume,
214                             vtkImageData *image,
215                             int blend_mode,
216                             double viewDirection[3],
217                             double viewUp[3] );
218 
219   //@{
220   /**
221    * Optionally, set a mask input. This mask may be a binary mask or a label
222    * map. This must be specified via SetMaskType.
223 
224    * If the mask is a binary mask, the volume rendering is confined to regions
225    * within the binary mask. The binary mask is assumed to have a datatype of
226    * UCHAR and values of 255 (inside) and 0 (outside).
227 
228    * The mask may also be a label map. The label map is allowed to contain only
229    * 3 labels (values of 0, 1 and 2) and must have a datatype of UCHAR. In voxels
230    * with label value of 0, the color transfer function supplied by component
231    * 0 is used.
232    * In voxels with label value of 1, the color transfer function supplied by
233    * component 1 is used and blended with the transfer function supplied by
234    * component 0, with the blending weight being determined by
235    * MaskBlendFactor.
236    * In voxels with a label value of 2, the color transfer function supplied
237    * by component 2 is used and blended with the transfer function supplied by
238    * component 0, with the blending weight being determined by
239    * MaskBlendFactor.
240    */
241   void SetMaskInput(vtkImageData *mask);
242   vtkGetObjectMacro(MaskInput, vtkImageData);
243   //@}
244 
245   enum { BinaryMaskType = 0, LabelMapMaskType };
246 
247   //@{
248   /**
249    * Set the mask type, if mask is to be used. See documentation for
250    * SetMaskInput(). The default is a LabelMapMaskType.
251    */
252   vtkSetMacro( MaskType, int );
253   vtkGetMacro( MaskType, int );
254   void SetMaskTypeToBinary();
255   void SetMaskTypeToLabelMap();
256   //@}
257 
258   //@{
259   /**
260    * Tells how much mask color transfer function is used compared to the
261    * standard color transfer function when the mask is true. This is relevant
262    * only for the label map mask.
263    * 0.0 means only standard color transfer function.
264    * 1.0 means only mask color transfer function.
265    * The default value is 1.0.
266    */
267   vtkSetClampMacro(MaskBlendFactor,float,0.0f,1.0f);
268   vtkGetMacro(MaskBlendFactor,float);
269   //@}
270 
271   //@{
272   /**
273    * Enable or disable setting output of volume rendering to be
274    * color and depth textures. By default this is set to 0 (off).
275    * It should be noted that it is possible that underlying API specific
276    * mapper may not supoport RenderToImage mode.
277    * \warning
278    * \li This method ignores any other volumes / props in the scene.
279    * \li This method does not respect the general attributes of the
280    * scene i.e. background color, etc. It always produces a color
281    * image that has a transparent white background outside the
282    * bounds of the volume.
283 
284    * \sa GetDepthImage(), GetColorImage()
285    */
286   vtkSetMacro(RenderToImage, vtkTypeBool);
287   vtkGetMacro(RenderToImage, vtkTypeBool);
288   vtkBooleanMacro(RenderToImage, vtkTypeBool);
289   //@}
290 
291   //@{
292   /**
293    * Set/Get the scalar type of the depth texture in RenderToImage mode.
294    * By default, the type if VTK_FLOAT.
295    * \sa SetRenderToImage()
296    */
297   vtkSetMacro(DepthImageScalarType, int);
298   vtkGetMacro(DepthImageScalarType, int);
299   void SetDepthImageScalarTypeToUnsignedChar();
300   void SetDepthImageScalarTypeToUnsignedShort();
301   void SetDepthImageScalarTypeToFloat();
302   //@}
303 
304   //@{
305   /**
306    * Enable or disable clamping the depth value of the fully
307    * transparent voxel to the depth of the back-face of the
308    * volume. This parameter is used when RenderToImage mode is
309    * enabled. When ClampDepthToBackFace is false, the fully transparent
310    * voxels will have a value of 1.0 in the depth image. When
311    * this is true, the fully transparent voxels will have the
312    * depth value of the face at which the ray exits the volume.
313    * By default, this is set to 0 (off).
314    * \sa SetRenderToImage(), GetDepthImage()
315    */
316   vtkSetMacro(ClampDepthToBackface, vtkTypeBool);
317   vtkGetMacro(ClampDepthToBackface, vtkTypeBool);
318   vtkBooleanMacro(ClampDepthToBackface, vtkTypeBool);
319   //@}
320 
321   /**
322    * Low level API to export the depth texture as vtkImageData in
323    * RenderToImage mode.
324    * Should be implemented by the graphics API specific mapper (GL or other).
325    * \sa SetRenderToImage()
326    */
GetDepthImage(vtkImageData *)327   virtual void GetDepthImage(vtkImageData*) {};
328 
329   /**
330    * Low level API to export the color texture as vtkImageData in
331    * RenderToImage mode.
332    * Should be implemented by the graphics API specific mapper (GL or other).
333    * \sa SetRenderToImage()
334    */
GetColorImage(vtkImageData *)335   virtual void GetColorImage(vtkImageData*) {};
336 
337   /**
338    * Initialize rendering for this volume.
339    * \warning INTERNAL METHOD - NOT INTENDED FOR GENERAL USE
340    */
341   void Render( vtkRenderer *, vtkVolume * ) override;
342 
343   /**
344    * Handled in the subclass - the actual render method
345    * \pre input is up-to-date.
346    */
GPURender(vtkRenderer *,vtkVolume *)347   virtual void GPURender( vtkRenderer *, vtkVolume *) {}
348 
349   /**
350    * Release any graphics resources that are being consumed by this mapper.
351    * The parameter window could be used to determine which graphic
352    * resources to release.
353    * \warning INTERNAL METHOD - NOT INTENDED FOR GENERAL USE
354    */
ReleaseGraphicsResources(vtkWindow *)355   void ReleaseGraphicsResources(vtkWindow *) override {}
356 
357   /**
358    * Return how much the dataset has to be reduced in each dimension to
359    * fit on the GPU. If the value is 1.0, there is no need to reduce the
360    * dataset.
361    * \pre the calling thread has a current OpenGL context.
362    * \pre mapper_supported: IsRenderSupported(renderer->GetRenderWindow(),0)
363    * The computation is based on hardware limits (3D texture indexable size)
364    * and MaxMemoryInBytes.
365    * \post valid_i_ratio: ratio[0]>0 && ratio[0]<=1.0
366    * \post valid_j_ratio: ratio[1]>0 && ratio[1]<=1.0
367    * \post valid_k_ratio: ratio[2]>0 && ratio[2]<=1.0
368    */
369   virtual void GetReductionRatio(double ratio[3])=0;
370 
371   enum TFRangeType
372   {
373     SCALAR = 0, // default
374     NATIVE
375   };
376 
377   //@{
378   /**
379    * Set whether to use the scalar range or the native transfer function range
380    * when looking up transfer functions for color and opacity values. When the
381    * range is set to TransferFunctionRange::SCALAR, the function is distributed
382    * over the entire scalar range. If it is set to
383    * TransferFunctionRange::NATIVE, the scalar values outside the native
384    * transfer function range will be truncated to native range. By
385    * default, the volume scalar range is used.
386    *
387    * \note The native range of the transfer function is the range returned by
388    * vtkColorTransferFunction::GetRange() or vtkPiecewiseFunction::GetRange().
389    *
390    * \note There is no special API provided for 2D transfer functions
391    * considering that they are set as a pre-generated vtkImageData on this
392    * class i.e. the range is already encoded.
393    */
394   vtkSetMacro(ColorRangeType, int);
395   vtkGetMacro(ColorRangeType, int);
396   vtkSetMacro(ScalarOpacityRangeType, int);
397   vtkGetMacro(ScalarOpacityRangeType, int);
398   vtkSetMacro(GradientOpacityRangeType, int);
399   vtkGetMacro(GradientOpacityRangeType, int);
400   //@}
401 
GetInput()402   vtkImageData* GetInput() override
403   {
404     return this->GetInput(0);
405   };
406 
407   //@{
408   /**
409    * Add/Remove input connections. Active and removed ports are cached in
410    * Ports and RemovedPorts respectively.
411    */
412   void RemoveInputConnection(int port, vtkAlgorithmOutput* input) override;
413   void RemoveInputConnection(int port, int idx) override;
414   void SetInputConnection(int port, vtkAlgorithmOutput* input) override;
SetInputConnection(vtkAlgorithmOutput * input)415   void SetInputConnection(vtkAlgorithmOutput* input) override
416   {
417     this->SetInputConnection(0, input);
418   }
419   //@}
420 
421   /**
422    * Number of currently active ports.
423    */
424   int GetInputCount();
425 
426   vtkImageData* GetTransformedInput(const int port = 0);
427 
428   double* GetBoundsFromPort(const int port) VTK_SIZEHINT(6);
429 
430 protected:
431   vtkGPUVolumeRayCastMapper();
432   ~vtkGPUVolumeRayCastMapper() override;
433 
434   /**
435    * Handle inputs. This mapper provides an interface to support multiple
436    * inputs but it is up to the OpenGL implementation use them during rendering.
437    * Currently, only VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper makes use
438    * of these inputs.
439    *
440    * \sa vtkOpenGLGPUVolumeRayCastMapper vtkMultiVolume
441    */
442   int FillInputPortInformation(int port, vtkInformation* info) override;
443 
444   /**
445    * A transformation is applied (translation) to the input.  The resulting
446    * data is stored in TransformedInputs. Takes as an argumet the port of an
447    * input connection.
448    *
449    * ///TODO Elaborate on why this is an issue, texture coords (?)
450    * @TODO: This is the workaround to deal with GPUVolumeRayCastMapper
451    * not able to handle extents starting from non zero values.
452    * There is not a easy fix in the GPU volume ray cast mapper hence
453    * this fix has been introduced.
454    */
455   void TransformInput(const int port);
456 
457   //@{
458   /**
459    * This method is used by the Render() method to validate everything before
460    * attempting to render. This method returns 0 if something is not right -
461    * such as missing input, a null renderer or a null volume, no scalars, etc.
462    * In some cases it will produce a vtkErrorMacro message, and in others
463    * (for example, in the case of cropping planes that define a region with
464    * a volume or 0 or less) it will fail silently. If everything is OK, it will
465    * return with a value of 1.
466    */
467   int ValidateRender( vtkRenderer *, vtkVolume * );
468   int ValidateInputs();
469   int ValidateInput(vtkVolumeProperty* property, const int port);
470   //@}
471 
472   //@{
473   /**
474    * Shallow-copy the inputs into a transform-adjusted clone.
475    * \sa vtkGPUVolumeRayCastMapper::TransformInput
476    */
477   void CloneInputs();
478   void CloneInput(vtkImageData* input, const int port);
479   //@}
480 
481   // Special version of render called during the creation
482   // of a canonical view.
483   void CanonicalViewRender( vtkRenderer *, vtkVolume * );
484 
485   // Methods called by the AMR Volume Mapper.
486   virtual void PreRender(vtkRenderer *ren,
487                          vtkVolume *vol,
488                          double datasetBounds[6],
489                          double scalarRange[2],
490                          int numberOfScalarComponents,
491                          unsigned int numberOfLevels)=0;
492 
493   // \pre input is up-to-date
494   virtual void RenderBlock(vtkRenderer *ren,
495                            vtkVolume *vol,
496                            unsigned int level)=0;
497 
498   virtual void PostRender(vtkRenderer *ren,
499                           int numberOfScalarComponents)=0;
500   vtkImageData* GetInput(const int port) override;
501 
502   /**
503    * Called by the AMR Volume Mapper.
504    * Set the flag that tells if the scalars are on point data (0) or
505    * cell data (1).
506    */
507   void SetCellFlag(int cellFlag);
508   void RemovePortInternal(const int port);
509 
510   vtkTypeBool LockSampleDistanceToInputSpacing;
511   vtkTypeBool    AutoAdjustSampleDistances;
512   float  ImageSampleDistance;
513   float  MinimumImageSampleDistance;
514   float  MaximumImageSampleDistance;
515 
516   // Render to texture mode flag
517   vtkTypeBool RenderToImage;
518 
519   // Depth image scalar type
520   int DepthImageScalarType;
521 
522   // Clamp depth values to the depth of the face at which the ray
523   // exits the volume
524   vtkTypeBool ClampDepthToBackface;
525 
526   // Enable / disable stochastic jittering
527   vtkTypeBool UseJittering;
528 
529   // Enable / disable two pass rendering
530   vtkTypeBool UseDepthPass;
531   vtkContourValues* DepthPassContourValues;
532 
533   // The distance between sample points along the ray
534   float  SampleDistance;
535 
536   int    SmallVolumeRender;
537   double BigTimeToDraw;
538   double SmallTimeToDraw;
539 
540   float FinalColorWindow;
541   float FinalColorLevel;
542 
543   // 1 if we are generating the canonical image, 0 otherwise
544   int   GeneratingCanonicalView;
545   vtkImageData *CanonicalViewImageData;
546 
547   //@{
548   /**
549    * Set the mapper in AMR Mode or not. Initial value is false.
550    * Called only by the vtkKWAMRVolumeMapper
551    */
552   vtkSetClampMacro(AMRMode,vtkTypeBool,0,1);
553   vtkGetMacro(AMRMode,vtkTypeBool);
554   vtkBooleanMacro(AMRMode,vtkTypeBool);
555   //@}
556 
557   vtkImageData * MaskInput;
558   float          MaskBlendFactor;
559   int            MaskType;
560 
561   vtkTypeBool AMRMode;
562 
563   // Transfer function range type
564   int ColorRangeType;
565   int ScalarOpacityRangeType;
566   int GradientOpacityRangeType;
567 
568   // Point data or cell data (or field data, not handled) ?
569   int CellFlag;
570 
571   /**
572    * Compute the cropping planes clipped by the bounds of the volume.
573    * The result is put into this->ClippedCroppingRegionPlanes.
574    * NOTE: IT WILL BE MOVED UP TO vtkVolumeMapper after bullet proof usage
575    * in this mapper. Other subclasses will use the ClippedCroppingRegionsPlanes
576    * members instead of CroppingRegionPlanes.
577    * \pre volume_exists: this->GetInput()!=0
578    * \pre valid_cropping: this->Cropping &&
579    * this->CroppingRegionPlanes[0]<this->CroppingRegionPlanes[1] &&
580    * this->CroppingRegionPlanes[2]<this->CroppingRegionPlanes[3] &&
581    * this->CroppingRegionPlanes[4]<this->CroppingRegionPlanes[5])
582    */
583   virtual void ClipCroppingRegionPlanes();
584 
585   using DataMap = std::unordered_map<int, vtkImageData*>;
586   void SetTransformedInput(vtkImageData*);
587   vtkImageData* FindData(int port, DataMap& container);
588 
589   double         ClippedCroppingRegionPlanes[6];
590 
591   vtkIdType MaxMemoryInBytes;
592   float MaxMemoryFraction;
593 
594   bool           ReportProgress;
595   std::vector<int> Ports;
596   std::vector<int> RemovedPorts;
597   DataMap TransformedInputs;
598 
599   /**
600    * This is needed only to check if the input data has been changed since the last
601    * Render() call.
602    */
603   DataMap LastInputs;
604 
605 private:
606   vtkGPUVolumeRayCastMapper(const vtkGPUVolumeRayCastMapper&) = delete;
607   void operator=(const vtkGPUVolumeRayCastMapper&) = delete;
608 };
609 
610 #endif
611