UNPKG

@cornerstonejs/core

Version:
244 lines (243 loc) • 10 kB
import { vec3 } from 'gl-matrix'; import { ActorRenderMode } from '../../../types/index.js'; import getClosestImageId from '../../../utilities/getClosestImageId.js'; import imageIdToURI from '../../../utilities/imageIdToURI.js'; import isEqual from '../../../utilities/isEqual.js'; import getVolumeViewReferenceId from '../../../utilities/getVolumeViewReferenceId.js'; import { updatePlaneRestriction } from '../../../utilities/updatePlaneRestriction.js'; import { getDimensionGroupReferenceContext } from '../genericViewportReferenceCompatibility.js'; import { resolvePlanarViewportView } from './PlanarResolvedView.js'; export function getPlanarReferencedImageId(args) { const { rendering, viewRefSpecifier } = args; if (!rendering) { return; } const imageIds = getImageIds(args.data); if (!imageIds.length) { return; } if (rendering.renderMode === ActorRenderMode.CPU_IMAGE || rendering.renderMode === ActorRenderMode.VTK_IMAGE) { const imageIdIndex = typeof viewRefSpecifier?.sliceIndex === 'number' ? Math.min(Math.max(0, viewRefSpecifier.sliceIndex), imageIds.length - 1) : args.viewState?.slice?.kind === 'stackIndex' ? Math.min(Math.max(0, args.viewState.slice.imageIdIndex), imageIds.length - 1) : getCurrentSliceIndex(rendering); return imageIds[imageIdIndex]; } const resolvedView = getPlanarResolvedViewForReference({ viewState: args.viewState, data: args.data, frameOfReferenceUID: args.frameOfReferenceUID, renderContext: args.renderContext, rendering, sliceIndex: viewRefSpecifier?.sliceIndex, })?.toICamera(); if (!resolvedView?.focalPoint || !resolvedView.viewPlaneNormal) { return imageIds[Math.min(getCurrentSliceIndex(rendering), imageIds.length - 1)]; } return getClosestImageId(rendering.imageVolume, resolvedView.focalPoint, resolvedView.viewPlaneNormal); } export function getPlanarViewReference(args) { const { frameOfReferenceUID, rendering, viewRefSpecifier } = args; const { dimensionGroupNumber } = getDimensionGroupReferenceContext(args.data?.imageVolume); const sliceIndex = viewRefSpecifier?.sliceIndex ?? (rendering ? getCurrentSliceIndex(rendering) : undefined); const rangeEndSliceIndex = viewRefSpecifier?.rangeEndSliceIndex; const targetCamera = getPlanarResolvedViewForReference({ ...args, sliceIndex, })?.toICamera(); const cameraFocalPoint = toPoint3(targetCamera?.focalPoint); const viewPlaneNormal = toPoint3(targetCamera?.viewPlaneNormal); const viewUp = toPoint3(targetCamera?.viewUp); const inPlaneVector2 = viewUp && viewPlaneNormal ? toPoint3(vec3.cross(vec3.create(), viewUp, viewPlaneNormal)) : undefined; const viewReference = { FrameOfReferenceUID: frameOfReferenceUID, dataId: args.dataId, dimensionGroupNumber, cameraFocalPoint, viewPlaneNormal, viewUp, sliceIndex, planeRestriction: viewPlaneNormal && viewUp && cameraFocalPoint ? { FrameOfReferenceUID: frameOfReferenceUID, point: toPoint3(viewRefSpecifier?.points?.[0]) || cameraFocalPoint, inPlaneVector1: viewUp, inPlaneVector2, } : undefined, }; const referencedImageId = getPlanarReferencedImageId(args); const rangeEndReferencedImageId = typeof sliceIndex === 'number' && typeof rangeEndSliceIndex === 'number' && rangeEndSliceIndex > sliceIndex ? getPlanarReferencedImageId({ ...args, viewRefSpecifier: { ...viewRefSpecifier, sliceIndex: rangeEndSliceIndex, }, }) : undefined; if (rendering && (rendering.renderMode === ActorRenderMode.CPU_VOLUME || rendering.renderMode === ActorRenderMode.VTK_VOLUME_SLICE) && viewRefSpecifier?.forFrameOfReference !== true) { viewReference.volumeId = args.data?.volumeId; } if (referencedImageId) { viewReference.referencedImageId = referencedImageId; viewReference.referencedImageURI = imageIdToURI(referencedImageId); } if (rangeEndReferencedImageId && typeof rangeEndSliceIndex === 'number' && typeof sliceIndex === 'number' && rangeEndSliceIndex > sliceIndex) { viewReference.multiSliceReference = { FrameOfReferenceUID: frameOfReferenceUID, referencedImageId: rangeEndReferencedImageId, referencedImageURI: imageIdToURI(rangeEndReferencedImageId), sliceIndex: rangeEndSliceIndex, }; } if (viewRefSpecifier?.points && viewReference.planeRestriction) { updatePlaneRestriction(viewRefSpecifier.points, viewReference); } return viewReference; } export function getPlanarViewReferenceId(args) { const { rendering, viewRefSpecifier } = args; if (!rendering) { return null; } if (rendering.renderMode === ActorRenderMode.CPU_VOLUME || rendering.renderMode === ActorRenderMode.VTK_VOLUME_SLICE) { const resolvedView = getPlanarResolvedViewForReference({ ...args, sliceIndex: viewRefSpecifier?.sliceIndex, })?.toICamera(); const sliceIndex = viewRefSpecifier?.sliceIndex ?? getCurrentSliceIndex(rendering); const volumeId = args.data?.volumeId; if (!volumeId || !resolvedView?.viewPlaneNormal) { return null; } return getVolumeViewReferenceId({ sliceIndex, viewPlaneNormal: resolvedView.viewPlaneNormal, volumeId, }); } const referencedImageId = getPlanarReferencedImageId(args); return referencedImageId ? `imageId:${referencedImageId}` : null; } export function isPlanarPlaneViewable(args) { const { frameOfReferenceUID, options, planeRestriction } = args; if (planeRestriction.FrameOfReferenceUID !== frameOfReferenceUID) { return false; } const resolvedView = getPlanarResolvedViewForReference(args)?.toICamera(); const { focalPoint, viewPlaneNormal } = resolvedView || {}; if (!focalPoint || !viewPlaneNormal) { return false; } if (options?.withOrientation) { return true; } if (planeRestriction.inPlaneVector1 && !isEqual(0, vec3.dot(viewPlaneNormal, planeRestriction.inPlaneVector1))) { return false; } if (planeRestriction.inPlaneVector2 && !isEqual(0, vec3.dot(viewPlaneNormal, planeRestriction.inPlaneVector2))) { return false; } if (options?.withNavigation) { return true; } const { point } = planeRestriction; const pointVector = vec3.sub(vec3.create(), point, focalPoint); return isEqual(0, vec3.dot(pointVector, viewPlaneNormal)); } export function isPlanarReferenceViewable(args) { const { frameOfReferenceUID, imageIds, options = {}, viewRef } = args; if (!viewRef) { return false; } if (viewRef.planeRestriction) { return isPlanarPlaneViewable({ viewState: args.viewState, frameOfReferenceUID, options, planeRestriction: viewRef.planeRestriction, renderContext: args.renderContext, rendering: args.rendering, }); } if (viewRef.FrameOfReferenceUID && viewRef.FrameOfReferenceUID !== frameOfReferenceUID) { return false; } const resolvedView = getPlanarResolvedViewForReference(args)?.toICamera(); if (!resolvedView?.viewPlaneNormal) { return false; } if (viewRef.viewPlaneNormal && !isEqual(viewRef.viewPlaneNormal, resolvedView.viewPlaneNormal) && !isEqual(vec3.negate(vec3.create(), resolvedView.viewPlaneNormal), viewRef.viewPlaneNormal)) { return Boolean(options.withOrientation); } if (viewRef.referencedImageId || viewRef.referencedImageURI) { const referencedImageURI = viewRef.referencedImageURI || imageIdToURI(viewRef.referencedImageId); const currentSliceIndex = args.rendering ? getCurrentSliceIndex(args.rendering) : 0; const currentReferencedImageId = imageIds[currentSliceIndex]; if (currentReferencedImageId && imageIdToURI(currentReferencedImageId) === referencedImageURI) { return true; } const foundSliceIndex = imageIds.findIndex((imageId) => imageIdToURI(imageId) === referencedImageURI); if (foundSliceIndex === -1) { return false; } if (options.withNavigation) { return true; } const rangeEndSliceIndex = viewRef.multiSliceReference && imageIds.findIndex((imageId) => imageIdToURI(imageId) === imageIdToURI(viewRef.multiSliceReference.referencedImageId)); if (rangeEndSliceIndex !== undefined && rangeEndSliceIndex >= 0) { return (foundSliceIndex <= currentSliceIndex && currentSliceIndex <= rangeEndSliceIndex); } return currentSliceIndex === foundSliceIndex; } const currentSliceIndex = args.rendering ? getCurrentSliceIndex(args.rendering) : 0; const { sliceIndex } = viewRef; if (Array.isArray(sliceIndex)) { return (sliceIndex[0] <= currentSliceIndex && currentSliceIndex <= sliceIndex[1]); } return sliceIndex === undefined || sliceIndex === currentSliceIndex; } function getCurrentSliceIndex(rendering) { return rendering.currentImageIdIndex; } function getImageIds(payload) { return payload?.imageVolume?.imageIds || payload?.imageIds || []; } function toPoint3(point) { if (!point) { return; } return [point[0], point[1], point[2]]; } function getPlanarResolvedViewForReference(args) { return resolvePlanarViewportView(args); }