mirror of https://gitee.com/openkylin/vtk9.git
163 lines
5.9 KiB
C++
163 lines
5.9 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkUnstructuredGridPartialPreIntegration.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.
|
|
|
|
=========================================================================*/
|
|
|
|
/*
|
|
* Copyright 2004 Sandia Corporation.
|
|
* Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
|
* license for use of this work by or on behalf of the
|
|
* U.S. Government. Redistribution and use in source and binary forms, with
|
|
* or without modification, are permitted provided that this Notice and any
|
|
* statement of authorship are reproduced on all copies.
|
|
*/
|
|
|
|
/**
|
|
* @class vtkUnstructuredGridPartialPreIntegration
|
|
* @brief performs piecewise linear ray integration.
|
|
*
|
|
*
|
|
*
|
|
* vtkUnstructuredGridPartialPreIntegration performs piecewise linear ray
|
|
* integration. This will give the same results as
|
|
* vtkUnstructuredGridLinearRayIntegration (with potentially a error due to
|
|
* table lookup quantization), but should be notably faster. The algorithm
|
|
* used is given by Moreland and Angel, "A Fast High Accuracy Volume
|
|
* Renderer for Unstructured Data."
|
|
*
|
|
* This class is thread safe only after the first instance is created.
|
|
*
|
|
*/
|
|
|
|
#ifndef vtkUnstructuredGridPartialPreIntegration_h
|
|
#define vtkUnstructuredGridPartialPreIntegration_h
|
|
|
|
#include "vtkMath.h" // For all the inline methods
|
|
#include "vtkRenderingVolumeModule.h" // For export macro
|
|
#include "vtkUnstructuredGridVolumeRayIntegrator.h"
|
|
|
|
class vtkPartialPreIntegrationTransferFunction;
|
|
class vtkVolumeProperty;
|
|
|
|
class VTKRENDERINGVOLUME_EXPORT vtkUnstructuredGridPartialPreIntegration
|
|
: public vtkUnstructuredGridVolumeRayIntegrator
|
|
{
|
|
public:
|
|
vtkTypeMacro(vtkUnstructuredGridPartialPreIntegration, vtkUnstructuredGridVolumeRayIntegrator);
|
|
static vtkUnstructuredGridPartialPreIntegration* New();
|
|
void PrintSelf(ostream& os, vtkIndent indent) override;
|
|
|
|
void Initialize(vtkVolume* volume, vtkDataArray* scalars) override;
|
|
|
|
void Integrate(vtkDoubleArray* intersectionLengths, vtkDataArray* nearIntersections,
|
|
vtkDataArray* farIntersections, float color[4]) override;
|
|
|
|
///@{
|
|
/**
|
|
* Integrates a single ray segment. \c color is blended with the result
|
|
* (with \c color in front). The result is written back into \c color.
|
|
*/
|
|
static void IntegrateRay(double length, double intensity_front, double attenuation_front,
|
|
double intensity_back, double attenuation_back, float color[4]);
|
|
static void IntegrateRay(double length, const double color_front[3], double attenuation_front,
|
|
const double color_back[3], double attenuation_back, float color[4]);
|
|
///@}
|
|
|
|
///@{
|
|
/**
|
|
* Looks up Psi (as defined by Moreland and Angel, "A Fast High Accuracy
|
|
* Volume Renderer for Unstructured Data") in a table. The table must be
|
|
* created first, which happens on the first instantiation of this class
|
|
* or when BuildPsiTable is first called.
|
|
*/
|
|
static float Psi(float taufD, float taubD);
|
|
static float* GetPsiTable(int& size);
|
|
static void BuildPsiTable();
|
|
///@}
|
|
|
|
protected:
|
|
vtkUnstructuredGridPartialPreIntegration();
|
|
~vtkUnstructuredGridPartialPreIntegration() override;
|
|
|
|
vtkVolumeProperty* Property;
|
|
|
|
vtkPartialPreIntegrationTransferFunction* TransferFunctions;
|
|
vtkTimeStamp TransferFunctionsModified;
|
|
int NumIndependentComponents;
|
|
|
|
enum
|
|
{
|
|
PSI_TABLE_SIZE = 512
|
|
};
|
|
|
|
static float PsiTable[PSI_TABLE_SIZE * PSI_TABLE_SIZE];
|
|
static int PsiTableBuilt;
|
|
|
|
private:
|
|
vtkUnstructuredGridPartialPreIntegration(
|
|
const vtkUnstructuredGridPartialPreIntegration&) = delete;
|
|
void operator=(const vtkUnstructuredGridPartialPreIntegration&) = delete;
|
|
};
|
|
|
|
inline float vtkUnstructuredGridPartialPreIntegration::Psi(float taufD, float taubD)
|
|
{
|
|
float gammaf = taufD / (taufD + 1);
|
|
float gammab = taubD / (taubD + 1);
|
|
int gammafi = vtkMath::Floor(gammaf * PSI_TABLE_SIZE);
|
|
int gammabi = vtkMath::Floor(gammab * PSI_TABLE_SIZE);
|
|
return PsiTable[gammafi * PSI_TABLE_SIZE + gammabi];
|
|
}
|
|
|
|
inline float* vtkUnstructuredGridPartialPreIntegration::GetPsiTable(int& size)
|
|
{
|
|
size = PSI_TABLE_SIZE;
|
|
return PsiTable;
|
|
}
|
|
|
|
inline void vtkUnstructuredGridPartialPreIntegration::IntegrateRay(double length,
|
|
double intensity_front, double attenuation_front, double intensity_back, double attenuation_back,
|
|
float color[4])
|
|
{
|
|
float taufD = length * attenuation_front;
|
|
float taubD = length * attenuation_back;
|
|
float Psi = vtkUnstructuredGridPartialPreIntegration::Psi(taufD, taubD);
|
|
float zeta = static_cast<float>(exp(-0.5 * (taufD + taubD)));
|
|
float alpha = 1 - zeta;
|
|
|
|
float newintensity =
|
|
(1 - color[3]) * (intensity_front * (1 - Psi) + intensity_back * (Psi - zeta));
|
|
// Is setting the RGB values the same the right thing to do?
|
|
color[0] += newintensity;
|
|
color[1] += newintensity;
|
|
color[2] += newintensity;
|
|
color[3] += (1 - color[3]) * alpha;
|
|
}
|
|
|
|
inline void vtkUnstructuredGridPartialPreIntegration::IntegrateRay(double length,
|
|
const double color_front[3], double attenuation_front, const double color_back[3],
|
|
double attenuation_back, float color[4])
|
|
{
|
|
float taufD = length * attenuation_front;
|
|
float taubD = length * attenuation_back;
|
|
float Psi = vtkUnstructuredGridPartialPreIntegration::Psi(taufD, taubD);
|
|
float zeta = static_cast<float>(exp(-0.5 * (taufD + taubD)));
|
|
float alpha = 1 - zeta;
|
|
|
|
color[0] += (1 - color[3]) * (color_front[0] * (1 - Psi) + color_back[0] * (Psi - zeta));
|
|
color[1] += (1 - color[3]) * (color_front[1] * (1 - Psi) + color_back[1] * (Psi - zeta));
|
|
color[2] += (1 - color[3]) * (color_front[2] * (1 - Psi) + color_back[2] * (Psi - zeta));
|
|
color[3] += (1 - color[3]) * alpha;
|
|
}
|
|
|
|
#endif // vtkUnstructuredGridPartialPreIntegration_h
|