UNPKG

@cornerstonejs/core

Version:
115 lines (114 loc) 4.93 kB
import { vec3 } from 'gl-matrix'; import cache from '../../../cache/cache.js'; import { OrientationAxis } from '../../../enums/index.js'; import { getEffectiveRenderBackend } from '../../../init.js'; import * as metaData from '../../../metaData.js'; import { getRenderModeForBackend } from '../../helpers/renderBackendRegistry.js'; import { isValidVolume } from '../../../utilities/isValidVolume.js'; import { getOrientationFromScanAxisNormal } from '../../helpers/getCameraVectors.js'; export class PlanarRenderPathDecisionService { select(dataSet, options = {}) { if (!dataSet.imageIds.length) { throw new Error('[PlanarViewport] Cannot add an empty planar dataset'); } const orientation = options.orientation || OrientationAxis.ACQUISITION; const acquisitionOrientation = getPlanarAcquisitionOrientation(dataSet.imageIds); const volumeId = getVolumeId(dataSet); const isAcquisitionPath = orientation === OrientationAxis.ACQUISITION || (acquisitionOrientation !== undefined && orientation === acquisitionOrientation); const useVolumePath = isVolumeBackedDataSet(dataSet, isAcquisitionPath); if (!isAcquisitionPath && !useVolumePath && !dataSet.useWorldCoordinateImageData) { throw new Error('[PlanarViewport] Non-acquisition rendering requires a valid volume dataset'); } if (useVolumePath && !supportsVolumeRendering(dataSet)) { throw new Error('[PlanarViewport] Volume rendering requires a valid volume dataset'); } return { acquisitionOrientation, renderMode: useVolumePath ? this.selectVolumeRenderMode(options) : this.selectImageRenderMode(options), volumeId, }; } canRender(dataSet, options = {}) { if (!dataSet.imageIds.length) { return false; } const orientation = options.orientation || OrientationAxis.ACQUISITION; const acquisitionOrientation = getPlanarAcquisitionOrientation(dataSet.imageIds); const isAcquisitionPath = orientation === OrientationAxis.ACQUISITION || (acquisitionOrientation !== undefined && orientation === acquisitionOrientation); const useVolumePath = isVolumeBackedDataSet(dataSet, isAcquisitionPath); if (!isAcquisitionPath && !useVolumePath && !dataSet.useWorldCoordinateImageData) { return false; } if (useVolumePath && !supportsVolumeRendering(dataSet)) { return false; } return true; } selectImageRenderMode(options) { return getRenderModeForBackend(this.resolveBackend(options), 'image'); } selectVolumeRenderMode(options) { return getRenderModeForBackend(this.resolveBackend(options), 'volume'); } resolveBackend(options) { return getEffectiveRenderBackend(options.renderBackend); } } export const defaultPlanarRenderPathDecisionService = new PlanarRenderPathDecisionService(); export function selectPlanarRenderPath(dataSet, options = {}) { return defaultPlanarRenderPathDecisionService.select(dataSet, options); } export function getPlanarAcquisitionOrientation(imageIds) { const imageId = imageIds[0]; if (!imageId) { return; } const imagePlaneModule = metaData.get('imagePlaneModule', imageId); const imageOrientationPatient = imagePlaneModule?.imageOrientationPatient; if (!imageOrientationPatient || imageOrientationPatient.length !== 6) { return; } const rowVec = vec3.fromValues(imageOrientationPatient[0], imageOrientationPatient[1], imageOrientationPatient[2]); const colVec = vec3.fromValues(imageOrientationPatient[3], imageOrientationPatient[4], imageOrientationPatient[5]); const scanAxisNormal = vec3.create(); vec3.cross(scanAxisNormal, rowVec, colVec); const orientation = getOrientationFromScanAxisNormal([ scanAxisNormal[0], scanAxisNormal[1], scanAxisNormal[2], ]); if (orientation !== OrientationAxis.AXIAL && orientation !== OrientationAxis.CORONAL && orientation !== OrientationAxis.SAGITTAL) { return; } return orientation; } function getVolumeId(dataSet) { return dataSet.volumeId || cache.generateVolumeId(dataSet.imageIds); } function hasExplicitCachedVolume(dataSet) { return !!(dataSet.volumeId && cache.getVolume(dataSet.volumeId)); } function supportsVolumeRendering(dataSet) { return hasExplicitCachedVolume(dataSet) || isValidVolume(dataSet.imageIds); } function isVolumeBackedDataSet(dataSet, isAcquisitionPath) { if (dataSet.useWorldCoordinateImageData) { return false; } if (dataSet.volumeId) { return true; } return !isAcquisitionPath && supportsVolumeRendering(dataSet); }