UNPKG

@cornerstonejs/core

Version:
131 lines (130 loc) 5.9 kB
import vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray.js'; import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData.js'; import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction.js'; import { InterpolationType, VOILUTFunctionType } from '../../enums/index.js'; import createLinearRGBTransferFunction from '../../utilities/createLinearRGBTransferFunction.js'; import createSigmoidRGBTransferFunction from '../../utilities/createSigmoidRGBTransferFunction.js'; import getVOIRangeFromWindowLevel from '../../utilities/getVOIRangeFromWindowLevel.js'; import isPTPrescaledWithSUV from '../../utilities/isPTPrescaledWithSUV.js'; import { getImageDataMetadata } from '../../utilities/getImageDataMetadata.js'; import invertRgbTransferFunction from '../../utilities/invertRgbTransferFunction.js'; import { resolveColormap } from '../../utilities/colormap.js'; import { updateVTKImageDataWithCornerstoneImage } from '../../utilities/updateVTKImageDataWithCornerstoneImage.js'; export function createEmptyVTKImageData(args) { const { dimensions, direction, numberOfComponents, origin, pixelArray, spacing, } = args; const values = ArrayBuffer.isView(pixelArray) && !(pixelArray instanceof DataView) ? pixelArray : Array.from(pixelArray); const dataType = ArrayBuffer.isView(values) && !(values instanceof DataView) ? vtkDataArray.getDataType(values) : undefined; const scalarArray = vtkDataArray.newInstance({ ...(dataType ? { dataType } : {}), name: 'Pixels', numberOfComponents, values, }); const imageData = vtkImageData.newInstance(); imageData.setDimensions(dimensions); imageData.setSpacing(spacing); imageData.setDirection(new Float32Array(Array.from(direction))); imageData.setOrigin(origin); imageData.getPointData().setScalars(scalarArray); return imageData; } export function createVTKImageDataFromImage(image) { const { dimensions, direction, numberOfComponents, origin, spacing } = getImageDataMetadata(image); const pixelArray = image.voxelManager.getScalarData().slice(); const imageData = createEmptyVTKImageData({ dimensions, direction: Array.from(direction), numberOfComponents, origin, pixelArray, spacing, }); updateVTKImageDataWithCornerstoneImage(imageData, image); return imageData; } export function updateVTKImageDataGeometryFromImage(imageData, image) { const { direction, origin, spacing } = getImageDataMetadata(image); imageData.setOrigin(origin); imageData.setDirection(new Float32Array(Array.from(direction))); imageData.setSpacing(spacing); } export function getDefaultImageVOIRange(image) { if (isPTPrescaledWithSUV(image)) { return { lower: 0, upper: 5 }; } return getVOIRangeFromWindowLevel(image.windowWidth, image.windowCenter, image.voiLUTFunction); } export function getPlanarCameraState(renderer) { const camera = renderer.getActiveCamera(); return { focalPoint: [...camera.getFocalPoint()], parallelScale: camera.getParallelScale(), position: [...camera.getPosition()], viewPlaneNormal: [...camera.getViewPlaneNormal()], viewUp: [...camera.getViewUp()], }; } export function applyPlanarImagePresentation(args) { const { actor, defaultVOIRange, defaultVOILUTFunction, props } = args; const property = actor.getProperty(); const voiRange = props?.voiRange ?? defaultVOIRange; if (props?.visible !== undefined) { actor.setVisibility(props.visible); } if (props?.opacity !== undefined) { property.setOpacity(props.opacity); } if (props?.interpolationType !== undefined) { property.setInterpolationType(props.interpolationType); } if (!voiRange) { return; } const transferFunction = createPlanarRGBTransferFunction({ colormap: props?.colormap, invert: props?.invert, voiRange, voiLUTFunction: props?.voiLUTFunction ?? defaultVOILUTFunction, }); property.setUseLookupTableScalarRange(true); property.setRGBTransferFunction(0, transferFunction); } export function createPlanarRGBTransferFunction(args) { const { colormap, invert, voiRange, voiLUTFunction } = args; const transferFunction = colormap?.name !== undefined ? createColormapTransferFunction(colormap, voiRange) : voiLUTFunction === VOILUTFunctionType.SAMPLED_SIGMOID ? createSigmoidRGBTransferFunction(voiRange) : createLinearRGBTransferFunction(voiRange); if (invert) { invertRgbTransferFunction(transferFunction); } return transferFunction; } function createColormapTransferFunction(colormap, voiRange) { const colormapName = colormap.name; const colormapDefinition = colormapName ? resolveColormap(colormapName) : undefined; if (!colormapDefinition) { throw new Error(`Colormap ${colormapName} not found`); } const transferFunction = vtkColorTransferFunction.newInstance(); transferFunction.applyColorMap(colormapDefinition); transferFunction.setMappingRange(voiRange.lower, voiRange.upper); return transferFunction; } export function applyPlanarCameraViewState(args) { const { initialCamera, renderer, viewState } = args; const camera = renderer.getActiveCamera(); const zoom = Math.max(viewState?.zoom ?? 1, 0.001); const [panX, panY] = viewState?.pan ?? [0, 0]; camera.setParallelProjection(true); camera.setParallelScale(initialCamera.parallelScale / zoom); camera.setFocalPoint(initialCamera.focalPoint[0] + panX, initialCamera.focalPoint[1] + panY, initialCamera.focalPoint[2]); camera.setPosition(initialCamera.position[0] + panX, initialCamera.position[1] + panY, initialCamera.position[2]); }