/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkFixedPointVolumeRayCastHelper.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   vtkFixedPointVolumeRayCastHelper
 * @brief   An abstract helper that generates images for the volume ray cast mapper
 *
 * This is the abstract superclass of all helper classes for the
 * vtkFixedPointVolumeRayCastMapper. This class should not be used directly.
 *
 * @sa
 * vtkFixedPointVolumeRayCastMapper
 */

#ifndef vtkFixedPointVolumeRayCastHelper_h
#define vtkFixedPointVolumeRayCastHelper_h

#define VTKKWRCHelper_GetCellScalarValues(DATA, SCALE, SHIFT)                                      \
  A = static_cast<unsigned int>(SCALE * (*(DATA) + SHIFT));                                        \
  B = static_cast<unsigned int>(SCALE * (*(DATA + Binc) + SHIFT));                                 \
  C = static_cast<unsigned int>(SCALE * (*(DATA + Cinc) + SHIFT));                                 \
  D = static_cast<unsigned int>(SCALE * (*(DATA + Dinc) + SHIFT));                                 \
  E = static_cast<unsigned int>(SCALE * (*(DATA + Einc) + SHIFT));                                 \
  F = static_cast<unsigned int>(SCALE * (*(DATA + Finc) + SHIFT));                                 \
  G = static_cast<unsigned int>(SCALE * (*(DATA + Ginc) + SHIFT));                                 \
  H = static_cast<unsigned int>(SCALE * (*(DATA + Hinc) + SHIFT))

#define VTKKWRCHelper_GetCellScalarValuesSimple(DATA)                                              \
  A = static_cast<unsigned int>(*(DATA));                                                          \
  B = static_cast<unsigned int>(*(DATA + Binc));                                                   \
  C = static_cast<unsigned int>(*(DATA + Cinc));                                                   \
  D = static_cast<unsigned int>(*(DATA + Dinc));                                                   \
  E = static_cast<unsigned int>(*(DATA + Einc));                                                   \
  F = static_cast<unsigned int>(*(DATA + Finc));                                                   \
  G = static_cast<unsigned int>(*(DATA + Ginc));                                                   \
  H = static_cast<unsigned int>(*(DATA + Hinc))

#define VTKKWRCHelper_GetCellMagnitudeValues(ABCD, EFGH)                                           \
  mA = static_cast<unsigned int>(*(ABCD));                                                         \
  mB = static_cast<unsigned int>(*(ABCD + mBFinc));                                                \
  mC = static_cast<unsigned int>(*(ABCD + mCGinc));                                                \
  mD = static_cast<unsigned int>(*(ABCD + mDHinc));                                                \
  mE = static_cast<unsigned int>(*(EFGH));                                                         \
  mF = static_cast<unsigned int>(*(EFGH + mBFinc));                                                \
  mG = static_cast<unsigned int>(*(EFGH + mCGinc));                                                \
  mH = static_cast<unsigned int>(*(EFGH + mDHinc))

#define VTKKWRCHelper_GetCellDirectionValues(ABCD, EFGH)                                           \
  normalA = static_cast<unsigned int>(*(ABCD));                                                    \
  normalB = static_cast<unsigned int>(*(ABCD + dBFinc));                                           \
  normalC = static_cast<unsigned int>(*(ABCD + dCGinc));                                           \
  normalD = static_cast<unsigned int>(*(ABCD + dDHinc));                                           \
  normalE = static_cast<unsigned int>(*(EFGH));                                                    \
  normalF = static_cast<unsigned int>(*(EFGH + dBFinc));                                           \
  normalG = static_cast<unsigned int>(*(EFGH + dCGinc));                                           \
  normalH = static_cast<unsigned int>(*(EFGH + dDHinc));

#define VTKKWRCHelper_GetCellComponentScalarValues(DATA, CIDX, SCALE, SHIFT)                       \
  A[CIDX] = static_cast<unsigned int>(SCALE * (*(DATA) + SHIFT));                                  \
  B[CIDX] = static_cast<unsigned int>(SCALE * (*(DATA + Binc) + SHIFT));                           \
  C[CIDX] = static_cast<unsigned int>(SCALE * (*(DATA + Cinc) + SHIFT));                           \
  D[CIDX] = static_cast<unsigned int>(SCALE * (*(DATA + Dinc) + SHIFT));                           \
  E[CIDX] = static_cast<unsigned int>(SCALE * (*(DATA + Einc) + SHIFT));                           \
  F[CIDX] = static_cast<unsigned int>(SCALE * (*(DATA + Finc) + SHIFT));                           \
  G[CIDX] = static_cast<unsigned int>(SCALE * (*(DATA + Ginc) + SHIFT));                           \
  H[CIDX] = static_cast<unsigned int>(SCALE * (*(DATA + Hinc) + SHIFT))

#define VTKKWRCHelper_GetCellComponentRawScalarValues(DATA, CIDX)                                  \
  A[CIDX] = static_cast<unsigned int>((*(DATA)));                                                  \
  B[CIDX] = static_cast<unsigned int>((*(DATA + Binc)));                                           \
  C[CIDX] = static_cast<unsigned int>((*(DATA + Cinc)));                                           \
  D[CIDX] = static_cast<unsigned int>((*(DATA + Dinc)));                                           \
  E[CIDX] = static_cast<unsigned int>((*(DATA + Einc)));                                           \
  F[CIDX] = static_cast<unsigned int>((*(DATA + Finc)));                                           \
  G[CIDX] = static_cast<unsigned int>((*(DATA + Ginc)));                                           \
  H[CIDX] = static_cast<unsigned int>((*(DATA + Hinc)))

#define VTKKWRCHelper_GetCellComponentMagnitudeValues(ABCD, EFGH, CIDX)                            \
  mA[CIDX] = static_cast<unsigned int>(*(ABCD));                                                   \
  mB[CIDX] = static_cast<unsigned int>(*(ABCD + mBFinc));                                          \
  mC[CIDX] = static_cast<unsigned int>(*(ABCD + mCGinc));                                          \
  mD[CIDX] = static_cast<unsigned int>(*(ABCD + mDHinc));                                          \
  mE[CIDX] = static_cast<unsigned int>(*(EFGH));                                                   \
  mF[CIDX] = static_cast<unsigned int>(*(EFGH + mBFinc));                                          \
  mG[CIDX] = static_cast<unsigned int>(*(EFGH + mCGinc));                                          \
  mH[CIDX] = static_cast<unsigned int>(*(EFGH + mDHinc))

#define VTKKWRCHelper_GetCellComponentDirectionValues(ABCD, EFGH, CIDX)                            \
  normalA[CIDX] = static_cast<unsigned int>(*(ABCD));                                              \
  normalB[CIDX] = static_cast<unsigned int>(*(ABCD + dBFinc));                                     \
  normalC[CIDX] = static_cast<unsigned int>(*(ABCD + dCGinc));                                     \
  normalD[CIDX] = static_cast<unsigned int>(*(ABCD + dDHinc));                                     \
  normalE[CIDX] = static_cast<unsigned int>(*(EFGH));                                              \
  normalF[CIDX] = static_cast<unsigned int>(*(EFGH + dBFinc));                                     \
  normalG[CIDX] = static_cast<unsigned int>(*(EFGH + dCGinc));                                     \
  normalH[CIDX] = static_cast<unsigned int>(*(EFGH + dDHinc));

#define VTKKWRCHelper_ComputeWeights(POS)                                                          \
  w2X = (POS[0] & VTKKW_FP_MASK);                                                                  \
  w2Y = (POS[1] & VTKKW_FP_MASK);                                                                  \
  w2Z = (POS[2] & VTKKW_FP_MASK);                                                                  \
                                                                                                   \
  w1X = ((~w2X) & VTKKW_FP_MASK);                                                                  \
  w1Y = ((~w2Y) & VTKKW_FP_MASK);                                                                  \
  w1Z = ((~w2Z) & VTKKW_FP_MASK);                                                                  \
                                                                                                   \
  w1Xw1Y = (0x4000 + (w1X * w1Y)) >> VTKKW_FP_SHIFT;                                               \
  w2Xw1Y = (0x4000 + (w2X * w1Y)) >> VTKKW_FP_SHIFT;                                               \
  w1Xw2Y = (0x4000 + (w1X * w2Y)) >> VTKKW_FP_SHIFT;                                               \
  w2Xw2Y = (0x4000 + (w2X * w2Y)) >> VTKKW_FP_SHIFT;

#define VTKKWRCHelper_InterpolateScalar(VAL)                                                       \
  VAL = (0x7fff +                                                                                  \
          ((A * ((0x4000 + w1Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +                                     \
            (B * ((0x4000 + w2Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +                                    \
            (C * ((0x4000 + w1Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +                                    \
            (D * ((0x4000 + w2Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +                                    \
            (E * ((0x4000 + w1Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +                                    \
            (F * ((0x4000 + w2Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +                                    \
            (G * ((0x4000 + w1Xw2Y * w2Z) >> VTKKW_FP_SHIFT)) +                                    \
            (H * ((0x4000 + w2Xw2Y * w2Z) >> VTKKW_FP_SHIFT)))) >>                                 \
    VTKKW_FP_SHIFT;

#define VTKKWRCHelper_InterpolateMagnitude(VAL)                                                    \
  VAL = (0x7fff +                                                                                  \
          ((mA * ((0x4000 + w1Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +                                    \
            (mB * ((0x4000 + w2Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +                                   \
            (mC * ((0x4000 + w1Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +                                   \
            (mD * ((0x4000 + w2Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +                                   \
            (mE * ((0x4000 + w1Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +                                   \
            (mF * ((0x4000 + w2Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +                                   \
            (mG * ((0x4000 + w1Xw2Y * w2Z) >> VTKKW_FP_SHIFT)) +                                   \
            (mH * ((0x4000 + w2Xw2Y * w2Z) >> VTKKW_FP_SHIFT)))) >>                                \
    VTKKW_FP_SHIFT;

#define VTKKWRCHelper_InterpolateScalarComponent(VAL, CIDX, COMPONENTS)                            \
  for (CIDX = 0; CIDX < COMPONENTS; CIDX++)                                                        \
  {                                                                                                \
    VAL[CIDX] = (0x7fff +                                                                          \
                  ((A[CIDX] * ((0x4000 + w1Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +                       \
                    (B[CIDX] * ((0x4000 + w2Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +                      \
                    (C[CIDX] * ((0x4000 + w1Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +                      \
                    (D[CIDX] * ((0x4000 + w2Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +                      \
                    (E[CIDX] * ((0x4000 + w1Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +                      \
                    (F[CIDX] * ((0x4000 + w2Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +                      \
                    (G[CIDX] * ((0x4000 + w1Xw2Y * w2Z) >> VTKKW_FP_SHIFT)) +                      \
                    (H[CIDX] * ((0x4000 + w2Xw2Y * w2Z) >> VTKKW_FP_SHIFT)))) >>                   \
      VTKKW_FP_SHIFT;                                                                              \
  }

#define VTKKWRCHelper_InterpolateMagnitudeComponent(VAL, CIDX, COMPONENTS)                         \
  for (CIDX = 0; CIDX < COMPONENTS; CIDX++)                                                        \
  {                                                                                                \
    VAL[CIDX] = (0x7fff +                                                                          \
                  ((mA[CIDX] * ((0x4000 + w1Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +                      \
                    (mB[CIDX] * ((0x4000 + w2Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +                     \
                    (mC[CIDX] * ((0x4000 + w1Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +                     \
                    (mD[CIDX] * ((0x4000 + w2Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +                     \
                    (mE[CIDX] * ((0x4000 + w1Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +                     \
                    (mF[CIDX] * ((0x4000 + w2Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +                     \
                    (mG[CIDX] * ((0x4000 + w1Xw2Y * w2Z) >> VTKKW_FP_SHIFT)) +                     \
                    (mH[CIDX] * ((0x4000 + w2Xw2Y * w2Z) >> VTKKW_FP_SHIFT)))) >>                  \
      VTKKW_FP_SHIFT;                                                                              \
  }

#define VTKKWRCHelper_InterpolateShading(DTABLE, STABLE, COLOR)                                    \
  unsigned int _tmpDColor[3];                                                                      \
  unsigned int _tmpSColor[3];                                                                      \
                                                                                                   \
  _tmpDColor[0] = (0x7fff +                                                                        \
                    ((DTABLE[3 * normalA] * ((0x4000 + w1Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +         \
                      (DTABLE[3 * normalB] * ((0x4000 + w2Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +        \
                      (DTABLE[3 * normalC] * ((0x4000 + w1Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +        \
                      (DTABLE[3 * normalD] * ((0x4000 + w2Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +        \
                      (DTABLE[3 * normalE] * ((0x4000 + w1Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +        \
                      (DTABLE[3 * normalF] * ((0x4000 + w2Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +        \
                      (DTABLE[3 * normalG] * ((0x4000 + w1Xw2Y * w2Z) >> VTKKW_FP_SHIFT)) +        \
                      (DTABLE[3 * normalH] * ((0x4000 + w2Xw2Y * w2Z) >> VTKKW_FP_SHIFT)))) >>     \
    VTKKW_FP_SHIFT;                                                                                \
                                                                                                   \
  _tmpDColor[1] = (0x7fff +                                                                        \
                    ((DTABLE[3 * normalA + 1] * ((0x4000 + w1Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +     \
                      (DTABLE[3 * normalB + 1] * ((0x4000 + w2Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +    \
                      (DTABLE[3 * normalC + 1] * ((0x4000 + w1Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +    \
                      (DTABLE[3 * normalD + 1] * ((0x4000 + w2Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +    \
                      (DTABLE[3 * normalE + 1] * ((0x4000 + w1Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +    \
                      (DTABLE[3 * normalF + 1] * ((0x4000 + w2Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +    \
                      (DTABLE[3 * normalG + 1] * ((0x4000 + w1Xw2Y * w2Z) >> VTKKW_FP_SHIFT)) +    \
                      (DTABLE[3 * normalH + 1] * ((0x4000 + w2Xw2Y * w2Z) >> VTKKW_FP_SHIFT)))) >> \
    VTKKW_FP_SHIFT;                                                                                \
                                                                                                   \
  _tmpDColor[2] = (0x7fff +                                                                        \
                    ((DTABLE[3 * normalA + 2] * ((0x4000 + w1Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +     \
                      (DTABLE[3 * normalB + 2] * ((0x4000 + w2Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +    \
                      (DTABLE[3 * normalC + 2] * ((0x4000 + w1Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +    \
                      (DTABLE[3 * normalD + 2] * ((0x4000 + w2Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +    \
                      (DTABLE[3 * normalE + 2] * ((0x4000 + w1Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +    \
                      (DTABLE[3 * normalF + 2] * ((0x4000 + w2Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +    \
                      (DTABLE[3 * normalG + 2] * ((0x4000 + w1Xw2Y * w2Z) >> VTKKW_FP_SHIFT)) +    \
                      (DTABLE[3 * normalH + 2] * ((0x4000 + w2Xw2Y * w2Z) >> VTKKW_FP_SHIFT)))) >> \
    VTKKW_FP_SHIFT;                                                                                \
                                                                                                   \
  _tmpSColor[0] = (0x7fff +                                                                        \
                    ((STABLE[3 * normalA] * ((0x4000 + w1Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +         \
                      (STABLE[3 * normalB] * ((0x4000 + w2Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +        \
                      (STABLE[3 * normalC] * ((0x4000 + w1Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +        \
                      (STABLE[3 * normalD] * ((0x4000 + w2Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +        \
                      (STABLE[3 * normalE] * ((0x4000 + w1Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +        \
                      (STABLE[3 * normalF] * ((0x4000 + w2Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +        \
                      (STABLE[3 * normalG] * ((0x4000 + w1Xw2Y * w2Z) >> VTKKW_FP_SHIFT)) +        \
                      (STABLE[3 * normalH] * ((0x4000 + w2Xw2Y * w2Z) >> VTKKW_FP_SHIFT)))) >>     \
    VTKKW_FP_SHIFT;                                                                                \
                                                                                                   \
  _tmpSColor[1] = (0x7fff +                                                                        \
                    ((STABLE[3 * normalA + 1] * ((0x4000 + w1Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +     \
                      (STABLE[3 * normalB + 1] * ((0x4000 + w2Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +    \
                      (STABLE[3 * normalC + 1] * ((0x4000 + w1Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +    \
                      (STABLE[3 * normalD + 1] * ((0x4000 + w2Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +    \
                      (STABLE[3 * normalE + 1] * ((0x4000 + w1Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +    \
                      (STABLE[3 * normalF + 1] * ((0x4000 + w2Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +    \
                      (STABLE[3 * normalG + 1] * ((0x4000 + w1Xw2Y * w2Z) >> VTKKW_FP_SHIFT)) +    \
                      (STABLE[3 * normalH + 1] * ((0x4000 + w2Xw2Y * w2Z) >> VTKKW_FP_SHIFT)))) >> \
    VTKKW_FP_SHIFT;                                                                                \
                                                                                                   \
  _tmpSColor[2] = (0x7fff +                                                                        \
                    ((STABLE[3 * normalA + 2] * ((0x4000 + w1Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +     \
                      (STABLE[3 * normalB + 2] * ((0x4000 + w2Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +    \
                      (STABLE[3 * normalC + 2] * ((0x4000 + w1Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +    \
                      (STABLE[3 * normalD + 2] * ((0x4000 + w2Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +    \
                      (STABLE[3 * normalE + 2] * ((0x4000 + w1Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +    \
                      (STABLE[3 * normalF + 2] * ((0x4000 + w2Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +    \
                      (STABLE[3 * normalG + 2] * ((0x4000 + w1Xw2Y * w2Z) >> VTKKW_FP_SHIFT)) +    \
                      (STABLE[3 * normalH + 2] * ((0x4000 + w2Xw2Y * w2Z) >> VTKKW_FP_SHIFT)))) >> \
    VTKKW_FP_SHIFT;                                                                                \
                                                                                                   \
  COLOR[0] = static_cast<unsigned short>((_tmpDColor[0] * COLOR[0] + 0x7fff) >> VTKKW_FP_SHIFT);   \
  COLOR[1] = static_cast<unsigned short>((_tmpDColor[1] * COLOR[1] + 0x7fff) >> VTKKW_FP_SHIFT);   \
  COLOR[2] = static_cast<unsigned short>((_tmpDColor[2] * COLOR[2] + 0x7fff) >> VTKKW_FP_SHIFT);   \
  COLOR[0] += (_tmpSColor[0] * COLOR[3] + 0x7fff) >> VTKKW_FP_SHIFT;                               \
  COLOR[1] += (_tmpSColor[1] * COLOR[3] + 0x7fff) >> VTKKW_FP_SHIFT;                               \
  COLOR[2] += (_tmpSColor[2] * COLOR[3] + 0x7fff) >> VTKKW_FP_SHIFT;

#define VTKKWRCHelper_InterpolateShadingComponent(DTABLE, STABLE, COLOR, CIDX)                     \
  unsigned int _tmpDColor[3];                                                                      \
  unsigned int _tmpSColor[3];                                                                      \
                                                                                                   \
  _tmpDColor[0] =                                                                                  \
    (0x7fff +                                                                                      \
      ((DTABLE[CIDX][3 * normalA[CIDX]] * ((0x4000 + w1Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +           \
        (DTABLE[CIDX][3 * normalB[CIDX]] * ((0x4000 + w2Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +          \
        (DTABLE[CIDX][3 * normalC[CIDX]] * ((0x4000 + w1Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +          \
        (DTABLE[CIDX][3 * normalD[CIDX]] * ((0x4000 + w2Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +          \
        (DTABLE[CIDX][3 * normalE[CIDX]] * ((0x4000 + w1Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +          \
        (DTABLE[CIDX][3 * normalF[CIDX]] * ((0x4000 + w2Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +          \
        (DTABLE[CIDX][3 * normalG[CIDX]] * ((0x4000 + w1Xw2Y * w2Z) >> VTKKW_FP_SHIFT)) +          \
        (DTABLE[CIDX][3 * normalH[CIDX]] * ((0x4000 + w2Xw2Y * w2Z) >> VTKKW_FP_SHIFT)))) >>       \
    VTKKW_FP_SHIFT;                                                                                \
                                                                                                   \
  _tmpDColor[1] =                                                                                  \
    (0x7fff +                                                                                      \
      ((DTABLE[CIDX][3 * normalA[CIDX] + 1] * ((0x4000 + w1Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +       \
        (DTABLE[CIDX][3 * normalB[CIDX] + 1] * ((0x4000 + w2Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +      \
        (DTABLE[CIDX][3 * normalC[CIDX] + 1] * ((0x4000 + w1Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +      \
        (DTABLE[CIDX][3 * normalD[CIDX] + 1] * ((0x4000 + w2Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +      \
        (DTABLE[CIDX][3 * normalE[CIDX] + 1] * ((0x4000 + w1Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +      \
        (DTABLE[CIDX][3 * normalF[CIDX] + 1] * ((0x4000 + w2Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +      \
        (DTABLE[CIDX][3 * normalG[CIDX] + 1] * ((0x4000 + w1Xw2Y * w2Z) >> VTKKW_FP_SHIFT)) +      \
        (DTABLE[CIDX][3 * normalH[CIDX] + 1] * ((0x4000 + w2Xw2Y * w2Z) >> VTKKW_FP_SHIFT)))) >>   \
    VTKKW_FP_SHIFT;                                                                                \
                                                                                                   \
  _tmpDColor[2] =                                                                                  \
    (0x7fff +                                                                                      \
      ((DTABLE[CIDX][3 * normalA[CIDX] + 2] * ((0x4000 + w1Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +       \
        (DTABLE[CIDX][3 * normalB[CIDX] + 2] * ((0x4000 + w2Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +      \
        (DTABLE[CIDX][3 * normalC[CIDX] + 2] * ((0x4000 + w1Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +      \
        (DTABLE[CIDX][3 * normalD[CIDX] + 2] * ((0x4000 + w2Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +      \
        (DTABLE[CIDX][3 * normalE[CIDX] + 2] * ((0x4000 + w1Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +      \
        (DTABLE[CIDX][3 * normalF[CIDX] + 2] * ((0x4000 + w2Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +      \
        (DTABLE[CIDX][3 * normalG[CIDX] + 2] * ((0x4000 + w1Xw2Y * w2Z) >> VTKKW_FP_SHIFT)) +      \
        (DTABLE[CIDX][3 * normalH[CIDX] + 2] * ((0x4000 + w2Xw2Y * w2Z) >> VTKKW_FP_SHIFT)))) >>   \
    VTKKW_FP_SHIFT;                                                                                \
                                                                                                   \
  _tmpSColor[0] =                                                                                  \
    (0x7fff +                                                                                      \
      ((STABLE[CIDX][3 * normalA[CIDX]] * ((0x4000 + w1Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +           \
        (STABLE[CIDX][3 * normalB[CIDX]] * ((0x4000 + w2Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +          \
        (STABLE[CIDX][3 * normalC[CIDX]] * ((0x4000 + w1Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +          \
        (STABLE[CIDX][3 * normalD[CIDX]] * ((0x4000 + w2Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +          \
        (STABLE[CIDX][3 * normalE[CIDX]] * ((0x4000 + w1Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +          \
        (STABLE[CIDX][3 * normalF[CIDX]] * ((0x4000 + w2Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +          \
        (STABLE[CIDX][3 * normalG[CIDX]] * ((0x4000 + w1Xw2Y * w2Z) >> VTKKW_FP_SHIFT)) +          \
        (STABLE[CIDX][3 * normalH[CIDX]] * ((0x4000 + w2Xw2Y * w2Z) >> VTKKW_FP_SHIFT)))) >>       \
    VTKKW_FP_SHIFT;                                                                                \
                                                                                                   \
  _tmpSColor[1] =                                                                                  \
    (0x7fff +                                                                                      \
      ((STABLE[CIDX][3 * normalA[CIDX] + 1] * ((0x4000 + w1Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +       \
        (STABLE[CIDX][3 * normalB[CIDX] + 1] * ((0x4000 + w2Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +      \
        (STABLE[CIDX][3 * normalC[CIDX] + 1] * ((0x4000 + w1Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +      \
        (STABLE[CIDX][3 * normalD[CIDX] + 1] * ((0x4000 + w2Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +      \
        (STABLE[CIDX][3 * normalE[CIDX] + 1] * ((0x4000 + w1Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +      \
        (STABLE[CIDX][3 * normalF[CIDX] + 1] * ((0x4000 + w2Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +      \
        (STABLE[CIDX][3 * normalG[CIDX] + 1] * ((0x4000 + w1Xw2Y * w2Z) >> VTKKW_FP_SHIFT)) +      \
        (STABLE[CIDX][3 * normalH[CIDX] + 1] * ((0x4000 + w2Xw2Y * w2Z) >> VTKKW_FP_SHIFT)))) >>   \
    VTKKW_FP_SHIFT;                                                                                \
                                                                                                   \
  _tmpSColor[2] =                                                                                  \
    (0x7fff +                                                                                      \
      ((STABLE[CIDX][3 * normalA[CIDX] + 2] * ((0x4000 + w1Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +       \
        (STABLE[CIDX][3 * normalB[CIDX] + 2] * ((0x4000 + w2Xw1Y * w1Z) >> VTKKW_FP_SHIFT)) +      \
        (STABLE[CIDX][3 * normalC[CIDX] + 2] * ((0x4000 + w1Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +      \
        (STABLE[CIDX][3 * normalD[CIDX] + 2] * ((0x4000 + w2Xw2Y * w1Z) >> VTKKW_FP_SHIFT)) +      \
        (STABLE[CIDX][3 * normalE[CIDX] + 2] * ((0x4000 + w1Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +      \
        (STABLE[CIDX][3 * normalF[CIDX] + 2] * ((0x4000 + w2Xw1Y * w2Z) >> VTKKW_FP_SHIFT)) +      \
        (STABLE[CIDX][3 * normalG[CIDX] + 2] * ((0x4000 + w1Xw2Y * w2Z) >> VTKKW_FP_SHIFT)) +      \
        (STABLE[CIDX][3 * normalH[CIDX] + 2] * ((0x4000 + w2Xw2Y * w2Z) >> VTKKW_FP_SHIFT)))) >>   \
    VTKKW_FP_SHIFT;                                                                                \
                                                                                                   \
  COLOR[0] = static_cast<unsigned short>((_tmpDColor[0] * COLOR[0] + 0x7fff) >> VTKKW_FP_SHIFT);   \
  COLOR[1] = static_cast<unsigned short>((_tmpDColor[1] * COLOR[1] + 0x7fff) >> VTKKW_FP_SHIFT);   \
  COLOR[2] = static_cast<unsigned short>((_tmpDColor[2] * COLOR[2] + 0x7fff) >> VTKKW_FP_SHIFT);   \
  COLOR[0] += (_tmpSColor[0] * COLOR[3] + 0x7fff) >> VTKKW_FP_SHIFT;                               \
  COLOR[1] += (_tmpSColor[1] * COLOR[3] + 0x7fff) >> VTKKW_FP_SHIFT;                               \
  COLOR[2] += (_tmpSColor[2] * COLOR[3] + 0x7fff) >> VTKKW_FP_SHIFT;

#define VTKKWRCHelper_LookupColorUS(COLORTABLE, SCALAROPACITYTABLE, IDX, COLOR)                    \
  COLOR[3] = SCALAROPACITYTABLE[IDX];                                                              \
  if (!COLOR[3])                                                                                   \
  {                                                                                                \
    continue;                                                                                      \
  }                                                                                                \
  COLOR[0] =                                                                                       \
    static_cast<unsigned short>((COLORTABLE[3 * IDX] * COLOR[3] + 0x7fff) >> (VTKKW_FP_SHIFT));    \
  COLOR[1] = static_cast<unsigned short>(                                                          \
    (COLORTABLE[3 * IDX + 1] * COLOR[3] + 0x7fff) >> (VTKKW_FP_SHIFT));                            \
  COLOR[2] = static_cast<unsigned short>(                                                          \
    (COLORTABLE[3 * IDX + 2] * COLOR[3] + 0x7fff) >> (VTKKW_FP_SHIFT));

#define VTKKWRCHelper_LookupColorMax(COLORTABLE, SCALAROPACITYTABLE, IDX, COLOR)                   \
  COLOR[3] = SCALAROPACITYTABLE[IDX];                                                              \
  COLOR[0] =                                                                                       \
    static_cast<unsigned short>((COLORTABLE[3 * IDX] * COLOR[3] + 0x7fff) >> (VTKKW_FP_SHIFT));    \
  COLOR[1] = static_cast<unsigned short>(                                                          \
    (COLORTABLE[3 * IDX + 1] * COLOR[3] + 0x7fff) >> (VTKKW_FP_SHIFT));                            \
  COLOR[2] = static_cast<unsigned short>(                                                          \
    (COLORTABLE[3 * IDX + 2] * COLOR[3] + 0x7fff) >> (VTKKW_FP_SHIFT));

#define VTKKWRCHelper_LookupDependentColorUS(COLORTABLE, SCALAROPACITYTABLE, IDX, CMPS, COLOR)     \
  {                                                                                                \
    unsigned short _alpha;                                                                         \
    switch (CMPS)                                                                                  \
    {                                                                                              \
      case 2:                                                                                      \
        _alpha = SCALAROPACITYTABLE[IDX[1]];                                                       \
        COLOR[0] = static_cast<unsigned short>(                                                    \
          (COLORTABLE[3 * IDX[0]] * _alpha + 0x7fff) >> (VTKKW_FP_SHIFT));                         \
        COLOR[1] = static_cast<unsigned short>(                                                    \
          (COLORTABLE[3 * IDX[0] + 1] * _alpha + 0x7fff) >> (VTKKW_FP_SHIFT));                     \
        COLOR[2] = static_cast<unsigned short>(                                                    \
          (COLORTABLE[3 * IDX[0] + 2] * _alpha + 0x7fff) >> (VTKKW_FP_SHIFT));                     \
        COLOR[3] = _alpha;                                                                         \
        break;                                                                                     \
      case 4:                                                                                      \
        _alpha = SCALAROPACITYTABLE[IDX[3]];                                                       \
        COLOR[0] = static_cast<unsigned short>((IDX[0] * _alpha + 0x7f) >> 8);                     \
        COLOR[1] = static_cast<unsigned short>((IDX[1] * _alpha + 0x7f) >> 8);                     \
        COLOR[2] = static_cast<unsigned short>((IDX[2] * _alpha + 0x7f) >> 8);                     \
        COLOR[3] = _alpha;                                                                         \
        break;                                                                                     \
    }                                                                                              \
  }

#define VTKKWRCHelper_LookupColorGOUS(CTABLE, SOTABLE, GOTABLE, IDX, IDX2, COLOR)                  \
  COLOR[3] = (SOTABLE[IDX] * GOTABLE[IDX2] + 0x7fff) >> VTKKW_FP_SHIFT;                            \
  if (!COLOR[3])                                                                                   \
  {                                                                                                \
    continue;                                                                                      \
  }                                                                                                \
  COLOR[0] =                                                                                       \
    static_cast<unsigned short>((CTABLE[3 * IDX] * COLOR[3] + 0x7fff) >> (VTKKW_FP_SHIFT));        \
  COLOR[1] =                                                                                       \
    static_cast<unsigned short>((CTABLE[3 * IDX + 1] * COLOR[3] + 0x7fff) >> (VTKKW_FP_SHIFT));    \
  COLOR[2] =                                                                                       \
    static_cast<unsigned short>((CTABLE[3 * IDX + 2] * COLOR[3] + 0x7fff) >> (VTKKW_FP_SHIFT));

#define VTKKWRCHelper_LookupShading(DTABLE, STABLE, NORMAL, COLOR)                                 \
  COLOR[0] =                                                                                       \
    static_cast<unsigned short>((DTABLE[3 * NORMAL] * COLOR[0] + 0x7fff) >> VTKKW_FP_SHIFT);       \
  COLOR[1] =                                                                                       \
    static_cast<unsigned short>((DTABLE[3 * NORMAL + 1] * COLOR[1] + 0x7fff) >> VTKKW_FP_SHIFT);   \
  COLOR[2] =                                                                                       \
    static_cast<unsigned short>((DTABLE[3 * NORMAL + 2] * COLOR[2] + 0x7fff) >> VTKKW_FP_SHIFT);   \
  COLOR[0] += (STABLE[3 * NORMAL] * COLOR[3] + 0x7fff) >> VTKKW_FP_SHIFT;                          \
  COLOR[1] += (STABLE[3 * NORMAL + 1] * COLOR[3] + 0x7fff) >> VTKKW_FP_SHIFT;                      \
  COLOR[2] += (STABLE[3 * NORMAL + 2] * COLOR[3] + 0x7fff) >> VTKKW_FP_SHIFT;

#define VTKKWRCHelper_LookupAndCombineIndependentColorsUS(                                         \
  COLORTABLE, SOTABLE, SCALAR, WEIGHTS, COMPONENTS, COLOR)                                         \
  unsigned int _tmp[4] = { 0, 0, 0, 0 };                                                           \
  unsigned short _alpha[4] = { 0, 0, 0, 0 };                                                       \
  unsigned int _totalAlpha = 0;                                                                    \
                                                                                                   \
  {                                                                                                \
    for (int _idx = 0; _idx < COMPONENTS; _idx++)                                                  \
    {                                                                                              \
      _alpha[_idx] = static_cast<unsigned short>(SOTABLE[_idx][SCALAR[_idx]] * WEIGHTS[_idx]);     \
      _totalAlpha += _alpha[_idx];                                                                 \
    }                                                                                              \
  }                                                                                                \
                                                                                                   \
  if (!_totalAlpha)                                                                                \
  {                                                                                                \
    continue;                                                                                      \
  }                                                                                                \
  {                                                                                                \
    for (int _idx = 0; _idx < COMPONENTS; _idx++)                                                  \
    {                                                                                              \
      if (_alpha[_idx])                                                                            \
      {                                                                                            \
        _tmp[0] += static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx]]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT));     \
        _tmp[1] += static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx] + 1]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT)); \
        _tmp[2] += static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx] + 2]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT)); \
        _tmp[3] += ((_alpha[_idx] * _alpha[_idx]) / _totalAlpha);                                  \
      }                                                                                            \
    }                                                                                              \
  }                                                                                                \
  if (!_tmp[3])                                                                                    \
  {                                                                                                \
    continue;                                                                                      \
  }                                                                                                \
  COLOR[0] = (_tmp[0] > 32767) ? (32767) : (_tmp[0]);                                              \
  COLOR[1] = (_tmp[1] > 32767) ? (32767) : (_tmp[1]);                                              \
  COLOR[2] = (_tmp[2] > 32767) ? (32767) : (_tmp[2]);                                              \
  COLOR[3] = (_tmp[3] > 32767) ? (32767) : (_tmp[3]);

#define VTKKWRCHelper_LookupAndCombineIndependentColorsMax(                                        \
  COLORTABLE, SCALAROPACITYTABLE, IDX, WEIGHTS, CMPS, COLOR)                                       \
  {                                                                                                \
    unsigned int _tmp[4] = { 0, 0, 0, 0 };                                                         \
    for (int _idx = 0; _idx < CMPS; _idx++)                                                        \
    {                                                                                              \
      unsigned short _alpha =                                                                      \
        static_cast<unsigned short>(SCALAROPACITYTABLE[_idx][IDX[_idx]] * WEIGHTS[_idx]);          \
      _tmp[0] += static_cast<unsigned short>(                                                      \
        ((COLORTABLE[_idx][3 * IDX[_idx]]) * _alpha + 0x7fff) >> (VTKKW_FP_SHIFT));                \
      _tmp[1] += static_cast<unsigned short>(                                                      \
        ((COLORTABLE[_idx][3 * IDX[_idx] + 1]) * _alpha + 0x7fff) >> (VTKKW_FP_SHIFT));            \
      _tmp[2] += static_cast<unsigned short>(                                                      \
        ((COLORTABLE[_idx][3 * IDX[_idx] + 2]) * _alpha + 0x7fff) >> (VTKKW_FP_SHIFT));            \
      _tmp[3] += _alpha;                                                                           \
    }                                                                                              \
    COLOR[0] = (_tmp[0] > 32767) ? (32767) : (_tmp[0]);                                            \
    COLOR[1] = (_tmp[1] > 32767) ? (32767) : (_tmp[1]);                                            \
    COLOR[2] = (_tmp[2] > 32767) ? (32767) : (_tmp[2]);                                            \
    COLOR[3] = (_tmp[3] > 32767) ? (32767) : (_tmp[3]);                                            \
  }

#define VTKKWRCHelper_LookupAndCombineIndependentColorsGOUS(                                       \
  COLORTABLE, SOTABLE, GOTABLE, SCALAR, MAG, WEIGHTS, COMPONENTS, COLOR)                           \
  unsigned int _tmp[4] = { 0, 0, 0, 0 };                                                           \
  unsigned short _alpha[4] = { 0, 0, 0, 0 };                                                       \
  unsigned int _totalAlpha = 0;                                                                    \
  COMPONENTS = (COMPONENTS < 4) ? COMPONENTS : 4;                                                  \
  {                                                                                                \
    for (int _idx = 0; _idx < COMPONENTS; _idx++)                                                  \
    {                                                                                              \
      _alpha[_idx] = static_cast<unsigned short>(SOTABLE[_idx][SCALAR[_idx]] * WEIGHTS[_idx]);     \
      if (_alpha[_idx])                                                                            \
      {                                                                                            \
        _alpha[_idx] = static_cast<unsigned short>(                                                \
          (_alpha[_idx] * GOTABLE[_idx][MAG[_idx]] + 0x7fff) >> (VTKKW_FP_SHIFT));                 \
        _totalAlpha += _alpha[_idx];                                                               \
      }                                                                                            \
    }                                                                                              \
  }                                                                                                \
                                                                                                   \
  if (!_totalAlpha)                                                                                \
  {                                                                                                \
    continue;                                                                                      \
  }                                                                                                \
  {                                                                                                \
    for (int _idx = 0; _idx < COMPONENTS; _idx++)                                                  \
    {                                                                                              \
      if (_alpha[_idx])                                                                            \
      {                                                                                            \
        _tmp[0] += static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx]]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT));     \
        _tmp[1] += static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx] + 1]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT)); \
        _tmp[2] += static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx] + 2]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT)); \
        _tmp[3] += ((_alpha[_idx] * _alpha[_idx]) / _totalAlpha);                                  \
      }                                                                                            \
    }                                                                                              \
  }                                                                                                \
  if (!_tmp[3])                                                                                    \
  {                                                                                                \
    continue;                                                                                      \
  }                                                                                                \
  COLOR[0] = (_tmp[0] > 32767) ? (32767) : (_tmp[0]);                                              \
  COLOR[1] = (_tmp[1] > 32767) ? (32767) : (_tmp[1]);                                              \
  COLOR[2] = (_tmp[2] > 32767) ? (32767) : (_tmp[2]);                                              \
  COLOR[3] = (_tmp[3] > 32767) ? (32767) : (_tmp[3]);

#define VTKKWRCHelper_LookupAndCombineIndependentColorsShadeUS(                                    \
  COLORTABLE, SOTABLE, DTABLE, STABLE, SCALAR, NORMAL, WEIGHTS, COMPONENTS, COLOR)                 \
  unsigned int _tmp[4] = { 0, 0, 0, 0 };                                                           \
  unsigned int _tmpC[3];                                                                           \
  unsigned short _alpha[4] = { 0, 0, 0, 0 };                                                       \
  unsigned int _totalAlpha = 0;                                                                    \
                                                                                                   \
  {                                                                                                \
    for (int _idx = 0; _idx < COMPONENTS; _idx++)                                                  \
    {                                                                                              \
      _alpha[_idx] = static_cast<unsigned short>(SOTABLE[_idx][SCALAR[_idx]] * WEIGHTS[_idx]);     \
      _totalAlpha += _alpha[_idx];                                                                 \
    }                                                                                              \
  }                                                                                                \
                                                                                                   \
  if (!_totalAlpha)                                                                                \
  {                                                                                                \
    continue;                                                                                      \
  }                                                                                                \
  {                                                                                                \
    for (int _idx = 0; _idx < COMPONENTS; _idx++)                                                  \
    {                                                                                              \
      if (_alpha[_idx])                                                                            \
      {                                                                                            \
        _tmpC[0] = static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx]]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT));     \
        _tmpC[1] = static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx] + 1]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT)); \
        _tmpC[2] = static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx] + 2]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT)); \
        _tmpC[0] = static_cast<unsigned short>(                                                    \
          (DTABLE[_idx][3 * NORMAL[_idx]] * _tmpC[0] + 0x7fff) >> VTKKW_FP_SHIFT);                 \
        _tmpC[1] = static_cast<unsigned short>(                                                    \
          (DTABLE[_idx][3 * NORMAL[_idx] + 1] * _tmpC[1] + 0x7fff) >> VTKKW_FP_SHIFT);             \
        _tmpC[2] = static_cast<unsigned short>(                                                    \
          (DTABLE[_idx][3 * NORMAL[_idx] + 2] * _tmpC[2] + 0x7fff) >> VTKKW_FP_SHIFT);             \
        _tmpC[0] += (STABLE[_idx][3 * NORMAL[_idx]] * _alpha[_idx] + 0x7fff) >> VTKKW_FP_SHIFT;    \
        _tmpC[1] +=                                                                                \
          (STABLE[_idx][3 * NORMAL[_idx] + 1] * _alpha[_idx] + 0x7fff) >> VTKKW_FP_SHIFT;          \
        _tmpC[2] +=                                                                                \
          (STABLE[_idx][3 * NORMAL[_idx] + 2] * _alpha[_idx] + 0x7fff) >> VTKKW_FP_SHIFT;          \
        _tmp[0] += _tmpC[0];                                                                       \
        _tmp[1] += _tmpC[1];                                                                       \
        _tmp[2] += _tmpC[2];                                                                       \
        _tmp[3] += ((_alpha[_idx] * _alpha[_idx]) / _totalAlpha);                                  \
      }                                                                                            \
    }                                                                                              \
  }                                                                                                \
  if (!_tmp[3])                                                                                    \
  {                                                                                                \
    continue;                                                                                      \
  }                                                                                                \
                                                                                                   \
  COLOR[0] = (_tmp[0] > 32767) ? (32767) : (_tmp[0]);                                              \
  COLOR[1] = (_tmp[1] > 32767) ? (32767) : (_tmp[1]);                                              \
  COLOR[2] = (_tmp[2] > 32767) ? (32767) : (_tmp[2]);                                              \
  COLOR[3] = (_tmp[3] > 32767) ? (32767) : (_tmp[3]);

#define VTKKWRCHelper_LookupAndCombineIndependentColorsInterpolateShadeUS(                         \
  COLORTABLE, SOTABLE, DTABLE, STABLE, SCALAR, WEIGHTS, COMPONENTS, COLOR)                         \
  unsigned int _tmp[4] = { 0, 0, 0, 0 };                                                           \
  unsigned int _tmpC[4];                                                                           \
  unsigned short _alpha[4] = { 0, 0, 0, 0 };                                                       \
  unsigned int _totalAlpha = 0;                                                                    \
                                                                                                   \
  {                                                                                                \
    for (int _idx = 0; _idx < COMPONENTS; _idx++)                                                  \
    {                                                                                              \
      _alpha[_idx] = static_cast<unsigned short>(SOTABLE[_idx][SCALAR[_idx]] * WEIGHTS[_idx]);     \
      _totalAlpha += _alpha[_idx];                                                                 \
    }                                                                                              \
  }                                                                                                \
                                                                                                   \
  if (!_totalAlpha)                                                                                \
  {                                                                                                \
    continue;                                                                                      \
  }                                                                                                \
  {                                                                                                \
    for (int _idx = 0; _idx < COMPONENTS; _idx++)                                                  \
    {                                                                                              \
      if (_alpha[_idx])                                                                            \
      {                                                                                            \
        _tmpC[0] = static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx]]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT));     \
        _tmpC[1] = static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx] + 1]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT)); \
        _tmpC[2] = static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx] + 2]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT)); \
        _tmpC[3] = _alpha[_idx];                                                                   \
        VTKKWRCHelper_InterpolateShadingComponent(DTABLE, STABLE, _tmpC, _idx);                    \
        _tmp[0] += _tmpC[0];                                                                       \
        _tmp[1] += _tmpC[1];                                                                       \
        _tmp[2] += _tmpC[2];                                                                       \
        _tmp[3] += ((_alpha[_idx] * _alpha[_idx]) / _totalAlpha);                                  \
      }                                                                                            \
    }                                                                                              \
  }                                                                                                \
  if (!_tmp[3])                                                                                    \
  {                                                                                                \
    continue;                                                                                      \
  }                                                                                                \
  COLOR[0] = (_tmp[0] > 32767) ? (32767) : (_tmp[0]);                                              \
  COLOR[1] = (_tmp[1] > 32767) ? (32767) : (_tmp[1]);                                              \
  COLOR[2] = (_tmp[2] > 32767) ? (32767) : (_tmp[2]);                                              \
  COLOR[3] = (_tmp[3] > 32767) ? (32767) : (_tmp[3]);

#define VTKKWRCHelper_CompositeColorAndCheckEarlyTermination(COLOR, TMP, REMAININGOPACITY)         \
  COLOR[0] += (TMP[0] * REMAININGOPACITY + 0x7fff) >> VTKKW_FP_SHIFT;                              \
  COLOR[1] += (TMP[1] * REMAININGOPACITY + 0x7fff) >> VTKKW_FP_SHIFT;                              \
  COLOR[2] += (TMP[2] * REMAININGOPACITY + 0x7fff) >> VTKKW_FP_SHIFT;                              \
  REMAININGOPACITY =                                                                               \
    (REMAININGOPACITY * ((~(TMP[3]) & VTKKW_FP_MASK)) + 0x7fff) >> VTKKW_FP_SHIFT;                 \
  if (REMAININGOPACITY < 0xff)                                                                     \
  {                                                                                                \
    break;                                                                                         \
  }

#define VTKKWRCHelper_LookupAndCombineIndependentColorsGOShadeUS(                                  \
  COLORTABLE, SOTABLE, GOTABLE, DTABLE, STABLE, SCALAR, MAG, NORMAL, WEIGHTS, COMPONENTS, COLOR)   \
  unsigned int _tmp[4] = { 0, 0, 0, 0 };                                                           \
  unsigned int _tmpC[3];                                                                           \
  unsigned short _alpha[4] = { 0, 0, 0, 0 };                                                       \
  unsigned int _totalAlpha = 0;                                                                    \
                                                                                                   \
  {                                                                                                \
    for (int _idx = 0; _idx < COMPONENTS; _idx++)                                                  \
    {                                                                                              \
      _alpha[_idx] = static_cast<unsigned short>(SOTABLE[_idx][SCALAR[_idx]] * WEIGHTS[_idx]);     \
      if (_alpha[_idx])                                                                            \
      {                                                                                            \
        _alpha[_idx] = static_cast<unsigned short>(                                                \
          (_alpha[_idx] * GOTABLE[_idx][MAG[_idx]] + 0x7fff) >> (VTKKW_FP_SHIFT));                 \
        _totalAlpha += _alpha[_idx];                                                               \
      }                                                                                            \
    }                                                                                              \
  }                                                                                                \
                                                                                                   \
  if (!_totalAlpha)                                                                                \
  {                                                                                                \
    continue;                                                                                      \
  }                                                                                                \
                                                                                                   \
  {                                                                                                \
    for (int _idx = 0; _idx < COMPONENTS; _idx++)                                                  \
    {                                                                                              \
      if (_alpha[_idx])                                                                            \
      {                                                                                            \
        _tmpC[0] = static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx]]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT));     \
        _tmpC[1] = static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx] + 1]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT)); \
        _tmpC[2] = static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx] + 2]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT)); \
        _tmpC[0] = static_cast<unsigned short>(                                                    \
          (DTABLE[_idx][3 * NORMAL[_idx]] * _tmpC[0] + 0x7fff) >> VTKKW_FP_SHIFT);                 \
        _tmpC[1] = static_cast<unsigned short>(                                                    \
          (DTABLE[_idx][3 * NORMAL[_idx] + 1] * _tmpC[1] + 0x7fff) >> VTKKW_FP_SHIFT);             \
        _tmpC[2] = static_cast<unsigned short>(                                                    \
          (DTABLE[_idx][3 * NORMAL[_idx] + 2] * _tmpC[2] + 0x7fff) >> VTKKW_FP_SHIFT);             \
        _tmpC[0] += (STABLE[_idx][3 * NORMAL[_idx]] * _alpha[_idx] + 0x7fff) >> VTKKW_FP_SHIFT;    \
        _tmpC[1] +=                                                                                \
          (STABLE[_idx][3 * NORMAL[_idx] + 1] * _alpha[_idx] + 0x7fff) >> VTKKW_FP_SHIFT;          \
        _tmpC[2] +=                                                                                \
          (STABLE[_idx][3 * NORMAL[_idx] + 2] * _alpha[_idx] + 0x7fff) >> VTKKW_FP_SHIFT;          \
        _tmp[0] += _tmpC[0];                                                                       \
        _tmp[1] += _tmpC[1];                                                                       \
        _tmp[2] += _tmpC[2];                                                                       \
        _tmp[3] += ((_alpha[_idx] * _alpha[_idx]) / _totalAlpha);                                  \
      }                                                                                            \
    }                                                                                              \
  }                                                                                                \
  if (!_tmp[3])                                                                                    \
  {                                                                                                \
    continue;                                                                                      \
  }                                                                                                \
  COLOR[0] = (_tmp[0] > 32767) ? (32767) : (_tmp[0]);                                              \
  COLOR[1] = (_tmp[1] > 32767) ? (32767) : (_tmp[1]);                                              \
  COLOR[2] = (_tmp[2] > 32767) ? (32767) : (_tmp[2]);                                              \
  COLOR[3] = (_tmp[3] > 32767) ? (32767) : (_tmp[3]);

#define VTKKWRCHelper_LookupAndCombineIndependentColorsGOInterpolateShadeUS(                       \
  COLORTABLE, SOTABLE, GOTABLE, DTABLE, STABLE, SCALAR, MAG, WEIGHTS, COMPONENTS, COLOR)           \
  unsigned int _tmp[4] = { 0, 0, 0, 0 };                                                           \
  unsigned int _tmpC[4];                                                                           \
  unsigned short _alpha[4] = { 0, 0, 0, 0 };                                                       \
  unsigned int _totalAlpha = 0;                                                                    \
                                                                                                   \
  {                                                                                                \
    for (int _idx = 0; _idx < COMPONENTS; _idx++)                                                  \
    {                                                                                              \
      _alpha[_idx] = static_cast<unsigned short>(SOTABLE[_idx][SCALAR[_idx]] * WEIGHTS[_idx]);     \
      if (_alpha[_idx])                                                                            \
      {                                                                                            \
        _alpha[_idx] = static_cast<unsigned short>(                                                \
          (_alpha[_idx] * GOTABLE[_idx][MAG[_idx]] + 0x7fff) >> (VTKKW_FP_SHIFT));                 \
        _totalAlpha += _alpha[_idx];                                                               \
      }                                                                                            \
    }                                                                                              \
  }                                                                                                \
                                                                                                   \
  if (!_totalAlpha)                                                                                \
  {                                                                                                \
    continue;                                                                                      \
  }                                                                                                \
  {                                                                                                \
    for (int _idx = 0; _idx < COMPONENTS; _idx++)                                                  \
    {                                                                                              \
      if (_alpha[_idx])                                                                            \
      {                                                                                            \
        _tmpC[0] = static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx]]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT));     \
        _tmpC[1] = static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx] + 1]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT)); \
        _tmpC[2] = static_cast<unsigned short>(                                                    \
          ((COLORTABLE[_idx][3 * SCALAR[_idx] + 2]) * _alpha[_idx] + 0x7fff) >> (VTKKW_FP_SHIFT)); \
        _tmpC[3] = _alpha[_idx];                                                                   \
        VTKKWRCHelper_InterpolateShadingComponent(DTABLE, STABLE, _tmpC, _idx);                    \
        _tmp[0] += _tmpC[0];                                                                       \
        _tmp[1] += _tmpC[1];                                                                       \
        _tmp[2] += _tmpC[2];                                                                       \
        _tmp[3] += ((_alpha[_idx] * _alpha[_idx]) / _totalAlpha);                                  \
      }                                                                                            \
    }                                                                                              \
  }                                                                                                \
  if (!_tmp[3])                                                                                    \
  {                                                                                                \
    continue;                                                                                      \
  }                                                                                                \
  COLOR[0] = (_tmp[0] > 32767) ? (32767) : (_tmp[0]);                                              \
  COLOR[1] = (_tmp[1] > 32767) ? (32767) : (_tmp[1]);                                              \
  COLOR[2] = (_tmp[2] > 32767) ? (32767) : (_tmp[2]);                                              \
  COLOR[3] = (_tmp[3] > 32767) ? (32767) : (_tmp[3]);

#define VTKKWRCHelper_SetPixelColor(IMAGEPTR, COLOR, REMAININGOPACITY)                             \
  IMAGEPTR[0] = (COLOR[0] > 32767) ? (32767) : (COLOR[0]);                                         \
  IMAGEPTR[1] = (COLOR[1] > 32767) ? (32767) : (COLOR[1]);                                         \
  IMAGEPTR[2] = (COLOR[2] > 32767) ? (32767) : (COLOR[2]);                                         \
  unsigned int tmpAlpha = (~REMAININGOPACITY) & VTKKW_FP_MASK;                                     \
  IMAGEPTR[3] = (tmpAlpha > 32767) ? (32767) : (tmpAlpha);

#define VTKKWRCHelper_MoveToNextSampleNN()                                                         \
  if (k < numSteps - 1)                                                                            \
  {                                                                                                \
    mapper->FixedPointIncrement(pos, dir);                                                         \
    mapper->ShiftVectorDown(pos, spos);                                                            \
    dptr = data + spos[0] * inc[0] + spos[1] * inc[1] + spos[2] * inc[2];                          \
  }

#define VTKKWRCHelper_MoveToNextSampleGONN()                                                       \
  if (k < numSteps - 1)                                                                            \
  {                                                                                                \
    mapper->FixedPointIncrement(pos, dir);                                                         \
    mapper->ShiftVectorDown(pos, spos);                                                            \
    dptr = data + spos[0] * inc[0] + spos[1] * inc[1] + spos[2] * inc[2];                          \
    magPtr = gradientMag[spos[2]] + spos[0] * mInc[0] + spos[1] * mInc[1];                         \
  }

#define VTKKWRCHelper_MoveToNextSampleShadeNN()                                                    \
  if (k < numSteps - 1)                                                                            \
  {                                                                                                \
    mapper->FixedPointIncrement(pos, dir);                                                         \
    mapper->ShiftVectorDown(pos, spos);                                                            \
    dptr = data + spos[0] * inc[0] + spos[1] * inc[1] + spos[2] * inc[2];                          \
    dirPtr = gradientDir[spos[2]] + spos[0] * dInc[0] + spos[1] * dInc[1];                         \
  }

#define VTKKWRCHelper_MoveToNextSampleGOShadeNN()                                                  \
  if (k < numSteps - 1)                                                                            \
  {                                                                                                \
    mapper->FixedPointIncrement(pos, dir);                                                         \
    mapper->ShiftVectorDown(pos, spos);                                                            \
    dptr = data + spos[0] * inc[0] + spos[1] * inc[1] + spos[2] * inc[2];                          \
    magPtr = gradientMag[spos[2]] + spos[0] * mInc[0] + spos[1] * mInc[1];                         \
    dirPtr = gradientDir[spos[2]] + spos[0] * dInc[0] + spos[1] * dInc[1];                         \
  }

#define VTKKWRCHelper_InitializeVariables()                                                        \
  int i, j;                                                                                        \
  unsigned short* imagePtr;                                                                        \
                                                                                                   \
  int imageInUseSize[2];                                                                           \
  int imageMemorySize[2];                                                                          \
  int imageViewportSize[2];                                                                        \
  int imageOrigin[2];                                                                              \
  int dim[3];                                                                                      \
  float shift[4];                                                                                  \
  float scale[4];                                                                                  \
                                                                                                   \
  mapper->GetRayCastImage()->GetImageInUseSize(imageInUseSize);                                    \
  mapper->GetRayCastImage()->GetImageMemorySize(imageMemorySize);                                  \
  mapper->GetRayCastImage()->GetImageViewportSize(imageViewportSize);                              \
  mapper->GetRayCastImage()->GetImageOrigin(imageOrigin);                                          \
  vtkImageData* imData = vtkImageData::SafeDownCast(mapper->GetInput());                           \
  vtkRectilinearGrid* rGrid = vtkRectilinearGrid::SafeDownCast(mapper->GetInput());                \
  if (imData)                                                                                      \
  {                                                                                                \
    imData->GetDimensions(dim);                                                                    \
  }                                                                                                \
  else if (rGrid)                                                                                  \
  {                                                                                                \
    rGrid->GetDimensions(dim);                                                                     \
  }                                                                                                \
  mapper->GetTableShift(shift);                                                                    \
  mapper->GetTableScale(scale);                                                                    \
                                                                                                   \
  int* rowBounds = mapper->GetRowBounds();                                                         \
  unsigned short* image = mapper->GetRayCastImage()->GetImage();                                   \
  vtkRenderWindow* renWin = mapper->GetRenderWindow();                                             \
  int components = 1;                                                                              \
  if (imData)                                                                                      \
  {                                                                                                \
    components = imData->GetNumberOfScalarComponents();                                            \
  }                                                                                                \
  else if (rGrid)                                                                                  \
  {                                                                                                \
    components = rGrid->GetNumberOfScalarComponents();                                             \
  }                                                                                                \
  int cropping = (mapper->GetCropping() && mapper->GetCroppingRegionFlags() != 0x2000);            \
                                                                                                   \
  components = (components < 4) ? components : 4;                                                  \
  unsigned short* colorTable[4];                                                                   \
  unsigned short* scalarOpacityTable[4];                                                           \
                                                                                                   \
  int c;                                                                                           \
  for (c = 0; c < 4; c++)                                                                          \
  {                                                                                                \
    colorTable[c] = mapper->GetColorTable(c);                                                      \
    (void)(colorTable[c]);                                                                         \
    scalarOpacityTable[c] = mapper->GetScalarOpacityTable(c);                                      \
  }                                                                                                \
                                                                                                   \
  vtkIdType inc[3];                                                                                \
  inc[0] = components;                                                                             \
  inc[1] = inc[0] * dim[0];                                                                        \
  inc[2] = inc[1] * dim[1];

#define VTKKWRCHelper_InitializeWeights()                                                          \
  float weights[4] = {};                                                                           \
  weights[0] = vol->GetProperty()->GetComponentWeight(0);                                          \
  weights[1] = vol->GetProperty()->GetComponentWeight(1);                                          \
  weights[2] = vol->GetProperty()->GetComponentWeight(2);                                          \
  weights[3] = vol->GetProperty()->GetComponentWeight(3);

#define VTKKWRCHelper_InitializeVariablesGO()                                                      \
  unsigned short* gradientOpacityTable[4];                                                         \
  for (c = 0; c < 4; c++)                                                                          \
  {                                                                                                \
    gradientOpacityTable[c] = mapper->GetGradientOpacityTable(c);                                  \
  }                                                                                                \
  unsigned char** gradientMag = mapper->GetGradientMagnitude();                                    \
                                                                                                   \
  vtkIdType mInc[3];                                                                               \
  if (vol->GetProperty()->GetIndependentComponents())                                              \
  {                                                                                                \
    mInc[0] = inc[0];                                                                              \
    mInc[1] = inc[1];                                                                              \
    mInc[2] = inc[2];                                                                              \
  }                                                                                                \
  else                                                                                             \
  {                                                                                                \
    mInc[0] = 1;                                                                                   \
    mInc[1] = mInc[0] * dim[0];                                                                    \
    mInc[2] = mInc[1] * dim[1];                                                                    \
  }

#define VTKKWRCHelper_InitializeVariablesShade()                                                   \
  unsigned short* diffuseShadingTable[4];                                                          \
  unsigned short* specularShadingTable[4];                                                         \
  for (c = 0; c < 4; c++)                                                                          \
  {                                                                                                \
    diffuseShadingTable[c] = mapper->GetDiffuseShadingTable(c);                                    \
    specularShadingTable[c] = mapper->GetSpecularShadingTable(c);                                  \
  }                                                                                                \
  unsigned short** gradientDir = mapper->GetGradientNormal();                                      \
  vtkIdType dInc[3];                                                                               \
  if (vol->GetProperty()->GetIndependentComponents())                                              \
  {                                                                                                \
    dInc[0] = inc[0];                                                                              \
    dInc[1] = inc[1];                                                                              \
    dInc[2] = inc[2];                                                                              \
  }                                                                                                \
  else                                                                                             \
  {                                                                                                \
    dInc[0] = 1;                                                                                   \
    dInc[1] = dInc[0] * dim[0];                                                                    \
    dInc[2] = dInc[1] * dim[1];                                                                    \
  }

#define VTKKWRCHelper_InitializeTrilinVariables()                                                  \
  vtkIdType Binc = components;                                                                     \
  vtkIdType Cinc = Binc * dim[0];                                                                  \
  vtkIdType Dinc = Cinc + Binc;                                                                    \
  vtkIdType Einc = Cinc * dim[1];                                                                  \
  vtkIdType Finc = Einc + Binc;                                                                    \
  vtkIdType Ginc = Einc + Cinc;                                                                    \
  vtkIdType Hinc = Ginc + Binc;

#define VTKKWRCHelper_InitializeTrilinVariablesGO()                                                \
  vtkIdType magOffset;                                                                             \
  if (vol->GetProperty()->GetIndependentComponents())                                              \
  {                                                                                                \
    magOffset = components;                                                                        \
  }                                                                                                \
  else                                                                                             \
  {                                                                                                \
    magOffset = 1;                                                                                 \
  }                                                                                                \
                                                                                                   \
  vtkIdType mBFinc = magOffset;                                                                    \
  vtkIdType mCGinc = dim[0] * magOffset;                                                           \
  vtkIdType mDHinc = dim[0] * magOffset + magOffset;

#define VTKKWRCHelper_InitializeTrilinVariablesShade()                                             \
  vtkIdType dirOffset;                                                                             \
  if (vol->GetProperty()->GetIndependentComponents())                                              \
  {                                                                                                \
    dirOffset = components;                                                                        \
  }                                                                                                \
  else                                                                                             \
  {                                                                                                \
    dirOffset = 1;                                                                                 \
  }                                                                                                \
                                                                                                   \
  vtkIdType dBFinc = dirOffset;                                                                    \
  vtkIdType dCGinc = dim[0] * dirOffset;                                                           \
  vtkIdType dDHinc = dim[0] * dirOffset + dirOffset;

#define VTKKWRCHelper_OuterInitialization()                                                        \
  if (j % threadCount != threadID)                                                                 \
  {                                                                                                \
    continue;                                                                                      \
  }                                                                                                \
  if (!threadID)                                                                                   \
  {                                                                                                \
    if (renWin->CheckAbortStatus())                                                                \
    {                                                                                              \
      break;                                                                                       \
    }                                                                                              \
  }                                                                                                \
  else if (renWin->GetAbortRender())                                                               \
  {                                                                                                \
    break;                                                                                         \
  }                                                                                                \
  imagePtr = image + 4 * (j * imageMemorySize[0] + rowBounds[j * 2]);

#define VTKKWRCHelper_InnerInitialization()                                                        \
  unsigned int numSteps;                                                                           \
  unsigned int pos[3];                                                                             \
  unsigned int dir[3];                                                                             \
  mapper->ComputeRayInfo(i, j, pos, dir, &numSteps);                                               \
  if (numSteps == 0)                                                                               \
  {                                                                                                \
    *(imagePtr) = 0;                                                                               \
    *(imagePtr + 1) = 0;                                                                           \
    *(imagePtr + 2) = 0;                                                                           \
    *(imagePtr + 3) = 0;                                                                           \
    imagePtr += 4;                                                                                 \
    continue;                                                                                      \
  }                                                                                                \
  unsigned int spos[3];                                                                            \
  unsigned int k;

#define VTKKWRCHelper_InitializeMIPOneNN()                                                         \
  mapper->ShiftVectorDown(pos, spos);                                                              \
  T* dptr = data + spos[0] * inc[0] + spos[1] * inc[1] + spos[2] * inc[2];                         \
  T maxValue = *(dptr);

#define VTKKWRCHelper_InitializeMIPMultiNN()                                                       \
  mapper->ShiftVectorDown(pos, spos);                                                              \
  T* dptr = data + spos[0] * inc[0] + spos[1] * inc[1] + spos[2] * inc[2];                         \
  T maxValue[4] = {};                                                                              \
  for (c = 0; c < components; c++)                                                                 \
  {                                                                                                \
    maxValue[c] = *(dptr + c);                                                                     \
  }

#define VTKKWRCHelper_InitializeMIPOneTrilin()                                                     \
  T* dptr;                                                                                         \
  unsigned int oldSPos[3];                                                                         \
                                                                                                   \
  oldSPos[0] = (pos[0] >> VTKKW_FP_SHIFT) + 1;                                                     \
  oldSPos[1] = 0;                                                                                  \
  oldSPos[2] = 0;                                                                                  \
                                                                                                   \
  unsigned int w1X, w1Y, w1Z;                                                                      \
  unsigned int w2X, w2Y, w2Z;                                                                      \
  unsigned int w1Xw1Y, w2Xw1Y, w1Xw2Y, w2Xw2Y;                                                     \
                                                                                                   \
  unsigned short maxValue = 0;                                                                     \
  unsigned short val;                                                                              \
  unsigned int A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0;

#define VTKKWRCHelper_InitializeMIPMultiTrilin()                                                   \
  T* dptr;                                                                                         \
  unsigned int oldSPos[3];                                                                         \
                                                                                                   \
  oldSPos[0] = (pos[0] >> VTKKW_FP_SHIFT) + 1;                                                     \
  oldSPos[1] = 0;                                                                                  \
  oldSPos[2] = 0;                                                                                  \
                                                                                                   \
  unsigned int w1X, w1Y, w1Z;                                                                      \
  unsigned int w2X, w2Y, w2Z;                                                                      \
  unsigned int w1Xw1Y, w2Xw1Y, w1Xw2Y, w2Xw2Y;                                                     \
                                                                                                   \
  unsigned short maxValue[4] = {};                                                                 \
  unsigned short val[4] = {};                                                                      \
  unsigned int A[4] = {}, B[4] = {}, C[4] = {}, D[4] = {}, E[4] = {}, F[4] = {}, G[4] = {},        \
               H[4] = {};

#define VTKKWRCHelper_InitializeCompositeGONN()                                                    \
  unsigned char* magPtr = gradientMag[spos[2]] + spos[0] * mInc[0] + spos[1] * mInc[1];

#define VTKKWRCHelper_InitializeCompositeShadeNN()                                                 \
  unsigned short* dirPtr = gradientDir[spos[2]] + spos[0] * dInc[0] + spos[1] * dInc[1];

#define VTKKWRCHelper_InitializeCompositeOneNN()                                                   \
  mapper->ShiftVectorDown(pos, spos);                                                              \
  T* dptr = data + spos[0] * inc[0] + spos[1] * inc[1] + spos[2] * inc[2];                         \
  unsigned int color[3] = { 0, 0, 0 };                                                             \
  unsigned short remainingOpacity = 0x7fff;                                                        \
  unsigned short tmp[4];

#define VTKKWRCHelper_InitializeCompositeMultiNN()                                                 \
  mapper->ShiftVectorDown(pos, spos);                                                              \
  T* dptr = data + spos[0] * inc[0] + spos[1] * inc[1] + spos[2] * inc[2];                         \
  unsigned int color[3] = { 0, 0, 0 };                                                             \
  unsigned int remainingOpacity = 0x7fff;                                                          \
  unsigned short tmp[4] = {};                                                                      \
  unsigned short val[4] = {};

#define VTKKWRCHelper_InitializeCompositeOneTrilin()                                               \
  T* dptr;                                                                                         \
  unsigned int oldSPos[3];                                                                         \
                                                                                                   \
  oldSPos[0] = (pos[0] >> VTKKW_FP_SHIFT) + 1;                                                     \
  oldSPos[1] = 0;                                                                                  \
  oldSPos[2] = 0;                                                                                  \
                                                                                                   \
  unsigned int w1X, w1Y, w1Z;                                                                      \
  unsigned int w2X, w2Y, w2Z;                                                                      \
  unsigned int w1Xw1Y, w2Xw1Y, w1Xw2Y, w2Xw2Y;                                                     \
                                                                                                   \
  unsigned short val;                                                                              \
  unsigned int A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0;                             \
                                                                                                   \
  unsigned int color[3] = { 0, 0, 0 };                                                             \
  unsigned short remainingOpacity = 0x7fff;                                                        \
  unsigned short tmp[4];

#define VTKKWRCHelper_InitializeCompositeOneGOTrilin()                                             \
  unsigned char *magPtrABCD = nullptr, *magPtrEFGH = nullptr;                                      \
  unsigned short mag;                                                                              \
  unsigned int mA = 0, mB = 0, mC = 0, mD = 0, mE = 0, mF = 0, mG = 0, mH = 0;

#define VTKKWRCHelper_InitializeCompositeOneShadeTrilin()                                          \
  unsigned short *dirPtrABCD = 0, *dirPtrEFGH = 0;                                                 \
  unsigned int normalA = 0, normalB = 0, normalC = 0, normalD = 0;                                 \
  unsigned int normalE = 0, normalF = 0, normalG = 0, normalH = 0;

#define VTKKWRCHelper_InitializeCompositeMultiTrilin()                                             \
  T* dptr;                                                                                         \
  unsigned int oldSPos[3];                                                                         \
                                                                                                   \
  oldSPos[0] = (pos[0] >> VTKKW_FP_SHIFT) + 1;                                                     \
  oldSPos[1] = 0;                                                                                  \
  oldSPos[2] = 0;                                                                                  \
                                                                                                   \
  unsigned int w1X, w1Y, w1Z;                                                                      \
  unsigned int w2X, w2Y, w2Z;                                                                      \
  unsigned int w1Xw1Y, w2Xw1Y, w1Xw2Y, w2Xw2Y;                                                     \
                                                                                                   \
  unsigned short val[4] = { 0, 0, 0, 0 };                                                          \
  unsigned int A[4] = { 0, 0, 0, 0 };                                                              \
  unsigned int B[4] = { 0, 0, 0, 0 };                                                              \
  unsigned int C[4] = { 0, 0, 0, 0 };                                                              \
  unsigned int D[4] = { 0, 0, 0, 0 };                                                              \
  unsigned int E[4] = { 0, 0, 0, 0 };                                                              \
  unsigned int F[4] = { 0, 0, 0, 0 };                                                              \
  unsigned int G[4] = { 0, 0, 0, 0 };                                                              \
  unsigned int H[4] = { 0, 0, 0, 0 };                                                              \
                                                                                                   \
  unsigned int color[3] = { 0, 0, 0 };                                                             \
  unsigned short remainingOpacity = 0x7fff;                                                        \
  unsigned short tmp[4];

#define VTKKWRCHelper_InitializeCompositeMultiGOTrilin()                                           \
  unsigned char *magPtrABCD = 0, *magPtrEFGH = 0;                                                  \
  unsigned short mag[4] = {};                                                                      \
  unsigned int mA[4] = {}, mB[4] = {}, mC[4] = {}, mD[4] = {}, mE[4] = {}, mF[4] = {}, mG[4] = {}, \
               mH[4] = {};

#define VTKKWRCHelper_InitializeCompositeMultiShadeTrilin()                                        \
  unsigned short *dirPtrABCD = 0, *dirPtrEFGH = 0;                                                 \
  unsigned int normalA[4], normalB[4], normalC[4], normalD[4];                                     \
  unsigned int normalE[4], normalF[4], normalG[4], normalH[4];

#define VTKKWRCHelper_InitializationAndLoopStartNN()                                               \
  VTKKWRCHelper_InitializeVariables();                                                             \
  for (j = 0; j < imageInUseSize[1]; j++)                                                          \
  {                                                                                                \
    VTKKWRCHelper_OuterInitialization();                                                           \
    for (i = rowBounds[j * 2]; i <= rowBounds[j * 2 + 1]; i++)                                     \
    {                                                                                              \
      VTKKWRCHelper_InnerInitialization();

#define VTKKWRCHelper_InitializationAndLoopStartGONN()                                             \
  VTKKWRCHelper_InitializeVariables();                                                             \
  VTKKWRCHelper_InitializeVariablesGO();                                                           \
  for (j = 0; j < imageInUseSize[1]; j++)                                                          \
  {                                                                                                \
    VTKKWRCHelper_OuterInitialization();                                                           \
    for (i = rowBounds[j * 2]; i <= rowBounds[j * 2 + 1]; i++)                                     \
    {                                                                                              \
      VTKKWRCHelper_InnerInitialization();

#define VTKKWRCHelper_InitializationAndLoopStartShadeNN()                                          \
  VTKKWRCHelper_InitializeVariables();                                                             \
  VTKKWRCHelper_InitializeVariablesShade();                                                        \
  for (j = 0; j < imageInUseSize[1]; j++)                                                          \
  {                                                                                                \
    VTKKWRCHelper_OuterInitialization();                                                           \
    for (i = rowBounds[j * 2]; i <= rowBounds[j * 2 + 1]; i++)                                     \
    {                                                                                              \
      VTKKWRCHelper_InnerInitialization();

#define VTKKWRCHelper_InitializationAndLoopStartGOShadeNN()                                        \
  VTKKWRCHelper_InitializeVariables();                                                             \
  VTKKWRCHelper_InitializeVariablesGO();                                                           \
  VTKKWRCHelper_InitializeVariablesShade();                                                        \
  for (j = 0; j < imageInUseSize[1]; j++)                                                          \
  {                                                                                                \
    VTKKWRCHelper_OuterInitialization();                                                           \
    for (i = rowBounds[j * 2]; i <= rowBounds[j * 2 + 1]; i++)                                     \
    {                                                                                              \
      VTKKWRCHelper_InnerInitialization();

#define VTKKWRCHelper_InitializationAndLoopStartTrilin()                                           \
  VTKKWRCHelper_InitializeVariables();                                                             \
  VTKKWRCHelper_InitializeTrilinVariables();                                                       \
  for (j = 0; j < imageInUseSize[1]; j++)                                                          \
  {                                                                                                \
    VTKKWRCHelper_OuterInitialization();                                                           \
    for (i = rowBounds[j * 2]; i <= rowBounds[j * 2 + 1]; i++)                                     \
    {                                                                                              \
      VTKKWRCHelper_InnerInitialization();

#define VTKKWRCHelper_InitializationAndLoopStartGOTrilin()                                         \
  VTKKWRCHelper_InitializeVariables();                                                             \
  VTKKWRCHelper_InitializeVariablesGO();                                                           \
  VTKKWRCHelper_InitializeTrilinVariables();                                                       \
  VTKKWRCHelper_InitializeTrilinVariablesGO();                                                     \
  for (j = 0; j < imageInUseSize[1]; j++)                                                          \
  {                                                                                                \
    VTKKWRCHelper_OuterInitialization();                                                           \
    for (i = rowBounds[j * 2]; i <= rowBounds[j * 2 + 1]; i++)                                     \
    {                                                                                              \
      VTKKWRCHelper_InnerInitialization();

#define VTKKWRCHelper_InitializationAndLoopStartShadeTrilin()                                      \
  VTKKWRCHelper_InitializeVariables();                                                             \
  VTKKWRCHelper_InitializeVariablesShade();                                                        \
  VTKKWRCHelper_InitializeTrilinVariables();                                                       \
  VTKKWRCHelper_InitializeTrilinVariablesShade();                                                  \
  for (j = 0; j < imageInUseSize[1]; j++)                                                          \
  {                                                                                                \
    VTKKWRCHelper_OuterInitialization();                                                           \
    for (i = rowBounds[j * 2]; i <= rowBounds[j * 2 + 1]; i++)                                     \
    {                                                                                              \
      VTKKWRCHelper_InnerInitialization();

#define VTKKWRCHelper_InitializationAndLoopStartGOShadeTrilin()                                    \
  VTKKWRCHelper_InitializeVariables();                                                             \
  VTKKWRCHelper_InitializeVariablesShade();                                                        \
  VTKKWRCHelper_InitializeVariablesGO();                                                           \
  VTKKWRCHelper_InitializeTrilinVariables();                                                       \
  VTKKWRCHelper_InitializeTrilinVariablesShade();                                                  \
  VTKKWRCHelper_InitializeTrilinVariablesGO();                                                     \
  for (j = 0; j < imageInUseSize[1]; j++)                                                          \
  {                                                                                                \
    VTKKWRCHelper_OuterInitialization();                                                           \
    for (i = rowBounds[j * 2]; i <= rowBounds[j * 2 + 1]; i++)                                     \
    {                                                                                              \
      VTKKWRCHelper_InnerInitialization();

#define VTKKWRCHelper_IncrementAndLoopEnd()                                                        \
  imagePtr += 4;                                                                                   \
  }                                                                                                \
  if ((j / threadCount) % 8 == 7 && threadID == 0)                                                 \
  {                                                                                                \
    double fargs[1];                                                                               \
    fargs[0] = static_cast<double>(j) / static_cast<float>(imageInUseSize[1] - 1);                 \
    mapper->InvokeEvent(vtkCommand::VolumeMapperRenderProgressEvent, fargs);                       \
  }                                                                                                \
  }

#define VTKKWRCHelper_CroppingCheckTrilin(POS)                                                     \
  if (cropping)                                                                                    \
  {                                                                                                \
    if (mapper->CheckIfCropped(POS))                                                               \
    {                                                                                              \
      continue;                                                                                    \
    }                                                                                              \
  }

#define VTKKWRCHelper_CroppingCheckNN(POS)                                                         \
  if (cropping)                                                                                    \
  {                                                                                                \
    if (mapper->CheckIfCropped(POS))                                                               \
    {                                                                                              \
      continue;                                                                                    \
    }                                                                                              \
  }

#define VTKKWRCHelper_SpaceLeapSetup()                                                             \
  unsigned int mmpos[3];                                                                           \
  mmpos[0] = (pos[0] >> VTKKW_FPMM_SHIFT) + 1;                                                     \
  mmpos[1] = 0;                                                                                    \
  mmpos[2] = 0;                                                                                    \
  int mmvalid = 0;

#define VTKKWRCHelper_SpaceLeapSetupMulti()                                                        \
  unsigned int mmpos[3];                                                                           \
  mmpos[0] = (pos[0] >> VTKKW_FPMM_SHIFT) + 1;                                                     \
  mmpos[1] = 0;                                                                                    \
  mmpos[2] = 0;                                                                                    \
  int mmvalid[4] = { 0, 0, 0, 0 };

#define VTKKWRCHelper_SpaceLeapCheck()                                                             \
  if (pos[0] >> VTKKW_FPMM_SHIFT != mmpos[0] || pos[1] >> VTKKW_FPMM_SHIFT != mmpos[1] ||          \
    pos[2] >> VTKKW_FPMM_SHIFT != mmpos[2])                                                        \
  {                                                                                                \
    mmpos[0] = pos[0] >> VTKKW_FPMM_SHIFT;                                                         \
    mmpos[1] = pos[1] >> VTKKW_FPMM_SHIFT;                                                         \
    mmpos[2] = pos[2] >> VTKKW_FPMM_SHIFT;                                                         \
    mmvalid = mapper->CheckMinMaxVolumeFlag(mmpos, 0);                                             \
  }                                                                                                \
                                                                                                   \
  if (!mmvalid)                                                                                    \
  {                                                                                                \
    continue;                                                                                      \
  }

#define VTKKWRCHelper_MIPSpaceLeapCheck(MAXIDX, MAXIDXDEF, FLIP)                                   \
  if (pos[0] >> VTKKW_FPMM_SHIFT != mmpos[0] || pos[1] >> VTKKW_FPMM_SHIFT != mmpos[1] ||          \
    pos[2] >> VTKKW_FPMM_SHIFT != mmpos[2])                                                        \
  {                                                                                                \
    mmpos[0] = pos[0] >> VTKKW_FPMM_SHIFT;                                                         \
    mmpos[1] = pos[1] >> VTKKW_FPMM_SHIFT;                                                         \
    mmpos[2] = pos[2] >> VTKKW_FPMM_SHIFT;                                                         \
    mmvalid = (MAXIDXDEF) ? (mapper->CheckMIPMinMaxVolumeFlag(mmpos, 0, MAXIDX, FLIP)) : (1);      \
  }                                                                                                \
                                                                                                   \
  if (!mmvalid)                                                                                    \
  {                                                                                                \
    continue;                                                                                      \
  }

#define VTKKWRCHelper_MIPSpaceLeapPopulateMulti(MAXIDX, FLIP)                                      \
  if (pos[0] >> VTKKW_FPMM_SHIFT != mmpos[0] || pos[1] >> VTKKW_FPMM_SHIFT != mmpos[1] ||          \
    pos[2] >> VTKKW_FPMM_SHIFT != mmpos[2])                                                        \
  {                                                                                                \
    mmpos[0] = pos[0] >> VTKKW_FPMM_SHIFT;                                                         \
    mmpos[1] = pos[1] >> VTKKW_FPMM_SHIFT;                                                         \
    mmpos[2] = pos[2] >> VTKKW_FPMM_SHIFT;                                                         \
    for (c = 0; c < components; c++)                                                               \
    {                                                                                              \
      mmvalid[c] = mapper->CheckMIPMinMaxVolumeFlag(mmpos, c, MAXIDX[c], FLIP);                    \
    }                                                                                              \
  }

#define VTKKWRCHelper_MIPSpaceLeapCheckMulti(COMP, FLIP) mmvalid[COMP]

#include "vtkObject.h"
#include "vtkRenderingVolumeModule.h" // For export macro

class vtkFixedPointVolumeRayCastMapper;
class vtkVolume;

class VTKRENDERINGVOLUME_EXPORT vtkFixedPointVolumeRayCastHelper : public vtkObject
{
public:
  static vtkFixedPointVolumeRayCastHelper* New();
  vtkTypeMacro(vtkFixedPointVolumeRayCastHelper, vtkObject);
  void PrintSelf(ostream& os, vtkIndent indent) override;

  virtual void GenerateImage(int, int, vtkVolume*, vtkFixedPointVolumeRayCastMapper*) {}

protected:
  vtkFixedPointVolumeRayCastHelper();
  ~vtkFixedPointVolumeRayCastHelper() override;

private:
  vtkFixedPointVolumeRayCastHelper(const vtkFixedPointVolumeRayCastHelper&) = delete;
  void operator=(const vtkFixedPointVolumeRayCastHelper&) = delete;
};

#endif
