text: /*=========================================================================
  
    Program:   Visualization Toolkit
    Module:    vtkVolumeMapper.h
  
    Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
    All rights reserved.
    See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
  
       This software is distributed WITHOUT ANY WARRANTY; without even
       the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
       PURPOSE.  See the above copyright notice for more information.
  
  =========================================================================*/
  /**
   * @class   vtkVolumeMapper
   * @brief   Abstract class for a volume mapper
   *
   *
   * vtkVolumeMapper is the abstract definition of a volume mapper for regular
   * rectilinear data (vtkImageData).  Several  basic types of volume mappers
   * are supported.
  */
  
  #ifndef vtkVolumeMapper_h
  #define vtkVolumeMapper_h
  
  #include "vtkRenderingVolumeModule.h" // For export macro
  #include "vtkAbstractVolumeMapper.h"
  
  class vtkRenderer;
  class vtkVolume;
  class vtkImageData;
  
  #define VTK_CROP_SUBVOLUME              0x0002000
  #define VTK_CROP_FENCE                  0x2ebfeba
  #define VTK_CROP_INVERTED_FENCE         0x5140145
  #define VTK_CROP_CROSS                  0x0417410
  #define VTK_CROP_INVERTED_CROSS         0x7be8bef
  
  class vtkWindow;
  
  class VTKRENDERINGVOLUME_EXPORT vtkVolumeMapper : public vtkAbstractVolumeMapper
  {
  public:
    vtkTypeMacro(vtkVolumeMapper,vtkAbstractVolumeMapper);
    void PrintSelf( ostream& os, vtkIndent indent ) override;
  
    //@{
    /**
     * Set/Get the input data
     */
    virtual void SetInputData( vtkImageData * );
    virtual void SetInputData( vtkDataSet * );
    vtkImageData *GetInput();
    //@}
  
    //@{
    /**
     * Set/Get the blend mode.
     * The default mode is Composite where the scalar values are sampled through
     * the volume and composited in a front-to-back scheme through alpha blending.
     * The final color and opacity is determined using the color and opacity
     * transfer functions.
     *
     * Maximum and minimum intensity blend modes use the maximum and minimum
     * scalar values, respectively,  along the sampling ray. The final color and
     * opacity is determined by passing the resultant value through the color and
     * opacity transfer functions.
     *
     * Additive blend mode accumulates scalar values by passing each value through
     * the opacity transfer function and then adding up the product of the value
     * and its opacity. In other words, the scalar values are scaled using the
     * opacity transfer function and summed to derive the final color. Note that
     * the resulting image is always grayscale i.e. aggregated values are not
     * passed through the color transfer function. This is because the final
     * value is a derived value and not a real data value along the sampling ray.
     *
     * Average intensity blend mode works similar to the additive blend mode where
     * the scalar values are multiplied by opacity calculated from the opacity
     * transfer function and then added. The additional step here is to
     * divide the sum by the number of samples taken through the volume.
     * One can control the scalar range by setting the AverageIPScalarRange ivar
     * to disregard scalar values, not in the range of interest, from the average
     * computation.
     * As is the case with the additive intensity projection, the final
     * image will always be grayscale i.e. the aggregated values are not
     * passed through the color transfer function. This is because the
     * resultant value is a derived value and not a real data value along
     * the sampling ray.
     *
     * \note vtkVolumeMapper::AVERAGE_INTENSITY_BLEND is only supported by the
     * vtkGPUVolumeRayCastMapper with the OpenGL2 backend.
     * \sa SetAverageIPScalarRange()
     */
    vtkSetMacro( BlendMode, int );
    void SetBlendModeToComposite()
      { this->SetBlendMode( vtkVolumeMapper::COMPOSITE_BLEND ); }
    void SetBlendModeToMaximumIntensity()
      { this->SetBlendMode( vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND ); }
    void SetBlendModeToMinimumIntensity()
      { this->SetBlendMode( vtkVolumeMapper::MINIMUM_INTENSITY_BLEND ); }
    void SetBlendModeToAverageIntensity()
      { this->SetBlendMode( vtkVolumeMapper::AVERAGE_INTENSITY_BLEND ); }
    void SetBlendModeToAdditive()
      { this->SetBlendMode( vtkVolumeMapper::ADDITIVE_BLEND ); }
    vtkGetMacro( BlendMode, int );
    //@}
  
    //@{
    /**
     * Set/Get the scalar range to be considered for average intensity projection
     * blend mode. Only scalar values between this range will be averaged during
     * ray casting. This can be useful when volume rendering CT datasets where the
     * areas occupied by air would deviate the final rendering. By default, the
     * range is set to (VTK_DOUBLE_MIN, VTK_DOUBLE_MAX).
     * \sa SetBlendModeToAverageIntensity()
     */
    vtkSetVector2Macro(AverageIPScalarRange, double);
    vtkGetVectorMacro(AverageIPScalarRange, double, 2);
    //@}
  
    //@{
    /**
     * Turn On/Off orthogonal cropping. (Clipping planes are
     * perpendicular to the coordinate axes.)
     */
    vtkSetClampMacro(Cropping,int,0,1);
    vtkGetMacro(Cropping,int);
    vtkBooleanMacro(Cropping,int);
    //@}
  
    //@{
    /**
     * Set/Get the Cropping Region Planes ( xmin, xmax, ymin, ymax, zmin, zmax )
     * These planes are defined in volume coordinates - spacing and origin are
     * considered.
     */
    vtkSetVector6Macro( CroppingRegionPlanes, double );
    vtkGetVectorMacro(  CroppingRegionPlanes, double, 6 );
    //@}
  
    //@{
    /**
     * Get the cropping region planes in voxels. Only valid during the
     * rendering process
     */
    vtkGetVectorMacro( VoxelCroppingRegionPlanes, double, 6 );
    //@}
  
    //@{
    /**
     * Set the flags for the cropping regions. The clipping planes divide the
     * volume into 27 regions - there is one bit for each region. The regions
     * start from the one containing voxel (0,0,0), moving along the x axis
     * fastest, the y axis next, and the z axis slowest. These are represented
     * from the lowest bit to bit number 27 in the integer containing the
     * flags. There are several convenience functions to set some common
     * configurations - subvolume (the default), fence (between any of the
     * clip plane pairs), inverted fence, cross (between any two of the
     * clip plane pairs) and inverted cross.
     */
    vtkSetClampMacro( CroppingRegionFlags, int, 0x0, 0x7ffffff );
    vtkGetMacro( CroppingRegionFlags, int );
    void SetCroppingRegionFlagsToSubVolume()
      {this->SetCroppingRegionFlags( VTK_CROP_SUBVOLUME );};
    void SetCroppingRegionFlagsToFence()
      {this->SetCroppingRegionFlags( VTK_CROP_FENCE );};
    void SetCroppingRegionFlagsToInvertedFence()
      {this->SetCroppingRegionFlags( VTK_CROP_INVERTED_FENCE );};
    void SetCroppingRegionFlagsToCross()
      {this->SetCroppingRegionFlags( VTK_CROP_CROSS );};
    void SetCroppingRegionFlagsToInvertedCross()
      {this->SetCroppingRegionFlags( VTK_CROP_INVERTED_CROSS );};
    //@}
  
    /**
     * WARNING: INTERNAL METHOD - NOT INTENDED FOR GENERAL USE
     * DO NOT USE THIS METHOD OUTSIDE OF THE RENDERING PROCESS
     * Render the volume
     */
    void Render(vtkRenderer *ren, vtkVolume *vol) override =0;
  
    /**
     * WARNING: INTERNAL METHOD - NOT INTENDED FOR GENERAL USE
     * Release any graphics resources that are being consumed by this mapper.
     * The parameter window could be used to determine which graphic
     * resources to release.
     */
    void ReleaseGraphicsResources(vtkWindow *) override {}
  
    /**
     * Blend modes.
     * The default mode is Composite where the scalar values are sampled through
     * the volume and composited in a front-to-back scheme through alpha blending.
     * The final color and opacity is determined using the color and opacity
     * transfer functions.
     *
     * Maximum and minimum intensity blend modes use the maximum and minimum
     * scalar values, respectively,  along the sampling ray. The final color and
     * opacity is determined by passing the resultant value through the color and
     * opacity transfer functions.
     *
     * Additive blend mode accumulates scalar values by passing each value through
     * the opacity transfer function and then adding up the product of the value
     * and its opacity. In other words, the scalar values are scaled using the
     * opacity transfer function and summed to derive the final color. Note that
     * the resulting image is always grayscale i.e. aggregated values are not
     * passed through the color transfer function. This is because the final
     * value is a derived value and not a real data value along the sampling ray.
     *
     * Average intensity blend mode works similar to the additive blend mode where
     * the scalar values are multiplied by opacity calculated from the opacity
     * transfer function and then added. The additional step here is to
     * divide the sum by the number of samples taken through the volume.
     * As is the case with the additive intensity projection, the final
     * image will always be grayscale i.e. the aggregated values are not
     * passed through the color transfer function. This is because the
     * resultant value is a derived value and not a real data value along
     * the sampling ray.
     *
     * \note vtkVolumeMapper::AVERAGE_INTENSITY_BLEND is only supported by the
     * vtkGPUVolumeRayCastMapper with the OpenGL2 backend.
     */
    enum BlendModes
    {
      COMPOSITE_BLEND,
      MAXIMUM_INTENSITY_BLEND,
      MINIMUM_INTENSITY_BLEND,
      AVERAGE_INTENSITY_BLEND,
      ADDITIVE_BLEND
    };
  
  protected:
    vtkVolumeMapper();
    ~vtkVolumeMapper() override;
  
    /**
     * Compute a sample distance from the data spacing. When the number of
     * voxels is 8, the sample distance will be roughly 1/200 the average voxel
     * size. The distance will grow proportionally to numVoxels^(1/3).
     */
    double SpacingAdjustedSampleDistance(double inputSpacing[3],
                                         int inputExtent[6]);
  
    int   BlendMode;
  
    /**
     * Threshold range for average intensity projection
     */
    double AverageIPScalarRange[2];
  
    //@{
    /**
     * Cropping variables, and a method for converting the world
     * coordinate cropping region planes to voxel coordinates
     */
    int                  Cropping;
    double               CroppingRegionPlanes[6];
    double               VoxelCroppingRegionPlanes[6];
    int                  CroppingRegionFlags;
    void ConvertCroppingRegionPlanesToVoxels();
    //@}
  
    int FillInputPortInformation(int, vtkInformation*) override;
  
  private:
    vtkVolumeMapper(const vtkVolumeMapper&) = delete;
    void operator=(const vtkVolumeMapper&) = delete;
  };
  
  
  #endif
  
  
  