@kitware/vtk.js
Version:
Visualization Toolkit for the Web
315 lines (292 loc) • 12.9 kB
JavaScript
import { m as macro } from '../../macros2.js';
import { F as clampValue, M as floor } from '../../Common/Core/Math/index.js';
import vtkColorTransferFunction from './ColorTransferFunction.js';
import vtkPiecewiseFunction from '../../Common/DataModel/PiecewiseFunction.js';
import Constants from './VolumeProperty/Constants.js';
const {
InterpolationType,
OpacityMode,
FilterMode,
ColorMixPreset
} = Constants;
const {
vtkErrorMacro
} = macro;
const VTK_MAX_VRCOMP = 4;
// ----------------------------------------------------------------------------
// vtkVolumeProperty methods
// ----------------------------------------------------------------------------
function vtkVolumeProperty(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkVolumeProperty');
const superClass = {
...publicAPI
};
publicAPI.getMTime = () => {
let mTime = model.mtime;
let time;
for (let index = 0; index < VTK_MAX_VRCOMP; index++) {
// Color MTimes
if (model.componentData[index].colorChannels === 1) {
if (model.componentData[index].grayTransferFunction) {
// time that Gray transfer function was last modified
time = model.componentData[index].grayTransferFunction.getMTime();
mTime = mTime > time ? mTime : time;
}
} else if (model.componentData[index].colorChannels === 3) {
if (model.componentData[index].rGBTransferFunction) {
// time that RGB transfer function was last modified
time = model.componentData[index].rGBTransferFunction.getMTime();
mTime = mTime > time ? mTime : time;
}
}
// Opacity MTimes
if (model.componentData[index].scalarOpacity) {
// time that Scalar opacity transfer function was last modified
time = model.componentData[index].scalarOpacity.getMTime();
mTime = mTime > time ? mTime : time;
}
if (model.componentData[index].gradientOpacity) {
if (!model.componentData[index].disableGradientOpacity) {
// time that Gradient opacity transfer function was last modified
time = model.componentData[index].gradientOpacity.getMTime();
mTime = mTime > time ? mTime : time;
}
}
}
return mTime;
};
publicAPI.getColorChannels = index => {
if (index < 0 || index > 3) {
vtkErrorMacro('Bad index - must be between 0 and 3');
return 0;
}
return model.componentData[index].colorChannels;
};
// Set the color of a volume to a gray transfer function
publicAPI.setGrayTransferFunction = function () {
let index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
let func = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
let modified = false;
if (model.componentData[index].grayTransferFunction !== func) {
model.componentData[index].grayTransferFunction = func;
modified = true;
}
if (model.componentData[index].colorChannels !== 1) {
model.componentData[index].colorChannels = 1;
modified = true;
}
if (modified) {
publicAPI.modified();
}
return modified;
};
// Get the currently set gray transfer function. Create one if none set.
publicAPI.getGrayTransferFunction = function () {
let index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
if (model.componentData[index].grayTransferFunction === null) {
model.componentData[index].grayTransferFunction = vtkPiecewiseFunction.newInstance();
model.componentData[index].grayTransferFunction.addPoint(0, 0.0);
model.componentData[index].grayTransferFunction.addPoint(1024, 1.0);
if (model.componentData[index].colorChannels !== 1) {
model.componentData[index].colorChannels = 1;
}
publicAPI.modified();
}
return model.componentData[index].grayTransferFunction;
};
// Set the color of a volume to an RGB transfer function
publicAPI.setRGBTransferFunction = function () {
let index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
let func = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
let modified = false;
if (model.componentData[index].rGBTransferFunction !== func) {
model.componentData[index].rGBTransferFunction = func;
modified = true;
}
if (model.componentData[index].colorChannels !== 3) {
model.componentData[index].colorChannels = 3;
modified = true;
}
if (modified) {
publicAPI.modified();
}
return modified;
};
// Get the currently set RGB transfer function. Create one if none set.
publicAPI.getRGBTransferFunction = function () {
let index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
if (model.componentData[index].rGBTransferFunction === null) {
model.componentData[index].rGBTransferFunction = vtkColorTransferFunction.newInstance();
model.componentData[index].rGBTransferFunction.addRGBPoint(0, 0.0, 0.0, 0.0);
model.componentData[index].rGBTransferFunction.addRGBPoint(1024, 1.0, 1.0, 1.0);
if (model.componentData[index].colorChannels !== 3) {
model.componentData[index].colorChannels = 3;
}
publicAPI.modified();
}
return model.componentData[index].rGBTransferFunction;
};
// Set the scalar opacity of a volume to a transfer function
publicAPI.setScalarOpacity = function () {
let index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
let func = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
if (model.componentData[index].scalarOpacity !== func) {
model.componentData[index].scalarOpacity = func;
publicAPI.modified();
return true;
}
return false;
};
// Get the scalar opacity transfer function. Create one if none set.
publicAPI.getScalarOpacity = function () {
let index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
if (model.componentData[index].scalarOpacity === null) {
model.componentData[index].scalarOpacity = vtkPiecewiseFunction.newInstance();
model.componentData[index].scalarOpacity.addPoint(0, 1.0);
model.componentData[index].scalarOpacity.addPoint(1024, 1.0);
publicAPI.modified();
}
return model.componentData[index].scalarOpacity;
};
publicAPI.setComponentWeight = function () {
let index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
let value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
if (index < 0 || index >= VTK_MAX_VRCOMP) {
vtkErrorMacro('Invalid index');
return false;
}
const val = Math.min(1, Math.max(0, value));
if (model.componentData[index].componentWeight !== val) {
model.componentData[index].componentWeight = val;
publicAPI.modified();
return true;
}
return false;
};
publicAPI.getComponentWeight = function () {
let index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
if (index < 0 || index >= VTK_MAX_VRCOMP) {
vtkErrorMacro('Invalid index');
return 0.0;
}
return model.componentData[index].componentWeight;
};
publicAPI.setInterpolationTypeToNearest = () => publicAPI.setInterpolationType(InterpolationType.NEAREST);
publicAPI.setInterpolationTypeToLinear = () => publicAPI.setInterpolationType(InterpolationType.LINEAR);
publicAPI.setInterpolationTypeToFastLinear = () => publicAPI.setInterpolationType(InterpolationType.FAST_LINEAR);
publicAPI.getInterpolationTypeAsString = () => macro.enumToString(InterpolationType, model.interpolationType);
const sets = ['useGradientOpacity', 'scalarOpacityUnitDistance', 'gradientOpacityMinimumValue', 'gradientOpacityMinimumOpacity', 'gradientOpacityMaximumValue', 'gradientOpacityMaximumOpacity', 'opacityMode', 'forceNearestInterpolation'];
sets.forEach(val => {
const cap = macro.capitalize(val);
publicAPI[`set${cap}`] = (index, value) => {
if (model.componentData[index][`${val}`] !== value) {
model.componentData[index][`${val}`] = value;
publicAPI.modified();
return true;
}
return false;
};
});
const gets = ['useGradientOpacity', 'scalarOpacityUnitDistance', 'gradientOpacityMinimumValue', 'gradientOpacityMinimumOpacity', 'gradientOpacityMaximumValue', 'gradientOpacityMaximumOpacity', 'opacityMode', 'forceNearestInterpolation'];
gets.forEach(val => {
const cap = macro.capitalize(val);
publicAPI[`get${cap}`] = index => model.componentData[index][`${val}`];
});
publicAPI.setAverageIPScalarRange = (min, max) => {
console.warn('setAverageIPScalarRange is deprecated use setIpScalarRange');
publicAPI.setIpScalarRange(min, max);
};
publicAPI.getFilterModeAsString = () => macro.enumToString(FilterMode, model.filterMode);
publicAPI.setFilterModeToOff = () => {
publicAPI.setFilterMode(FilterMode.OFF);
};
publicAPI.setFilterModeToNormalized = () => {
publicAPI.setFilterMode(FilterMode.NORMALIZED);
};
publicAPI.setFilterModeToRaw = () => {
publicAPI.setFilterMode(FilterMode.RAW);
};
publicAPI.setGlobalIlluminationReach = gl => superClass.setGlobalIlluminationReach(clampValue(gl, 0.0, 1.0));
publicAPI.setVolumetricScatteringBlending = vsb => superClass.setVolumetricScatteringBlending(clampValue(vsb, 0.0, 1.0));
publicAPI.setAnisotropy = at => superClass.setAnisotropy(clampValue(at, -0.99, 0.99));
publicAPI.setLAOKernelSize = ks => superClass.setLAOKernelSize(floor(clampValue(ks, 1, 32)));
publicAPI.setLAOKernelRadius = kr => superClass.setLAOKernelRadius(kr >= 1 ? kr : 1);
}
// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------
const defaultValues = initialValues => ({
colorMixPreset: ColorMixPreset.DEFAULT,
independentComponents: true,
interpolationType: InterpolationType.FAST_LINEAR,
shade: false,
ambient: 0.1,
diffuse: 0.7,
specular: 0.2,
specularPower: 10.0,
useLabelOutline: false,
labelOutlineThickness: [1],
labelOutlineOpacity: 1.0,
// Properties moved from volume mapper
ipScalarRange: [-1000000.0, 1000000.0],
filterMode: FilterMode.OFF,
// ignored by WebGL so no behavior change
preferSizeOverAccuracy: false,
// Whether to use halfFloat representation of float, when it is inaccurate
computeNormalFromOpacity: false,
// volume shadow parameters
volumetricScatteringBlending: 0.0,
globalIlluminationReach: 0.0,
anisotropy: 0.0,
// local ambient occlusion
localAmbientOcclusion: false,
LAOKernelSize: 15,
LAOKernelRadius: 7,
updatedExtents: [],
...initialValues
});
// ----------------------------------------------------------------------------
function extend(publicAPI, model) {
let initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
Object.assign(model, defaultValues(initialValues));
// Build VTK API
macro.obj(publicAPI, model);
if (!model.componentData) {
model.componentData = [];
for (let i = 0; i < VTK_MAX_VRCOMP; ++i) {
model.componentData.push({
colorChannels: 1,
grayTransferFunction: null,
rGBTransferFunction: null,
scalarOpacity: null,
scalarOpacityUnitDistance: 1.0,
opacityMode: OpacityMode.FRACTIONAL,
gradientOpacityMinimumValue: 0,
gradientOpacityMinimumOpacity: 0.0,
gradientOpacityMaximumValue: 1.0,
gradientOpacityMaximumOpacity: 1.0,
useGradientOpacity: false,
componentWeight: 1.0,
forceNearestInterpolation: false
});
}
}
macro.setGet(publicAPI, model, ['colorMixPreset', 'independentComponents', 'interpolationType', 'shade', 'ambient', 'diffuse', 'specular', 'specularPower', 'useLabelOutline', 'labelOutlineOpacity',
// Properties moved from volume mapper
'filterMode', 'preferSizeOverAccuracy', 'computeNormalFromOpacity', 'volumetricScatteringBlending', 'globalIlluminationReach', 'anisotropy', 'localAmbientOcclusion', 'LAOKernelSize', 'LAOKernelRadius', 'updatedExtents']);
// Property moved from volume mapper
macro.setGetArray(publicAPI, model, ['ipScalarRange'], 2);
macro.setGetArray(publicAPI, model, ['labelOutlineThickness']);
// Object methods
vtkVolumeProperty(publicAPI, model);
}
// ----------------------------------------------------------------------------
const newInstance = macro.newInstance(extend, 'vtkVolumeProperty');
// ----------------------------------------------------------------------------
var vtkVolumeProperty$1 = {
newInstance,
extend,
...Constants
};
export { vtkVolumeProperty$1 as default, extend, newInstance };