From 433d8c129172494827827bc1a058627f361fb68e Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 3 Nov 2022 14:21:13 +0000 Subject: [PATCH 1/7] Extract common volume viewport functionality to base class --- common/reviews/api/core.api.md | 4623 +++++++++-------- .../src/RenderingEngine/BaseVolumeViewport.ts | 674 +++ .../src/RenderingEngine/RenderingEngine.ts | 5 +- .../src/RenderingEngine/VolumeViewport.ts | 605 +-- .../helpers/addVolumesToViewports.ts | 7 +- .../helpers/setVolumesForViewports.ts | 8 +- .../helpers/volumeNewImageEventDispatcher.ts | 6 +- packages/core/src/index.ts | 2 + .../createLabelmapVolumeForViewport.ts | 2 +- .../utilities/viewport/isViewportPreScaled.ts | 4 +- 10 files changed, 3046 insertions(+), 2890 deletions(-) create mode 100644 packages/core/src/RenderingEngine/BaseVolumeViewport.ts diff --git a/common/reviews/api/core.api.md b/common/reviews/api/core.api.md index 9871fdd2c0..62de40822f 100644 --- a/common/reviews/api/core.api.md +++ b/common/reviews/api/core.api.md @@ -1,2299 +1,2324 @@ -## API Report File for "@cornerstonejs/core" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts - -import { mat4 } from 'gl-matrix'; -import { vec3 } from 'gl-matrix'; -import type vtkActor from '@kitware/vtk.js/Rendering/Core/Actor'; -import type { vtkCamera } from '@kitware/vtk.js/Rendering/Core/Camera'; -import type { vtkImageData } from '@kitware/vtk.js/Common/DataModel/ImageData'; -import vtkImageSlice from '@kitware/vtk.js/Rendering/Core/ImageSlice'; -import type { vtkObject } from '@kitware/vtk.js/interfaces'; -import vtkPlane from '@kitware/vtk.js/Common/DataModel/Plane'; -import type vtkVolume from '@kitware/vtk.js/Rendering/Core/Volume'; - -// @public (undocumented) -type Actor = vtkActor; - -// @public (undocumented) -type ActorEntry = { - uid: string; - actor: Actor | VolumeActor | ImageActor; - referenceId?: string; - slabThickness?: number; -}; - -// @public (undocumented) -type ActorSliceRange = { - actor: VolumeActor; - viewPlaneNormal: Point3; - focalPoint: Point3; - min: number; - max: number; - current: number; -}; - -// @public (undocumented) -function addProvider(provider: (type: string, query: any) => any, priority?: number): void; - -// @public (undocumented) -export function addVolumesToViewports(renderingEngine: IRenderingEngine, volumeInputs: Array, viewportIds: Array, immediateRender?: boolean, suppressEvents?: boolean): Promise; - -// @public (undocumented) -enum BlendModes { - // (undocumented) - AVERAGE_INTENSITY_BLEND = 3, - // (undocumented) - COMPOSITE = 0, - // (undocumented) - MAXIMUM_INTENSITY_BLEND = 1, - // (undocumented) - MINIMUM_INTENSITY_BLEND = 2 -} - -// @public (undocumented) -export const cache: Cache_2; - -// @public (undocumented) -function calculateViewportsSpatialRegistration(viewport1: IStackViewport, viewport2: IStackViewport): void; - -// @public (undocumented) -type CameraModifiedEvent = CustomEvent_2; - -// @public (undocumented) -type CameraModifiedEventDetail = { - previousCamera: ICamera; - camera: ICamera; - element: HTMLDivElement; - viewportId: string; - renderingEngineId: string; - rotation?: number; -}; - -// @public (undocumented) -function cancelLoadAll(): void; - -// @public (undocumented) -function cancelLoadImage(imageId: string): void; - -// @public (undocumented) -function cancelLoadImages(imageIds: Array): void; - -// @public (undocumented) -const colormapsData: CPUFallbackColormapsData; - -declare namespace CONSTANTS { - export { - colormapsData as CPU_COLORMAPS, - RENDERING_DEFAULTS, - mprCameraValues as MPR_CAMERA_VALUES, - EPSILON - } -} -export { CONSTANTS } - -// @public (undocumented) -interface CPUFallbackColormap { - // (undocumented) - addColor: (rgba: Point4) => void; - // (undocumented) - buildLookupTable: (lut: CPUFallbackLookupTable) => void; - // (undocumented) - clearColors: () => void; - // (undocumented) - createLookupTable: () => CPUFallbackLookupTable; - // (undocumented) - getColor: (index: number) => Point4; - // (undocumented) - getColorRepeating: (index: number) => Point4; - // (undocumented) - getColorSchemeName: () => string; - // (undocumented) - getId: () => string; - // (undocumented) - getNumberOfColors: () => number; - // (undocumented) - insertColor: (index: number, rgba: Point4) => void; - // (undocumented) - isValidIndex: (index: number) => boolean; - // (undocumented) - removeColor: (index: number) => void; - // (undocumented) - setColor: (index: number, rgba: Point4) => void; - // (undocumented) - setColorSchemeName: (name: string) => void; - // (undocumented) - setNumberOfColors: (numColors: number) => void; -} - -// @public (undocumented) -type CPUFallbackColormapData = { - name: string; - numOfColors?: number; - colors?: Point4[]; - segmentedData?: unknown; - numColors?: number; - gamma?: number; -}; - -// @public (undocumented) -type CPUFallbackColormapsData = { - [key: string]: CPUFallbackColormapData; -}; - -// @public (undocumented) -interface CPUFallbackEnabledElement { - // (undocumented) - canvas?: HTMLCanvasElement; - // (undocumented) - colormap?: CPUFallbackColormap; - // (undocumented) - image?: IImage; - // (undocumented) - invalid?: boolean; - // (undocumented) - metadata?: { - direction?: Mat3; - dimensions?: Point3; - spacing?: Point3; - origin?: Point3; - imagePlaneModule?: { - frameOfReferenceUID: string; - rows: number; - columns: number; - imageOrientationPatient: number[]; - rowCosines: Point3; - columnCosines: Point3; - imagePositionPatient: number[]; - sliceThickness?: number; - sliceLocation?: number; - pixelSpacing: Point2; - rowPixelSpacing: number; - columnPixelSpacing: number; - }; - imagePixelModule?: { - samplesPerPixel: number; - photometricInterpretation: string; - rows: number; - columns: number; - bitsAllocated: number; - bitsStored: number; - highBit: number; - pixelRepresentation: number; - planarConfiguration?: number; - pixelAspectRatio?: number; - smallestPixelValue?: number; - largestPixelValue?: number; - redPaletteColorLookupTableDescriptor?: number[]; - greenPaletteColorLookupTableDescriptor?: number[]; - bluePaletteColorLookupTableDescriptor?: number[]; - redPaletteColorLookupTableData: number[]; - greenPaletteColorLookupTableData: number[]; - bluePaletteColorLookupTableData: number[]; - }; - }; - // (undocumented) - needsRedraw?: boolean; - // (undocumented) - options?: { - [key: string]: unknown; - colormap?: CPUFallbackColormap; - }; - // (undocumented) - pan?: Point2; - // (undocumented) - renderingTools?: CPUFallbackRenderingTools; - // (undocumented) - rotation?: number; - // (undocumented) - scale?: number; - // (undocumented) - transform?: CPUFallbackTransform; - // (undocumented) - viewport?: CPUFallbackViewport; - // (undocumented) - zoom?: number; -} - -// @public (undocumented) -interface CPUFallbackLookupTable { - // (undocumented) - build: (force: boolean) => void; - // (undocumented) - getColor: (scalar: number) => Point4; - // (undocumented) - setAlphaRange: (start: number, end: number) => void; - // (undocumented) - setHueRange: (start: number, end: number) => void; - // (undocumented) - setNumberOfTableValues: (number: number) => void; - // (undocumented) - setRamp: (ramp: string) => void; - // (undocumented) - setRange: (start: number, end: number) => void; - // (undocumented) - setSaturationRange: (start: number, end: number) => void; - // (undocumented) - setTableRange: (start: number, end: number) => void; - // (undocumented) - setTableValue(index: number, rgba: Point4): any; - // (undocumented) - setValueRange: (start: number, end: number) => void; -} - -// @public (undocumented) -type CPUFallbackLUT = { - lut: number[]; -}; - -// @public (undocumented) -type CPUFallbackRenderingTools = { - renderCanvas?: HTMLCanvasElement; - lastRenderedIsColor?: boolean; - lastRenderedImageId?: string; - lastRenderedViewport?: { - windowWidth: number | number[]; - windowCenter: number | number[]; - invert: boolean; - rotation: number; - hflip: boolean; - vflip: boolean; - modalityLUT: CPUFallbackLUT; - voiLUT: CPUFallbackLUT; - colormap: unknown; - }; - renderCanvasContext?: CanvasRenderingContext2D; - colormapId?: string; - colorLUT?: CPUFallbackLookupTable; - renderCanvasData?: ImageData; -}; - -// @public (undocumented) -interface CPUFallbackTransform { - // (undocumented) - clone: () => CPUFallbackTransform; - // (undocumented) - getMatrix: () => TransformMatrix2D; - // (undocumented) - invert: () => void; - // (undocumented) - multiply: (matrix: TransformMatrix2D) => void; - // (undocumented) - reset: () => void; - // (undocumented) - rotate: (rad: number) => void; - // (undocumented) - scale: (sx: number, sy: number) => void; - // (undocumented) - transformPoint: (point: Point2) => Point2; - // (undocumented) - translate: (x: number, y: number) => void; -} - -// @public (undocumented) -type CPUFallbackViewport = { - scale?: number; - parallelScale?: number; - focalPoint?: number[]; - translation?: { - x: number; - y: number; - }; - voi?: { - windowWidth: number; - windowCenter: number; - }; - invert?: boolean; - pixelReplication?: boolean; - rotation?: number; - hflip?: boolean; - vflip?: boolean; - modalityLUT?: CPUFallbackLUT; - voiLUT?: CPUFallbackLUT; - colormap?: CPUFallbackColormap; - displayedArea?: CPUFallbackViewportDisplayedArea; - modality?: string; -}; - -// @public (undocumented) -type CPUFallbackViewportDisplayedArea = { - tlhc: { - x: number; - y: number; - }; - brhc: { - x: number; - y: number; - }; - rowPixelSpacing: number; - columnPixelSpacing: number; - presentationSizeMode: string; -}; - -// @public (undocumented) -type CPUIImageData = { - dimensions: Point3; - direction: Mat3; - spacing: Point3; - origin: Point3; - imageData: CPUImageData; - metadata: { - Modality: string; - }; - scalarData: number[]; - scaling: Scaling; - hasPixelSpacing?: boolean; - preScale?: { - scaled?: boolean; - scalingParameters?: { - modality?: string; - rescaleSlope?: number; - rescaleIntercept?: number; - suvbw?: number; - }; - }; -}; - -// @public (undocumented) -type CPUImageData = { - worldToIndex?: (point: Point3) => Point3; - indexToWorld?: (point: Point3) => Point3; - getWorldToIndex?: () => Point3; - getIndexToWorld?: () => Point3; - getSpacing?: () => Point3; - getDirection?: () => Mat3; - getScalarData?: () => number[]; - getDimensions?: () => Point3; -}; - -// @public (undocumented) -function createAndCacheDerivedVolume(referencedVolumeId: string, options: DerivedVolumeOptions): Promise; - -// @public (undocumented) -function createAndCacheVolume(volumeId: string, options: VolumeLoaderOptions): Promise>; - -// @public (undocumented) -function createFloat32SharedArray(length: number): Float32Array; - -// @public (undocumented) -function createLocalVolume(options: LocalVolumeOptions, volumeId: string, preventCache?: boolean): ImageVolume; - -// @public (undocumented) -function createUint8SharedArray(length: number): Uint8Array; - -// @public (undocumented) -export function createVolumeActor(props: createVolumeActorInterface, element: HTMLDivElement, viewportId: string, suppressEvents?: boolean): Promise; - -// @public (undocumented) -export function createVolumeMapper(imageData: any, vtkOpenGLTexture: any): any; - -// @public (undocumented) -interface CustomEvent_2 extends Event { - // (undocumented) - readonly detail: T; - // (undocumented) - initCustomEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, detailArg: T): void; -} - -// @public (undocumented) -type ElementDisabledEvent = CustomEvent_2; - -// @public (undocumented) -type ElementDisabledEventDetail = { - element: HTMLDivElement; - viewportId: string; - renderingEngineId: string; -}; - -// @public (undocumented) -type ElementEnabledEvent = CustomEvent_2; - -// @public (undocumented) -type ElementEnabledEventDetail = { - element: HTMLDivElement; - viewportId: string; - renderingEngineId: string; -}; - -declare namespace Enums { - export { - EVENTS as Events, - BlendModes, - InterpolationType, - RequestType, - ViewportType, - OrientationAxis - } -} -export { Enums } - -// @public (undocumented) -const EPSILON = 0.001; - -// @public (undocumented) -export enum EVENTS { - // (undocumented) - CACHE_SIZE_EXCEEDED = "CACHE_SIZE_EXCEEDED", - // (undocumented) - CAMERA_MODIFIED = "CORNERSTONE_CAMERA_MODIFIED", - // (undocumented) - CAMERA_RESET = "CORNERSTONE_CAMERA_RESET", - // (undocumented) - ELEMENT_DISABLED = "CORNERSTONE_ELEMENT_DISABLED", - // (undocumented) - ELEMENT_ENABLED = "CORNERSTONE_ELEMENT_ENABLED", - // (undocumented) - IMAGE_CACHE_IMAGE_ADDED = "CORNERSTONE_IMAGE_CACHE_IMAGE_ADDED", - // (undocumented) - IMAGE_CACHE_IMAGE_REMOVED = "CORNERSTONE_IMAGE_CACHE_IMAGE_REMOVED", - // (undocumented) - IMAGE_LOAD_ERROR = "IMAGE_LOAD_ERROR", - // (undocumented) - IMAGE_LOAD_FAILED = "CORNERSTONE_IMAGE_LOAD_FAILED", - // (undocumented) - IMAGE_LOAD_PROGRESS = "CORNERSTONE_IMAGE_LOAD_PROGRESS", - // (undocumented) - IMAGE_LOADED = "CORNERSTONE_IMAGE_LOADED", - // (undocumented) - IMAGE_RENDERED = "CORNERSTONE_IMAGE_RENDERED", - // (undocumented) - IMAGE_SPACING_CALIBRATED = "CORNERSTONE_IMAGE_SPACING_CALIBRATED", - // (undocumented) - IMAGE_VOLUME_MODIFIED = "CORNERSTONE_IMAGE_VOLUME_MODIFIED", - // (undocumented) - PRE_STACK_NEW_IMAGE = "CORNERSTONE_PRE_STACK_NEW_IMAGE", - // (undocumented) - STACK_NEW_IMAGE = "CORNERSTONE_STACK_NEW_IMAGE", - // (undocumented) - STACK_VIEWPORT_NEW_STACK = "CORNERSTONE_STACK_VIEWPORT_NEW_STACK", - // (undocumented) - STACK_VIEWPORT_SCROLL = "CORNERSTONE_STACK_VIEWPORT_SCROLL", - // (undocumented) - VOI_MODIFIED = "CORNERSTONE_VOI_MODIFIED", - // (undocumented) - VOLUME_CACHE_VOLUME_ADDED = "CORNERSTONE_VOLUME_CACHE_VOLUME_ADDED", - // (undocumented) - VOLUME_CACHE_VOLUME_REMOVED = "CORNERSTONE_VOLUME_CACHE_VOLUME_REMOVED", - // (undocumented) - VOLUME_LOADED = "CORNERSTONE_VOLUME_LOADED", - // (undocumented) - VOLUME_LOADED_FAILED = "CORNERSTONE_VOLUME_LOADED_FAILED", - // (undocumented) - VOLUME_NEW_IMAGE = "CORNERSTONE_VOLUME_NEW_IMAGE", - // (undocumented) - VOLUME_VIEWPORT_NEW_VOLUME = "CORNERSTONE_VOLUME_VIEWPORT_NEW_VOLUME" -} - -// @public (undocumented) -export const eventTarget: CornerstoneEventTarget; - -declare namespace EventTypes { - export { - CameraModifiedEventDetail, - CameraModifiedEvent, - VoiModifiedEvent, - VoiModifiedEventDetail, - ElementDisabledEvent, - ElementDisabledEventDetail, - ElementEnabledEvent, - ElementEnabledEventDetail, - ImageRenderedEventDetail, - ImageRenderedEvent, - ImageVolumeModifiedEvent, - ImageVolumeModifiedEventDetail, - ImageLoadedEvent, - ImageLoadedEventDetail, - ImageLoadedFailedEventDetail, - ImageLoadedFailedEvent, - VolumeLoadedEvent, - VolumeLoadedEventDetail, - VolumeLoadedFailedEvent, - VolumeLoadedFailedEventDetail, - ImageCacheImageAddedEvent, - ImageCacheImageAddedEventDetail, - ImageCacheImageRemovedEvent, - ImageCacheImageRemovedEventDetail, - VolumeCacheVolumeAddedEvent, - VolumeCacheVolumeAddedEventDetail, - VolumeCacheVolumeRemovedEvent, - VolumeCacheVolumeRemovedEventDetail, - StackNewImageEvent, - StackNewImageEventDetail, - PreStackNewImageEvent, - PreStackNewImageEventDetail, - ImageSpacingCalibratedEvent, - ImageSpacingCalibratedEventDetail, - ImageLoadProgressEvent, - ImageLoadProgressEventDetail, - VolumeNewImageEvent, - VolumeNewImageEventDetail, - StackViewportNewStackEvent, - StackViewportNewStackEventDetail, - StackViewportScrollEvent, - StackViewportScrollEventDetail - } -} - -// @public (undocumented) -type FlipDirection = { - flipHorizontal?: boolean; - flipVertical?: boolean; -}; - -// @public (undocumented) -function getClosestImageId(imageVolume: IImageVolume, worldPos: Point3, viewPlaneNormal: Point3, viewUp: Point3): string; - -// @public (undocumented) -function getClosestStackImageIndexForPoint(point: Point3, viewport: IStackViewport): number | null; - -// @public (undocumented) -export function getEnabledElement(element: HTMLDivElement | undefined): IEnabledElement | undefined; - -// @public (undocumented) -export function getEnabledElementByIds(viewportId: string, renderingEngineId: string): IEnabledElement; - -// @public (undocumented) -export function getEnabledElements(): IEnabledElement[]; - -// @public (undocumented) -function getImageSliceDataForVolumeViewport(viewport: IVolumeViewport): ImageSliceData; - -// @public (undocumented) -function getMetaData(type: string, query: string): any; - -// @public (undocumented) -function getMinMax(storedPixelData: number[]): { - min: number; - max: number; -}; - -// @public (undocumented) -export function getOrCreateCanvas(element: HTMLDivElement): HTMLCanvasElement; - -// @public (undocumented) -export function getRenderingEngine(id: string): IRenderingEngine | undefined; - -// @public (undocumented) -export function getRenderingEngines(): IRenderingEngine[] | undefined; - -// @public (undocumented) -function getRuntimeId(context?: unknown, separator?: string, max?: number): string; - -// @public (undocumented) -export function getShouldUseCPURendering(): boolean; - -// @public (undocumented) -function getSliceRange(volumeActor: VolumeActor, viewPlaneNormal: Point3, focalPoint: Point3): ActorSliceRange; - -// @public (undocumented) -function getSpacingInNormalDirection(imageVolume: IImageVolume, viewPlaneNormal: Point3): number; - -// @public (undocumented) -function getTargetVolumeAndSpacingInNormalDir(viewport: IVolumeViewport, camera: ICamera, targetVolumeId?: string): { - imageVolume: IImageVolume; - spacingInNormalDirection: number; -}; - -// @public (undocumented) -function getViewportImageCornersInWorld(viewport: IStackViewport | IVolumeViewport): Point3[]; - -// @public (undocumented) -function getViewportsWithImageURI(imageURI: string, renderingEngineId?: string): Array; - -// @public (undocumented) -function getViewportsWithVolumeId(volumeId: string, renderingEngineId?: string): Array; - -// @public (undocumented) -function getVolumeActorCorners(volumeActor: any): Array; - -// @public (undocumented) -function getVolumeViewportsContainingSameVolumes(targetViewport: IVolumeViewport, renderingEngineId?: string): Array; - -// @public (undocumented) -function hasNaNValues(input: number[] | number): boolean; - -// @public (undocumented) -interface ICache { - // (undocumented) - getCacheSize: () => number; - // (undocumented) - getImageLoadObject: (imageId: string) => IImageLoadObject | void; - // (undocumented) - getMaxCacheSize: () => number; - // (undocumented) - getVolumeLoadObject: (volumeId: string) => IVolumeLoadObject | void; - // (undocumented) - purgeCache: () => void; - // (undocumented) - putImageLoadObject: (imageId: string, imageLoadObject: IImageLoadObject) => Promise; - // (undocumented) - putVolumeLoadObject: (volumeId: string, volumeLoadObject: IVolumeLoadObject) => Promise; - // (undocumented) - setMaxCacheSize: (maxCacheSize: number) => void; -} - -// @public (undocumented) -interface ICachedImage { - // (undocumented) - image?: IImage; - // (undocumented) - imageId: string; - // (undocumented) - imageLoadObject: IImageLoadObject; - // (undocumented) - loaded: boolean; - // (undocumented) - sharedCacheKey?: string; - // (undocumented) - sizeInBytes: number; - // (undocumented) - timeStamp: number; -} - -// @public (undocumented) -interface ICachedVolume { - // (undocumented) - loaded: boolean; - // (undocumented) - sizeInBytes: number; - // (undocumented) - timeStamp: number; - // (undocumented) - volume?: IImageVolume; - // (undocumented) - volumeId: string; - // (undocumented) - volumeLoadObject: IVolumeLoadObject; -} - -// @public (undocumented) -interface ICamera { - // (undocumented) - clippingRange?: Point2; - // (undocumented) - flipHorizontal?: boolean; - // (undocumented) - flipVertical?: boolean; - // (undocumented) - focalPoint?: Point3; - // (undocumented) - parallelProjection?: boolean; - // (undocumented) - parallelScale?: number; - // (undocumented) - position?: Point3; - // (undocumented) - scale?: number; - // (undocumented) - viewAngle?: number; - // (undocumented) - viewPlaneNormal?: Point3; - // (undocumented) - viewUp?: Point3; -} - -// @public (undocumented) -interface IEnabledElement { - // (undocumented) - FrameOfReferenceUID: string; - // (undocumented) - renderingEngine: IRenderingEngine; - // (undocumented) - renderingEngineId: string; - // (undocumented) - viewport: IStackViewport | IVolumeViewport; - // (undocumented) - viewportId: string; -} - -// @public (undocumented) -interface IImage { - // (undocumented) - cachedLut?: { - windowWidth?: number | number[]; - windowCenter?: number | number[]; - invert?: boolean; - lutArray?: Uint8ClampedArray; - modalityLUT?: unknown; - voiLUT?: CPUFallbackLUT; - }; - // (undocumented) - color: boolean; - // (undocumented) - colormap?: CPUFallbackColormap; - // (undocumented) - columnPixelSpacing: number; - // (undocumented) - columns: number; - // (undocumented) - getCanvas: () => HTMLCanvasElement; - // (undocumented) - getPixelData: () => Array; - // (undocumented) - height: number; - // (undocumented) - imageId: string; - // (undocumented) - intercept: number; - // (undocumented) - invert: boolean; - // (undocumented) - isPreScaled?: boolean; - // (undocumented) - maxPixelValue: number; - // (undocumented) - minPixelValue: number; - // (undocumented) - modalityLUT?: CPUFallbackLUT; - // (undocumented) - numComps: number; - // (undocumented) - preScale?: { - scaled: boolean; - scalingParameters: { - modality?: string; - rescaleSlope?: number; - rescaleIntercept?: number; - suvbw?: number; - }; - }; - // (undocumented) - render?: (enabledElement: CPUFallbackEnabledElement, invalidated: boolean) => unknown; - // (undocumented) - rgba: boolean; - // (undocumented) - rowPixelSpacing: number; - // (undocumented) - rows: number; - // (undocumented) - scaling?: { - PET?: { - SUVlbmFactor?: number; - SUVbsaFactor?: number; - suvbwToSuvlbm?: number; - suvbwToSuvbsa?: number; - }; - }; - // (undocumented) - sharedCacheKey?: string; - // (undocumented) - sizeInBytes: number; - // (undocumented) - sliceThickness?: number; - // (undocumented) - slope: number; - // (undocumented) - stats?: { - lastStoredPixelDataToCanvasImageDataTime?: number; - lastGetPixelDataTime?: number; - lastPutImageDataTime?: number; - lastLutGenerateTime?: number; - lastRenderedViewport?: unknown; - lastRenderTime?: number; - }; - // (undocumented) - voiLUT?: CPUFallbackLUT; - // (undocumented) - width: number; - // (undocumented) - windowCenter: number[] | number; - // (undocumented) - windowWidth: number[] | number; -} - -// @public (undocumented) -interface IImageData { - // (undocumented) - dimensions: Point3; - // (undocumented) - direction: Mat3; - // (undocumented) - hasPixelSpacing?: boolean; - // (undocumented) - imageData: vtkImageData; - // (undocumented) - metadata: { - Modality: string; - }; - // (undocumented) - origin: Point3; - // (undocumented) - preScale?: { - scaled?: boolean; - scalingParameters?: { - modality?: string; - rescaleSlope?: number; - rescaleIntercept?: number; - suvbw?: number; - }; - }; - // (undocumented) - scalarData: Float32Array; - // (undocumented) - scaling?: Scaling; - // (undocumented) - spacing: Point3; -} - -// @public (undocumented) -interface IImageLoadObject { - // (undocumented) - cancelFn?: () => void; - // (undocumented) - decache?: () => void; - // (undocumented) - promise: Promise; -} - -// @public (undocumented) -interface IImageVolume { - // (undocumented) - cancelLoading?: () => void; - // (undocumented) - convertToCornerstoneImage?: (imageId: string, imageIdIndex: number) => IImageLoadObject; - // (undocumented) - dimensions: Point3; - // (undocumented) - direction: Mat3; - // (undocumented) - hasPixelSpacing: boolean; - // (undocumented) - imageData?: vtkImageData; - // (undocumented) - imageIds?: Array; - // (undocumented) - isPrescaled: boolean; - // (undocumented) - loadStatus?: Record; - // (undocumented) - metadata: Metadata; - // (undocumented) - numVoxels: number; - // (undocumented) - origin: Point3; - // (undocumented) - referencedVolumeId?: string; - // (undocumented) - scalarData: any; - // (undocumented) - scaling?: { - PET?: { - SUVlbmFactor?: number; - SUVbsaFactor?: number; - suvbwToSuvlbm?: number; - suvbwToSuvbsa?: number; - }; - }; - // (undocumented) - sizeInBytes?: number; - // (undocumented) - spacing: Point3; - // (undocumented) - readonly volumeId: string; - // (undocumented) - vtkOpenGLTexture: any; -} - -// @public (undocumented) -type ImageCacheImageAddedEvent = CustomEvent_2; - -// @public (undocumented) -type ImageCacheImageAddedEventDetail = { - image: ICachedImage; -}; - -// @public (undocumented) -type ImageCacheImageRemovedEvent = CustomEvent_2; - -// @public (undocumented) -type ImageCacheImageRemovedEventDetail = { - imageId: string; -}; - -// @public (undocumented) -function imageIdToURI(imageId: string): string; - -// @public (undocumented) -type ImageLoadedEvent = CustomEvent_2; - -// @public (undocumented) -type ImageLoadedEventDetail = { - image: IImage; -}; - -// @public (undocumented) -type ImageLoadedFailedEvent = CustomEvent_2; - -// @public (undocumented) -type ImageLoadedFailedEventDetail = { - imageId: string; - error: unknown; -}; - -declare namespace imageLoader { - export { - loadImage, - loadAndCacheImage, - loadAndCacheImages, - cancelLoadImage, - cancelLoadImages, - cancelLoadAll, - registerImageLoader, - registerUnknownImageLoader, - unregisterAllImageLoaders, - ImageLoaderOptions - } -} -export { imageLoader } - -// @public (undocumented) -type ImageLoaderFn = (imageId: string, options?: Record) => { - promise: Promise>; - cancelFn?: () => void | undefined; - decache?: () => void | undefined; -}; - -// @public (undocumented) -interface ImageLoaderOptions { - // (undocumented) - additionalDetails?: Record; - // (undocumented) - priority: number; - // (undocumented) - requestType: string; -} - -// @public (undocumented) -const imageLoadPoolManager: RequestPoolManager; -export { imageLoadPoolManager } -export { imageLoadPoolManager as requestPoolManager } - -// @public (undocumented) -type ImageLoadProgressEvent = CustomEvent_2; - -// @public (undocumented) -type ImageLoadProgressEventDetail = { - url: string; - imageId: string; - loaded: number; - total: number; - percent: number; -}; - -// @public (undocumented) -type ImageRenderedEvent = CustomEvent_2; - -// @public (undocumented) -type ImageRenderedEventDetail = { - element: HTMLDivElement; - viewportId: string; - renderingEngineId: string; - suppressEvents?: boolean; -}; - -// @public (undocumented) -export const imageRetrievalPoolManager: RequestPoolManager; - -// @public (undocumented) -type ImageSliceData = { - numberOfSlices: number; - imageIndex: number; -}; - -// @public (undocumented) -type ImageSpacingCalibratedEvent = CustomEvent_2; - -// @public (undocumented) -type ImageSpacingCalibratedEventDetail = { - element: HTMLDivElement; - viewportId: string; - renderingEngineId: string; - imageId: string; - rowScale: number; - columnScale: number; - imageData: vtkImageData; - worldToIndex: mat4; -}; - -// @public (undocumented) -function imageToWorldCoords(imageId: string, imageCoords: Point2): Point3 | undefined; - -// @public (undocumented) -export class ImageVolume implements IImageVolume { - constructor(props: IVolume); - // (undocumented) - cancelLoading: () => void; - // (undocumented) - dimensions: Point3; - // (undocumented) - direction: Mat3; - // (undocumented) - hasPixelSpacing: boolean; - // (undocumented) - imageData?: any; - // (undocumented) - imageIds?: Array; - // (undocumented) - isPrescaled: boolean; - // (undocumented) - loadStatus?: Record; - // (undocumented) - metadata: Metadata; - // (undocumented) - numVoxels: number; - // (undocumented) - origin: Point3; - // (undocumented) - referencedVolumeId?: string; - // (undocumented) - scalarData: Float32Array | Uint8Array; - // (undocumented) - scaling?: { - PET?: { - SUVlbmFactor?: number; - SUVbsaFactor?: number; - suvbwToSuvlbm?: number; - suvbwToSuvbsa?: number; - }; - }; - // (undocumented) - sizeInBytes?: number; - // (undocumented) - spacing: Point3; - // (undocumented) - readonly volumeId: string; - // (undocumented) - vtkOpenGLTexture: any; -} - -// @public (undocumented) -type ImageVolumeModifiedEvent = CustomEvent_2; - -// @public (undocumented) -type ImageVolumeModifiedEventDetail = { - imageVolume: IImageVolume; - FrameOfReferenceUID: string; -}; - -// @public (undocumented) -function indexWithinDimensions(index: Point3, dimensions: Point3): boolean; - -// @public (undocumented) -export function init(defaultConfiguration?: {}): Promise; - -// @public (undocumented) -enum InterpolationType { - // (undocumented) - FAST_LINEAR = 2, - // (undocumented) - LINEAR = 1, - // (undocumented) - NEAREST = 0 -} - -// @public (undocumented) -function invertRgbTransferFunction(rgbTransferFunction: any): void; - -// @public (undocumented) -interface IRegisterImageLoader { - // (undocumented) - registerImageLoader: (scheme: string, imageLoader: ImageLoaderFn) => void; -} - -// @public (undocumented) -interface IRenderingEngine { - // (undocumented) - _debugRender(): void; - // (undocumented) - destroy(): void; - // (undocumented) - disableElement(viewportId: string): void; - // (undocumented) - enableElement(viewportInputEntry: PublicViewportInput): void; - // (undocumented) - fillCanvasWithBackgroundColor(canvas: HTMLCanvasElement, backgroundColor: [number, number, number]): void; - // (undocumented) - getStackViewports(): Array; - // (undocumented) - getViewport(id: string): IStackViewport | IVolumeViewport; - // (undocumented) - getViewports(): Array; - // (undocumented) - getVolumeViewports(): Array; - // (undocumented) - hasBeenDestroyed: boolean; - // (undocumented) - id: string; - // (undocumented) - offScreenCanvasContainer: any; - // (undocumented) - offscreenMultiRenderWindow: any; - // (undocumented) - render(): void; - // (undocumented) - renderFrameOfReference(FrameOfReferenceUID: string): void; - // (undocumented) - renderViewport(viewportId: string): void; - // (undocumented) - renderViewports(viewportIds: Array): void; - // (undocumented) - resize(immediate?: boolean, resetPan?: boolean, resetZoom?: boolean): void; - // (undocumented) - setViewports(viewports: Array): void; -} - -// @public (undocumented) -export function isCornerstoneInitialized(): boolean; - -// @public (undocumented) -function isEqual(v1: number[] | Float32Array, v2: number[] | Float32Array, tolerance?: number): boolean; - -// @public (undocumented) -function isImageActor(actor: vtkActor | vtkVolume | vtkImageSlice): boolean; - -// @public (undocumented) -function isOpposite(v1: Point3, v2: Point3, tolerance?: number): boolean; - -// @public (undocumented) -interface IStackViewport extends IViewport { - // (undocumented) - calibrateSpacing(imageId: string): void; - // (undocumented) - canvasToWorld: (canvasPos: Point2) => Point3; - // (undocumented) - customRenderViewportToCanvas: () => { - canvas: HTMLCanvasElement; - element: HTMLDivElement; - viewportId: string; - renderingEngineId: string; - }; - // (undocumented) - getCamera(): ICamera; - // (undocumented) - getCurrentImageId: () => string; - // (undocumented) - getCurrentImageIdIndex: () => number; - // (undocumented) - getFrameOfReferenceUID: () => string; - // (undocumented) - getImageData(): IImageData | CPUIImageData; - // (undocumented) - getImageIds: () => string[]; - // (undocumented) - getProperties: () => StackViewportProperties; - // (undocumented) - getRenderer(): any; - // (undocumented) - hasImageId: (imageId: string) => boolean; - // (undocumented) - hasImageURI: (imageURI: string) => boolean; - // (undocumented) - modality: string; - // (undocumented) - resetCamera(resetPan?: boolean, resetZoom?: boolean): boolean; - // (undocumented) - resetProperties(): void; - // (undocumented) - resize: () => void; - // (undocumented) - scaling: Scaling; - // (undocumented) - setCamera(cameraInterface: ICamera): void; - // (undocumented) - setColormap(colormap: CPUFallbackColormapData): void; - // (undocumented) - setImageIdIndex(imageIdIndex: number): Promise; - // (undocumented) - setProperties({ voiRange, invert, interpolationType, rotation }: StackViewportProperties, suppressEvents?: boolean): void; - // (undocumented) - setStack(imageIds: Array, currentImageIdIndex?: number): Promise; - // (undocumented) - unsetColormap(): void; - // (undocumented) - worldToCanvas: (worldPos: Point3) => Point2; -} - -// @public (undocumented) -interface IStreamingImageVolume extends ImageVolume { - // (undocumented) - clearLoadCallbacks(): void; - // (undocumented) - convertToCornerstoneImage(imageId: string, imageIdIndex: number): any; - // (undocumented) - decache(completelyRemove: boolean): void; -} - -// @public (undocumented) -interface IStreamingVolumeProperties { - // (undocumented) - imageIds: Array; - // (undocumented) - loadStatus: { - loaded: boolean; - loading: boolean; - cachedFrames: Array; - callbacks: Array<() => void>; - }; -} - -// @public (undocumented) -interface IViewport { - // (undocumented) - _actors: Map; - // (undocumented) - addActor(actorEntry: ActorEntry): void; - // (undocumented) - addActors(actors: Array): void; - // (undocumented) - canvas: HTMLCanvasElement; - // (undocumented) - canvasToWorld: (canvasPos: Point2) => Point3; - // (undocumented) - customRenderViewportToCanvas: () => unknown; - // (undocumented) - defaultOptions: any; - // (undocumented) - element: HTMLDivElement; - // (undocumented) - getActor(actorUID: string): ActorEntry; - // (undocumented) - getActorByIndex(index: number): ActorEntry; - // (undocumented) - getActors(): Array; - // (undocumented) - getActorUIDByIndex(index: number): string; - // (undocumented) - getCamera(): ICamera; - // (undocumented) - getCanvas(): HTMLCanvasElement; - // (undocumented) - _getCorners(bounds: Array): Array[]; - // (undocumented) - getDefaultActor(): ActorEntry; - // (undocumented) - getFrameOfReferenceUID: () => string; - // (undocumented) - getPan(): Point2; - // (undocumented) - getRenderer(): void; - // (undocumented) - getRenderingEngine(): any; - // (undocumented) - getZoom(): number; - // (undocumented) - id: string; - // (undocumented) - isDisabled: boolean; - // (undocumented) - options: ViewportInputOptions; - // (undocumented) - removeAllActors(): void; - // (undocumented) - render(): void; - // (undocumented) - renderingEngineId: string; - // (undocumented) - reset(immediate: boolean): void; - // (undocumented) - setActors(actors: Array): void; - // (undocumented) - setCamera(cameraInterface: ICamera, storeAsInitialCamera?: boolean): void; - // (undocumented) - setOptions(options: ViewportInputOptions, immediate: boolean): void; - // (undocumented) - setPan(pan: Point2, storeAsInitialCamera?: boolean): any; - // (undocumented) - setZoom(zoom: number, storeAsInitialCamera?: boolean): any; - // (undocumented) - sHeight: number; - // (undocumented) - suppressEvents: boolean; - // (undocumented) - sWidth: number; - // (undocumented) - sx: number; - // (undocumented) - sy: number; - // (undocumented) - type: ViewportType; - // (undocumented) - worldToCanvas: (worldPos: Point3) => Point2; -} - -// @public (undocumented) -interface IViewportId { - // (undocumented) - renderingEngineId: string; - // (undocumented) - viewportId: string; -} - -// @public (undocumented) -interface IVolume { - // (undocumented) - dimensions: Point3; - // (undocumented) - direction: Mat3; - // (undocumented) - imageData?: vtkImageData; - // (undocumented) - metadata: Metadata; - // (undocumented) - origin: Point3; - // (undocumented) - referencedVolumeId?: string; - // (undocumented) - scalarData: Float32Array | Uint8Array; - // (undocumented) - scaling?: { - PET?: { - SUVlbmFactor?: number; - SUVbsaFactor?: number; - suvbwToSuvlbm?: number; - suvbwToSuvbsa?: number; - }; - }; - // (undocumented) - sizeInBytes?: number; - // (undocumented) - spacing: Point3; - // (undocumented) - volumeId: string; -} - -// @public (undocumented) -interface IVolumeInput { - // (undocumented) - actorUID?: string; - // (undocumented) - blendMode?: BlendModes; - // (undocumented) - callback?: VolumeInputCallback; - // (undocumented) - slabThickness?: number; - // (undocumented) - visibility?: boolean; - // (undocumented) - volumeId: string; -} - -// @public (undocumented) -interface IVolumeLoadObject { - // (undocumented) - cancelFn?: () => void; - // (undocumented) - decache?: () => void; - // (undocumented) - promise: Promise; -} - -// @public (undocumented) -interface IVolumeViewport extends IViewport { - // (undocumented) - addVolumes(volumeInputArray: Array, immediate?: boolean, suppressEvents?: boolean): Promise; - // (undocumented) - canvasToWorld: (canvasPos: Point2) => Point3; - // (undocumented) - flip(flipDirection: FlipDirection): void; - // (undocumented) - getBounds(): any; - // (undocumented) - getCurrentImageId: () => string; - // (undocumented) - getCurrentImageIdIndex: () => number; - // (undocumented) - getFrameOfReferenceUID: () => string; - // (undocumented) - getImageData(volumeId?: string): IImageData | undefined; - // (undocumented) - getIntensityFromWorld(point: Point3): number; - // (undocumented) - getProperties: () => any; - // (undocumented) - getSlabThickness(): number; - // (undocumented) - hasImageURI: (imageURI: string) => boolean; - // (undocumented) - hasVolumeId: (volumeId: string) => boolean; - // (undocumented) - removeVolumeActors(actorUIDs: Array, immediate?: boolean): void; - // (undocumented) - resetCamera(resetPan?: boolean, resetZoom?: boolean, resetToCenter?: boolean): boolean; - // (undocumented) - setBlendMode(blendMode: BlendModes, filterActorUIDs?: Array, immediate?: boolean): void; - // (undocumented) - setOrientation(orientation: OrientationAxis): void; - // (undocumented) - setProperties({ voiRange }: VolumeViewportProperties, volumeId?: string, suppressEvents?: boolean): void; - // (undocumented) - setSlabThickness(slabThickness: number, filterActorUIDs?: Array): void; - // (undocumented) - setVolumes(volumeInputArray: Array, immediate?: boolean, suppressEvents?: boolean): Promise; - // (undocumented) - useCPURendering: boolean; - // (undocumented) - worldToCanvas: (worldPos: Point3) => Point2; -} - -// @public (undocumented) -function linePlaneIntersection(p0: Point3, p1: Point3, plane: Plane): Point3; - -// @public (undocumented) -function loadAndCacheImage(imageId: string, options?: ImageLoaderOptions): Promise; - -// @public (undocumented) -function loadAndCacheImages(imageIds: Array, options?: ImageLoaderOptions): Promise[]; - -// @public (undocumented) -function loadImage(imageId: string, options?: ImageLoaderOptions): Promise; - -// @public (undocumented) -function loadImageToCanvas(canvas: HTMLCanvasElement, imageId: string, requestType?: RequestType, priority?: number): Promise; - -// @public (undocumented) -function loadVolume(volumeId: string, options?: VolumeLoaderOptions): Promise; - -// @public (undocumented) -type Mat3 = [ -number, -number, -number, -number, -number, -number, -number, -number, -number -]; - -// @public (undocumented) -type Metadata = { - BitsAllocated: number; - BitsStored: number; - SamplesPerPixel: number; - HighBit: number; - PhotometricInterpretation: string; - PixelRepresentation: number; - Modality: string; - SeriesInstanceUID?: string; - ImageOrientationPatient: Array; - PixelSpacing: Array; - FrameOfReferenceUID: string; - Columns: number; - Rows: number; - voiLut: Array; -}; - -declare namespace metaData { - export { - addProvider, - removeProvider, - removeAllProviders, - getMetaData as get - } -} -export { metaData } - -// @public (undocumented) -const metadataProvider: { - add: (imageId: string, payload: [number, number]) => void; - get: (type: string, imageId: string) => [number, number]; -}; - -// @public (undocumented) -const mprCameraValues: any; - -// @public (undocumented) -enum OrientationAxis { - // (undocumented) - ACQUISITION = "acquisition", - // (undocumented) - AXIAL = "axial", - // (undocumented) - CORONAL = "coronal", - // (undocumented) - SAGITTAL = "sagittal" -} - -// @public (undocumented) -type OrientationVectors = { - viewPlaneNormal: Point3; - viewUp: Point3; -}; - -declare namespace planar { - export { - linePlaneIntersection, - planeEquation, - threePlaneIntersection, - planeDistanceToPoint - } -} - -// @public (undocumented) -type Plane = [number, number, number, number]; - -// @public (undocumented) -function planeDistanceToPoint(plane: Plane, point: Point3, signed?: boolean): number; - -// @public (undocumented) -function planeEquation(normal: Point3, point: Point3 | vec3): Plane; - -// @public (undocumented) -type Point2 = [number, number]; - -// @public (undocumented) -type Point3 = [number, number, number]; - -// @public (undocumented) -type Point4 = [number, number, number, number]; - -// @public (undocumented) -type PreStackNewImageEvent = CustomEvent_2; - -// @public (undocumented) -type PreStackNewImageEventDetail = { - imageId: string; - imageIdIndex: number; - viewportId: string; - renderingEngineId: string; -}; - -// @public (undocumented) -type PTScaling = { - suvbwToSuvlbm?: number; - suvbwToSuvbsa?: number; -}; - -// @public (undocumented) -type PublicViewportInput = { - element: HTMLDivElement; - viewportId: string; - type: ViewportType; - defaultOptions?: ViewportInputOptions; -}; - -// @public (undocumented) -export function registerImageLoader(scheme: string, imageLoader: ImageLoaderFn): void; - -// @public (undocumented) -function registerUnknownImageLoader(imageLoader: ImageLoaderFn): ImageLoaderFn; - -// @public (undocumented) -function registerUnknownVolumeLoader(volumeLoader: Types.VolumeLoaderFn): Types.VolumeLoaderFn | undefined; - -// @public (undocumented) -function registerVolumeLoader(scheme: string, volumeLoader: Types.VolumeLoaderFn): void; - -// @public (undocumented) -function removeAllProviders(): void; - -// @public (undocumented) -function removeProvider(provider: (type: string, query: any) => { - any: any; -}): void; - -// @public (undocumented) -const RENDERING_DEFAULTS: { - MINIMUM_SLAB_THICKNESS: number; - MAXIMUM_RAY_DISTANCE: number; -}; - -// @public (undocumented) -export class RenderingEngine implements IRenderingEngine { - constructor(id?: string); - // (undocumented) - _debugRender(): void; - // (undocumented) - destroy(): void; - // (undocumented) - disableElement(viewportId: string): void; - // (undocumented) - _downloadOffScreenCanvas(): void; - // (undocumented) - enableElement(viewportInputEntry: PublicViewportInput): void; - // (undocumented) - fillCanvasWithBackgroundColor(canvas: HTMLCanvasElement, backgroundColor: [number, number, number]): void; - // (undocumented) - getStackViewports(): Array; - // (undocumented) - getViewport(viewportId: string): IStackViewport | IVolumeViewport; - // (undocumented) - getViewports(): Array; - // (undocumented) - getVolumeViewports(): Array; - // (undocumented) - hasBeenDestroyed: boolean; - // (undocumented) - readonly id: string; - // (undocumented) - readonly offScreenCanvasContainer: any; - // (undocumented) - offscreenMultiRenderWindow: any; - // (undocumented) - render(): void; - // (undocumented) - renderFrameOfReference: (FrameOfReferenceUID: string) => void; - // (undocumented) - renderViewport(viewportId: string): void; - // (undocumented) - renderViewports(viewportIds: Array): void; - // (undocumented) - resize(immediate?: boolean, keepCamera?: boolean): void; - // (undocumented) - setViewports(publicViewportInputEntries: Array): void; -} - -// @public (undocumented) -function renderToCanvas(canvas: HTMLCanvasElement, image: IImage, modality?: string): void; - -// @public (undocumented) -enum RequestType { - // (undocumented) - Interaction = "interaction", - // (undocumented) - Prefetch = "prefetch", - // (undocumented) - Thumbnail = "thumbnail" -} - -// @public (undocumented) -export function resetUseCPURendering(): void; - -// @public (undocumented) -function scaleRGBTransferFunction(rgbTransferFunction: any, scalingFactor: number): void; - -// @public (undocumented) -type Scaling = { - PET?: PTScaling; -}; - -// @public (undocumented) -type ScalingParameters = { - rescaleSlope: number; - rescaleIntercept: number; - modality: string; - suvbw?: number; - suvlbm?: number; - suvbsa?: number; -}; - -// @public (undocumented) -export class Settings { - constructor(base?: Settings); - // (undocumented) - static assert(subject: Settings): Settings; - // (undocumented) - dump(): Record; - // (undocumented) - extend(): Settings; - // (undocumented) - static extendRuntimeSettings(): Settings; - // (undocumented) - forEach(callback: (key: string, value: unknown) => void): void; - // (undocumented) - get(key: string): unknown; - // (undocumented) - static getDefaultSettings(subfield?: any): Settings | any; - // (undocumented) - static getObjectSettings(subject: unknown, from?: unknown): Settings; - // (undocumented) - static getRuntimeSettings(): Settings; - // (undocumented) - import(root: Record): void; - // (undocumented) - set(key: string, value: unknown): boolean; - // (undocumented) - unset(key: string): boolean; -} - -// @public (undocumented) -export function setUseCPURendering(status: boolean): void; - -// @public (undocumented) -export function setVolumesForViewports(renderingEngine: IRenderingEngine, volumeInputs: Array, viewportIds: Array, immediateRender?: boolean, suppressEvents?: boolean): Promise; - -// @public (undocumented) -function snapFocalPointToSlice(focalPoint: Point3, position: Point3, sliceRange: ActorSliceRange, viewPlaneNormal: Point3, spacingInNormalDirection: number, deltaFrames: number): { - newFocalPoint: Point3; - newPosition: Point3; -}; - -// @public (undocumented) -const spatialRegistrationMetadataProvider: { - add: (query: string[], payload: mat4) => void; - get: (type: string, query: string[]) => mat4; -}; - -// @public (undocumented) -type StackNewImageEvent = CustomEvent_2; - -// @public (undocumented) -type StackNewImageEventDetail = { - image: IImage; - imageId: string; - imageIdIndex: number; - viewportId: string; - renderingEngineId: string; -}; - -// @public (undocumented) -export class StackViewport extends Viewport implements IStackViewport { - constructor(props: ViewportInput); - // (undocumented) - addActor(actorEntry: ActorEntry): void; - // (undocumented) - addActors(actors: Array): void; - // (undocumented) - calibrateSpacing(imageId: string): void; - // (undocumented) - canvasToWorld: (canvasPos: Point2) => Point3; - // (undocumented) - customRenderViewportToCanvas: () => { - canvas: HTMLCanvasElement; - element: HTMLDivElement; - viewportId: string; - renderingEngineId: string; - }; - // (undocumented) - getActor(actorUID: string): ActorEntry; - // (undocumented) - getActors(): Array; - // (undocumented) - getCamera(): ICamera; - // (undocumented) - getCurrentImageId: () => string; - // (undocumented) - getCurrentImageIdIndex: () => number; - // (undocumented) - getDefaultActor(): ActorEntry; - // (undocumented) - getFrameOfReferenceUID: () => string | undefined; - // (undocumented) - getImageData(): IImageData | CPUIImageData; - // (undocumented) - getImageIds: () => Array; - // (undocumented) - getProperties: () => StackViewportProperties; - // (undocumented) - getRenderer(): any; - // (undocumented) - getTargetImageIdIndex: () => number; - // (undocumented) - hasImageId: (imageId: string) => boolean; - // (undocumented) - hasImageURI: (imageURI: string) => boolean; - // (undocumented) - modality: string; - // (undocumented) - removeAllActors(): void; - // (undocumented) - resetCamera(resetPan?: boolean, resetZoom?: boolean): boolean; - // (undocumented) - resetProperties(): void; - // (undocumented) - resize: () => void; - // (undocumented) - scaling: Scaling; - // (undocumented) - scroll(delta: number, debounce?: boolean, loop?: boolean): void; - // (undocumented) - setActors(actors: Array): void; - // (undocumented) - setCamera(cameraInterface: ICamera, storeAsInitialCamera?: boolean): void; - // (undocumented) - setColormap(colormap: CPUFallbackColormapData): void; - // (undocumented) - setImageIdIndex(imageIdIndex: number): Promise; - // (undocumented) - setProperties({ voiRange, invert, interpolationType, rotation, }?: StackViewportProperties, suppressEvents?: boolean): void; - // (undocumented) - setStack(imageIds: Array, currentImageIdIndex?: number): Promise; - // (undocumented) - unsetColormap(): void; - // (undocumented) - static get useCustomRenderingPipeline(): boolean; - // (undocumented) - worldToCanvas: (worldPos: Point3) => Point2; -} - -// @public (undocumented) -type StackViewportNewStackEvent = CustomEvent_2; - -// @public (undocumented) -type StackViewportNewStackEventDetail = { - imageIds: string[]; - viewportId: string; - element: HTMLDivElement; - currentImageIdIndex: number; -}; - -// @public (undocumented) -type StackViewportProperties = { - voiRange?: VOIRange; - invert?: boolean; - interpolationType?: InterpolationType; - rotation?: number; - suppressEvents?: boolean; -}; - -// @public (undocumented) -type StackViewportScrollEvent = CustomEvent_2; - -// @public (undocumented) -type StackViewportScrollEventDetail = { - newImageIdIndex: number; - imageId: string; - direction: number; -}; - -// @public (undocumented) -function threePlaneIntersection(firstPlane: Plane, secondPlane: Plane, thirdPlane: Plane): Point3; - -// @public (undocumented) -function toLowHighRange(windowWidth: number, windowCenter: number): { - lower: number; - upper: number; -}; - -// @public (undocumented) -function toWindowLevel(low: number, high: number): { - windowWidth: number; - windowCenter: number; -}; - -// @public (undocumented) -type TransformMatrix2D = [number, number, number, number, number, number]; - -// @public (undocumented) -function transformWorldToIndex(imageData: any, worldPos: Point3): any; - -// @public (undocumented) -export function triggerEvent(el: EventTarget, type: string, detail?: unknown): boolean; - -declare namespace Types { - export { - ICamera, - IStackViewport, - IVolumeViewport, - IEnabledElement, - ICache, - IVolume, - IViewportId, - IImageVolume, - IRenderingEngine, - ScalingParameters, - PTScaling, - Scaling, - IStreamingImageVolume, - IImage, - IImageData, - CPUIImageData, - CPUImageData, - EventTypes, - ImageLoaderFn, - VolumeLoaderFn, - IRegisterImageLoader, - IStreamingVolumeProperties, - IViewport, - StackViewportProperties, - VolumeViewportProperties, - PublicViewportInput, - VolumeActor, - Actor, - ActorEntry, - IImageLoadObject, - IVolumeLoadObject, - IVolumeInput, - VolumeInputCallback, - Metadata, - OrientationVectors, - Point2, - Point3, - Point4, - Mat3, - Plane, - ViewportInputOptions, - VOIRange, - VOI, - FlipDirection, - ICachedImage, - ICachedVolume, - CPUFallbackEnabledElement, - CPUFallbackViewport, - CPUFallbackTransform, - CPUFallbackColormapData, - CPUFallbackViewportDisplayedArea, - CPUFallbackColormapsData, - CPUFallbackColormap, - TransformMatrix2D, - CPUFallbackLookupTable, - CPUFallbackLUT, - CPUFallbackRenderingTools, - CustomEvent_2 as CustomEventType, - ActorSliceRange, - ImageSliceData - } -} -export { Types } - -// @public (undocumented) -function unregisterAllImageLoaders(): void; - -declare namespace utilities { - export { - invertRgbTransferFunction, - scaleRGBTransferFunction as scaleRgbTransferFunction, - triggerEvent, - imageIdToURI, - metadataProvider as calibratedPixelSpacingMetadataProvider, - uuidv4, - planar, - getMinMax, - getRuntimeId, - isEqual, - isOpposite, - createFloat32SharedArray, - createUint8SharedArray, - windowLevel, - getClosestImageId, - getSpacingInNormalDirection, - getTargetVolumeAndSpacingInNormalDir, - getVolumeActorCorners, - indexWithinDimensions, - getVolumeViewportsContainingSameVolumes, - getViewportsWithVolumeId, - transformWorldToIndex, - loadImageToCanvas, - renderToCanvas, - worldToImageCoords, - imageToWorldCoords, - getSliceRange, - snapFocalPointToSlice, - getImageSliceDataForVolumeViewport, - isImageActor, - getViewportsWithImageURI, - getClosestStackImageIndexForPoint, - calculateViewportsSpatialRegistration, - spatialRegistrationMetadataProvider, - getViewportImageCornersInWorld, - hasNaNValues - } -} -export { utilities } - -// @public (undocumented) -function uuidv4(): string; - -// @public (undocumented) -export class Viewport implements IViewport { - constructor(props: ViewportInput); - // (undocumented) - _actors: Map; - // (undocumented) - addActor(actorEntry: ActorEntry): void; - // (undocumented) - addActors(actors: Array, resetCameraPanAndZoom?: boolean): void; - // (undocumented) - readonly canvas: HTMLCanvasElement; - // (undocumented) - canvasToWorld: (canvasPos: Point2) => Point3; - // (undocumented) - customRenderViewportToCanvas: () => unknown; - // (undocumented) - readonly defaultOptions: any; - // (undocumented) - readonly element: HTMLDivElement; - // (undocumented) - protected flip({ flipHorizontal, flipVertical }: FlipDirection): void; - // (undocumented) - protected flipHorizontal: boolean; - // (undocumented) - protected flipVertical: boolean; - // (undocumented) - getActor(actorUID: string): ActorEntry; - // (undocumented) - getActorByIndex(index: number): ActorEntry; - // (undocumented) - getActors(): Array; - // (undocumented) - getActorUIDByIndex(index: number): string; - // (undocumented) - getCamera(): ICamera; - // (undocumented) - getCanvas(): HTMLCanvasElement; - // (undocumented) - _getCorners(bounds: Array): Array[]; - // (undocumented) - getDefaultActor(): ActorEntry; - // (undocumented) - _getEdges(bounds: Array): Array<[number[], number[]]>; - // (undocumented) - _getFocalPointForResetCamera(centeredFocalPoint: Point3, previousCamera: ICamera, { resetPan, resetToCenter }: { - resetPan?: boolean; - resetToCenter?: boolean; - }): Point3; - // (undocumented) - getFrameOfReferenceUID: () => string; - // (undocumented) - getPan(): Point2; - // (undocumented) - getProperties: () => void; - // (undocumented) - getRenderer(): any; - // (undocumented) - getRenderingEngine(): IRenderingEngine; - // (undocumented) - protected getVtkActiveCamera(): vtkCamera | vtkSlabCamera; - // (undocumented) - getZoom(): number; - // (undocumented) - protected hasPixelSpacing: boolean; - // (undocumented) - readonly id: string; - // (undocumented) - protected initialCamera: ICamera; - // (undocumented) - isDisabled: boolean; - // (undocumented) - _isInBounds(point: Point3, bounds: number[]): boolean; - // (undocumented) - options: ViewportInputOptions; - // (undocumented) - removeActor(actorUID: string): void; - // (undocumented) - removeActors(actorUIDs: Array): void; - // (undocumented) - removeAllActors(): void; - // (undocumented) - render(): void; - // (undocumented) - readonly renderingEngineId: string; - // (undocumented) - reset(immediate?: boolean): void; - // (undocumented) - protected resetCamera(resetPan?: boolean, resetZoom?: boolean, resetToCenter?: boolean, storeAsInitialCamera?: boolean): boolean; - // (undocumented) - protected resetCameraNoEvent(): void; - // (undocumented) - resize: () => void; - // (undocumented) - protected rotation: number; - // (undocumented) - setActors(actors: Array): void; - // (undocumented) - setCamera(cameraInterface: ICamera, storeAsInitialCamera?: boolean): void; - // (undocumented) - protected setCameraNoEvent(camera: ICamera): void; - // (undocumented) - protected setInitialCamera(camera: ICamera): void; - // (undocumented) - setOptions(options: ViewportInputOptions, immediate?: boolean): void; - // (undocumented) - setOrientationOfClippingPlanes(vtkPlanes: Array, slabThickness: number, viewPlaneNormal: Point3, focalPoint: Point3): void; - // (undocumented) - setPan(pan: Point2, storeAsInitialCamera?: boolean): void; - // (undocumented) - setZoom(value: number, storeAsInitialCamera?: boolean): void; - // (undocumented) - sHeight: number; - // (undocumented) - readonly suppressEvents: boolean; - // (undocumented) - sWidth: number; - // (undocumented) - sx: number; - // (undocumented) - sy: number; - // (undocumented) - triggerCameraModifiedEventIfNecessary(previousCamera: ICamera, updatedCamera: ICamera): void; - // (undocumented) - readonly type: ViewportType; - // (undocumented) - protected updateClippingPlanesForActors(updatedCamera: ICamera): void; - // (undocumented) - static get useCustomRenderingPipeline(): boolean; - // (undocumented) - worldToCanvas: (worldPos: Point3) => Point2; -} - -// @public (undocumented) -type ViewportInputOptions = { - background?: [number, number, number]; - orientation?: OrientationAxis | OrientationVectors; - suppressEvents?: boolean; -}; - -// @public (undocumented) -enum ViewportType { - // (undocumented) - ORTHOGRAPHIC = "orthographic", - // (undocumented) - PERSPECTIVE = "perspective", - // (undocumented) - STACK = "stack" -} - -// @public (undocumented) -type VOI = { - windowWidth: number; - windowCenter: number; -}; - -// @public (undocumented) -type VoiModifiedEvent = CustomEvent_2; - -// @public (undocumented) -type VoiModifiedEventDetail = { - viewportId: string; - range: VOIRange; - volumeId?: string; -}; - -// @public (undocumented) -type VOIRange = { - upper: number; - lower: number; -}; - -// @public (undocumented) -type VolumeActor = vtkVolume; - -// @public (undocumented) -type VolumeCacheVolumeAddedEvent = CustomEvent_2; - -// @public (undocumented) -type VolumeCacheVolumeAddedEventDetail = { - volume: ICachedVolume; -}; - -// @public (undocumented) -type VolumeCacheVolumeRemovedEvent = CustomEvent_2; - -// @public (undocumented) -type VolumeCacheVolumeRemovedEventDetail = { - volumeId: string; -}; - -// @public (undocumented) -type VolumeInputCallback = (params: { - volumeActor: VolumeActor; - volumeId: string; -}) => unknown; - -// @public (undocumented) -type VolumeLoadedEvent = CustomEvent_2; - -// @public (undocumented) -type VolumeLoadedEventDetail = { - volume: IImageVolume; -}; - -// @public (undocumented) -type VolumeLoadedFailedEvent = CustomEvent_2; - -// @public (undocumented) -type VolumeLoadedFailedEventDetail = { - volumeId: string; - error: unknown; -}; - -declare namespace volumeLoader { - export { - loadVolume, - createAndCacheVolume, - createAndCacheDerivedVolume, - createLocalVolume, - registerVolumeLoader, - registerUnknownVolumeLoader - } -} -export { volumeLoader } - -// @public (undocumented) -type VolumeLoaderFn = (volumeId: string, options?: Record) => { - promise: Promise>; - cancelFn?: () => void | undefined; - decache?: () => void | undefined; -}; - -// @public (undocumented) -type VolumeNewImageEvent = CustomEvent_2; - -// @public (undocumented) -type VolumeNewImageEventDetail = { - imageIndex: number; - numberOfSlices: number; - viewportId: string; - renderingEngineId: string; -}; - -// @public (undocumented) -export class VolumeViewport extends Viewport implements IVolumeViewport { - constructor(props: ViewportInput); - // (undocumented) - addVolumes(volumeInputArray: Array, immediate?: boolean, suppressEvents?: boolean): Promise; - // (undocumented) - canvasToWorld: (canvasPos: Point2) => Point3; - // (undocumented) - flip(flipDirection: FlipDirection): void; - // (undocumented) - getBounds(): number[]; - // (undocumented) - getCurrentImageId: () => string | undefined; - // (undocumented) - getCurrentImageIdIndex: () => number | undefined; - // (undocumented) - getFrameOfReferenceUID: () => string; - // (undocumented) - getImageData(volumeId?: string): IImageData | undefined; - // (undocumented) - getIntensityFromWorld(point: Point3): number; - // (undocumented) - getSlabThickness(): number; - // (undocumented) - hasImageURI: (imageURI: string) => boolean; - // (undocumented) - hasVolumeId(volumeId: string): boolean; - // (undocumented) - removeVolumeActors(actorUIDs: Array, immediate?: boolean): void; - // (undocumented) - resetCamera(resetPan?: boolean, resetZoom?: boolean, resetToCenter?: boolean): boolean; - // (undocumented) - setBlendMode(blendMode: BlendModes, filterActorUIDs?: any[], immediate?: boolean): void; - // (undocumented) - setOrientation(orientation: OrientationAxis, immediate?: boolean): void; - // (undocumented) - setProperties({ voiRange }?: VolumeViewportProperties, volumeId?: string, suppressEvents?: boolean): void; - // (undocumented) - setSlabThickness(slabThickness: number, filterActorUIDs?: any[]): void; - // (undocumented) - setVolumes(volumeInputArray: Array, immediate?: boolean, suppressEvents?: boolean): Promise; - // (undocumented) - useCPURendering: boolean; - // (undocumented) - static get useCustomRenderingPipeline(): boolean; - // (undocumented) - worldToCanvas: (worldPos: Point3) => Point2; -} - -// @public (undocumented) -type VolumeViewportProperties = { - voiRange?: VOIRange; -}; - -declare namespace windowLevel { - export { - toWindowLevel, - toLowHighRange - } -} - -// @public (undocumented) -function worldToImageCoords(imageId: string, worldCoords: Point3): Point2 | undefined; - -// (No @packageDocumentation comment for this package) - -``` +## API Report File for "@cornerstonejs/core" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { mat4 } from 'gl-matrix'; +import { vec3 } from 'gl-matrix'; +import type vtkActor from '@kitware/vtk.js/Rendering/Core/Actor'; +import type { vtkCamera } from '@kitware/vtk.js/Rendering/Core/Camera'; +import type { vtkImageData } from '@kitware/vtk.js/Common/DataModel/ImageData'; +import vtkImageSlice from '@kitware/vtk.js/Rendering/Core/ImageSlice'; +import type { vtkObject } from '@kitware/vtk.js/interfaces'; +import vtkPlane from '@kitware/vtk.js/Common/DataModel/Plane'; +import type vtkVolume from '@kitware/vtk.js/Rendering/Core/Volume'; + +// @public (undocumented) +type Actor = vtkActor; + +// @public (undocumented) +type ActorEntry = { + uid: string; + actor: Actor | VolumeActor | ImageActor; + referenceId?: string; + slabThickness?: number; +}; + +// @public (undocumented) +type ActorSliceRange = { + actor: VolumeActor; + viewPlaneNormal: Point3; + focalPoint: Point3; + min: number; + max: number; + current: number; +}; + +// @public (undocumented) +function addProvider(provider: (type: string, query: any) => any, priority?: number): void; + +// @public (undocumented) +export function addVolumesToViewports(renderingEngine: IRenderingEngine, volumeInputs: Array, viewportIds: Array, immediateRender?: boolean, suppressEvents?: boolean): Promise; + +// @public (undocumented) +export abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport { + constructor(props: ViewportInput); + // (undocumented) + addVolumes(volumeInputArray: Array, immediate?: boolean, suppressEvents?: boolean): Promise; + // (undocumented) + canvasToWorld: (canvasPos: Point2) => Point3; + // (undocumented) + flip(flipDirection: FlipDirection): void; + // (undocumented) + getBounds(): number[]; + // (undocumented) + getCurrentImageId: () => string; + // (undocumented) + getCurrentImageIdIndex: () => number; + // (undocumented) + getFrameOfReferenceUID: () => string; + // (undocumented) + getImageData(volumeId?: string): IImageData | undefined; + // (undocumented) + getIntensityFromWorld(point: Point3): number; + // (undocumented) + getSlabThickness(): number; + // (undocumented) + hasImageURI: (imageURI: string) => boolean; + // (undocumented) + hasVolumeId(volumeId: string): boolean; + // (undocumented) + removeVolumeActors(actorUIDs: Array, immediate?: boolean): void; + // (undocumented) + resetCamera(resetPan?: boolean, resetZoom?: boolean, resetToCenter?: boolean): boolean; + // (undocumented) + setBlendMode(blendMode: BlendModes, filterActorUIDs?: string[], immediate?: boolean): void; + // (undocumented) + setOrientation(orientation: OrientationAxis, immediate?: boolean): void; + // (undocumented) + setProperties({ voiRange }?: VolumeViewportProperties, volumeId?: string, suppressEvents?: boolean): void; + // (undocumented) + setSlabThickness(slabThickness: number, filterActorUIDs?: string[]): void; + // (undocumented) + setVolumes(volumeInputArray: Array, immediate?: boolean, suppressEvents?: boolean): Promise; + // (undocumented) + useCPURendering: boolean; + // (undocumented) + static get useCustomRenderingPipeline(): boolean; + // (undocumented) + worldToCanvas: (worldPos: Point3) => Point2; +} + +// @public (undocumented) +enum BlendModes { + // (undocumented) + AVERAGE_INTENSITY_BLEND = 3, + // (undocumented) + COMPOSITE = 0, + // (undocumented) + MAXIMUM_INTENSITY_BLEND = 1, + // (undocumented) + MINIMUM_INTENSITY_BLEND = 2 +} + +// @public (undocumented) +export const cache: Cache_2; + +// @public (undocumented) +function calculateViewportsSpatialRegistration(viewport1: IStackViewport, viewport2: IStackViewport): void; + +// @public (undocumented) +type CameraModifiedEvent = CustomEvent_2; + +// @public (undocumented) +type CameraModifiedEventDetail = { + previousCamera: ICamera; + camera: ICamera; + element: HTMLDivElement; + viewportId: string; + renderingEngineId: string; + rotation?: number; +}; + +// @public (undocumented) +function cancelLoadAll(): void; + +// @public (undocumented) +function cancelLoadImage(imageId: string): void; + +// @public (undocumented) +function cancelLoadImages(imageIds: Array): void; + +// @public (undocumented) +const colormapsData: CPUFallbackColormapsData; + +declare namespace CONSTANTS { + export { + colormapsData as CPU_COLORMAPS, + RENDERING_DEFAULTS, + mprCameraValues as MPR_CAMERA_VALUES, + EPSILON + } +} +export { CONSTANTS } + +// @public (undocumented) +interface CPUFallbackColormap { + // (undocumented) + addColor: (rgba: Point4) => void; + // (undocumented) + buildLookupTable: (lut: CPUFallbackLookupTable) => void; + // (undocumented) + clearColors: () => void; + // (undocumented) + createLookupTable: () => CPUFallbackLookupTable; + // (undocumented) + getColor: (index: number) => Point4; + // (undocumented) + getColorRepeating: (index: number) => Point4; + // (undocumented) + getColorSchemeName: () => string; + // (undocumented) + getId: () => string; + // (undocumented) + getNumberOfColors: () => number; + // (undocumented) + insertColor: (index: number, rgba: Point4) => void; + // (undocumented) + isValidIndex: (index: number) => boolean; + // (undocumented) + removeColor: (index: number) => void; + // (undocumented) + setColor: (index: number, rgba: Point4) => void; + // (undocumented) + setColorSchemeName: (name: string) => void; + // (undocumented) + setNumberOfColors: (numColors: number) => void; +} + +// @public (undocumented) +type CPUFallbackColormapData = { + name: string; + numOfColors?: number; + colors?: Point4[]; + segmentedData?: unknown; + numColors?: number; + gamma?: number; +}; + +// @public (undocumented) +type CPUFallbackColormapsData = { + [key: string]: CPUFallbackColormapData; +}; + +// @public (undocumented) +interface CPUFallbackEnabledElement { + // (undocumented) + canvas?: HTMLCanvasElement; + // (undocumented) + colormap?: CPUFallbackColormap; + // (undocumented) + image?: IImage; + // (undocumented) + invalid?: boolean; + // (undocumented) + metadata?: { + direction?: Mat3; + dimensions?: Point3; + spacing?: Point3; + origin?: Point3; + imagePlaneModule?: { + frameOfReferenceUID: string; + rows: number; + columns: number; + imageOrientationPatient: number[]; + rowCosines: Point3; + columnCosines: Point3; + imagePositionPatient: number[]; + sliceThickness?: number; + sliceLocation?: number; + pixelSpacing: Point2; + rowPixelSpacing: number; + columnPixelSpacing: number; + }; + imagePixelModule?: { + samplesPerPixel: number; + photometricInterpretation: string; + rows: number; + columns: number; + bitsAllocated: number; + bitsStored: number; + highBit: number; + pixelRepresentation: number; + planarConfiguration?: number; + pixelAspectRatio?: number; + smallestPixelValue?: number; + largestPixelValue?: number; + redPaletteColorLookupTableDescriptor?: number[]; + greenPaletteColorLookupTableDescriptor?: number[]; + bluePaletteColorLookupTableDescriptor?: number[]; + redPaletteColorLookupTableData: number[]; + greenPaletteColorLookupTableData: number[]; + bluePaletteColorLookupTableData: number[]; + }; + }; + // (undocumented) + needsRedraw?: boolean; + // (undocumented) + options?: { + [key: string]: unknown; + colormap?: CPUFallbackColormap; + }; + // (undocumented) + pan?: Point2; + // (undocumented) + renderingTools?: CPUFallbackRenderingTools; + // (undocumented) + rotation?: number; + // (undocumented) + scale?: number; + // (undocumented) + transform?: CPUFallbackTransform; + // (undocumented) + viewport?: CPUFallbackViewport; + // (undocumented) + zoom?: number; +} + +// @public (undocumented) +interface CPUFallbackLookupTable { + // (undocumented) + build: (force: boolean) => void; + // (undocumented) + getColor: (scalar: number) => Point4; + // (undocumented) + setAlphaRange: (start: number, end: number) => void; + // (undocumented) + setHueRange: (start: number, end: number) => void; + // (undocumented) + setNumberOfTableValues: (number: number) => void; + // (undocumented) + setRamp: (ramp: string) => void; + // (undocumented) + setRange: (start: number, end: number) => void; + // (undocumented) + setSaturationRange: (start: number, end: number) => void; + // (undocumented) + setTableRange: (start: number, end: number) => void; + // (undocumented) + setTableValue(index: number, rgba: Point4): any; + // (undocumented) + setValueRange: (start: number, end: number) => void; +} + +// @public (undocumented) +type CPUFallbackLUT = { + lut: number[]; +}; + +// @public (undocumented) +type CPUFallbackRenderingTools = { + renderCanvas?: HTMLCanvasElement; + lastRenderedIsColor?: boolean; + lastRenderedImageId?: string; + lastRenderedViewport?: { + windowWidth: number | number[]; + windowCenter: number | number[]; + invert: boolean; + rotation: number; + hflip: boolean; + vflip: boolean; + modalityLUT: CPUFallbackLUT; + voiLUT: CPUFallbackLUT; + colormap: unknown; + }; + renderCanvasContext?: CanvasRenderingContext2D; + colormapId?: string; + colorLUT?: CPUFallbackLookupTable; + renderCanvasData?: ImageData; +}; + +// @public (undocumented) +interface CPUFallbackTransform { + // (undocumented) + clone: () => CPUFallbackTransform; + // (undocumented) + getMatrix: () => TransformMatrix2D; + // (undocumented) + invert: () => void; + // (undocumented) + multiply: (matrix: TransformMatrix2D) => void; + // (undocumented) + reset: () => void; + // (undocumented) + rotate: (rad: number) => void; + // (undocumented) + scale: (sx: number, sy: number) => void; + // (undocumented) + transformPoint: (point: Point2) => Point2; + // (undocumented) + translate: (x: number, y: number) => void; +} + +// @public (undocumented) +type CPUFallbackViewport = { + scale?: number; + parallelScale?: number; + focalPoint?: number[]; + translation?: { + x: number; + y: number; + }; + voi?: { + windowWidth: number; + windowCenter: number; + }; + invert?: boolean; + pixelReplication?: boolean; + rotation?: number; + hflip?: boolean; + vflip?: boolean; + modalityLUT?: CPUFallbackLUT; + voiLUT?: CPUFallbackLUT; + colormap?: CPUFallbackColormap; + displayedArea?: CPUFallbackViewportDisplayedArea; + modality?: string; +}; + +// @public (undocumented) +type CPUFallbackViewportDisplayedArea = { + tlhc: { + x: number; + y: number; + }; + brhc: { + x: number; + y: number; + }; + rowPixelSpacing: number; + columnPixelSpacing: number; + presentationSizeMode: string; +}; + +// @public (undocumented) +type CPUIImageData = { + dimensions: Point3; + direction: Mat3; + spacing: Point3; + origin: Point3; + imageData: CPUImageData; + metadata: { + Modality: string; + }; + scalarData: number[]; + scaling: Scaling; + hasPixelSpacing?: boolean; + preScale?: { + scaled?: boolean; + scalingParameters?: { + modality?: string; + rescaleSlope?: number; + rescaleIntercept?: number; + suvbw?: number; + }; + }; +}; + +// @public (undocumented) +type CPUImageData = { + worldToIndex?: (point: Point3) => Point3; + indexToWorld?: (point: Point3) => Point3; + getWorldToIndex?: () => Point3; + getIndexToWorld?: () => Point3; + getSpacing?: () => Point3; + getDirection?: () => Mat3; + getScalarData?: () => number[]; + getDimensions?: () => Point3; +}; + +// @public (undocumented) +function createAndCacheDerivedVolume(referencedVolumeId: string, options: DerivedVolumeOptions): Promise; + +// @public (undocumented) +function createAndCacheVolume(volumeId: string, options: VolumeLoaderOptions): Promise>; + +// @public (undocumented) +function createFloat32SharedArray(length: number): Float32Array; + +// @public (undocumented) +function createLocalVolume(options: LocalVolumeOptions, volumeId: string, preventCache?: boolean): ImageVolume; + +// @public (undocumented) +function createUint8SharedArray(length: number): Uint8Array; + +// @public (undocumented) +export function createVolumeActor(props: createVolumeActorInterface, element: HTMLDivElement, viewportId: string, suppressEvents?: boolean): Promise; + +// @public (undocumented) +export function createVolumeMapper(imageData: any, vtkOpenGLTexture: any): any; + +// @public (undocumented) +interface CustomEvent_2 extends Event { + // (undocumented) + readonly detail: T; + // (undocumented) + initCustomEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, detailArg: T): void; +} + +// @public (undocumented) +type ElementDisabledEvent = CustomEvent_2; + +// @public (undocumented) +type ElementDisabledEventDetail = { + element: HTMLDivElement; + viewportId: string; + renderingEngineId: string; +}; + +// @public (undocumented) +type ElementEnabledEvent = CustomEvent_2; + +// @public (undocumented) +type ElementEnabledEventDetail = { + element: HTMLDivElement; + viewportId: string; + renderingEngineId: string; +}; + +declare namespace Enums { + export { + EVENTS as Events, + BlendModes, + InterpolationType, + RequestType, + ViewportType, + OrientationAxis + } +} +export { Enums } + +// @public (undocumented) +const EPSILON = 0.001; + +// @public (undocumented) +export enum EVENTS { + // (undocumented) + CACHE_SIZE_EXCEEDED = "CACHE_SIZE_EXCEEDED", + // (undocumented) + CAMERA_MODIFIED = "CORNERSTONE_CAMERA_MODIFIED", + // (undocumented) + CAMERA_RESET = "CORNERSTONE_CAMERA_RESET", + // (undocumented) + ELEMENT_DISABLED = "CORNERSTONE_ELEMENT_DISABLED", + // (undocumented) + ELEMENT_ENABLED = "CORNERSTONE_ELEMENT_ENABLED", + // (undocumented) + IMAGE_CACHE_IMAGE_ADDED = "CORNERSTONE_IMAGE_CACHE_IMAGE_ADDED", + // (undocumented) + IMAGE_CACHE_IMAGE_REMOVED = "CORNERSTONE_IMAGE_CACHE_IMAGE_REMOVED", + // (undocumented) + IMAGE_LOAD_ERROR = "IMAGE_LOAD_ERROR", + // (undocumented) + IMAGE_LOAD_FAILED = "CORNERSTONE_IMAGE_LOAD_FAILED", + // (undocumented) + IMAGE_LOAD_PROGRESS = "CORNERSTONE_IMAGE_LOAD_PROGRESS", + // (undocumented) + IMAGE_LOADED = "CORNERSTONE_IMAGE_LOADED", + // (undocumented) + IMAGE_RENDERED = "CORNERSTONE_IMAGE_RENDERED", + // (undocumented) + IMAGE_SPACING_CALIBRATED = "CORNERSTONE_IMAGE_SPACING_CALIBRATED", + // (undocumented) + IMAGE_VOLUME_MODIFIED = "CORNERSTONE_IMAGE_VOLUME_MODIFIED", + // (undocumented) + PRE_STACK_NEW_IMAGE = "CORNERSTONE_PRE_STACK_NEW_IMAGE", + // (undocumented) + STACK_NEW_IMAGE = "CORNERSTONE_STACK_NEW_IMAGE", + // (undocumented) + STACK_VIEWPORT_NEW_STACK = "CORNERSTONE_STACK_VIEWPORT_NEW_STACK", + // (undocumented) + STACK_VIEWPORT_SCROLL = "CORNERSTONE_STACK_VIEWPORT_SCROLL", + // (undocumented) + VOI_MODIFIED = "CORNERSTONE_VOI_MODIFIED", + // (undocumented) + VOLUME_CACHE_VOLUME_ADDED = "CORNERSTONE_VOLUME_CACHE_VOLUME_ADDED", + // (undocumented) + VOLUME_CACHE_VOLUME_REMOVED = "CORNERSTONE_VOLUME_CACHE_VOLUME_REMOVED", + // (undocumented) + VOLUME_LOADED = "CORNERSTONE_VOLUME_LOADED", + // (undocumented) + VOLUME_LOADED_FAILED = "CORNERSTONE_VOLUME_LOADED_FAILED", + // (undocumented) + VOLUME_NEW_IMAGE = "CORNERSTONE_VOLUME_NEW_IMAGE", + // (undocumented) + VOLUME_VIEWPORT_NEW_VOLUME = "CORNERSTONE_VOLUME_VIEWPORT_NEW_VOLUME" +} + +// @public (undocumented) +export const eventTarget: CornerstoneEventTarget; + +declare namespace EventTypes { + export { + CameraModifiedEventDetail, + CameraModifiedEvent, + VoiModifiedEvent, + VoiModifiedEventDetail, + ElementDisabledEvent, + ElementDisabledEventDetail, + ElementEnabledEvent, + ElementEnabledEventDetail, + ImageRenderedEventDetail, + ImageRenderedEvent, + ImageVolumeModifiedEvent, + ImageVolumeModifiedEventDetail, + ImageLoadedEvent, + ImageLoadedEventDetail, + ImageLoadedFailedEventDetail, + ImageLoadedFailedEvent, + VolumeLoadedEvent, + VolumeLoadedEventDetail, + VolumeLoadedFailedEvent, + VolumeLoadedFailedEventDetail, + ImageCacheImageAddedEvent, + ImageCacheImageAddedEventDetail, + ImageCacheImageRemovedEvent, + ImageCacheImageRemovedEventDetail, + VolumeCacheVolumeAddedEvent, + VolumeCacheVolumeAddedEventDetail, + VolumeCacheVolumeRemovedEvent, + VolumeCacheVolumeRemovedEventDetail, + StackNewImageEvent, + StackNewImageEventDetail, + PreStackNewImageEvent, + PreStackNewImageEventDetail, + ImageSpacingCalibratedEvent, + ImageSpacingCalibratedEventDetail, + ImageLoadProgressEvent, + ImageLoadProgressEventDetail, + VolumeNewImageEvent, + VolumeNewImageEventDetail, + StackViewportNewStackEvent, + StackViewportNewStackEventDetail, + StackViewportScrollEvent, + StackViewportScrollEventDetail + } +} + +// @public (undocumented) +type FlipDirection = { + flipHorizontal?: boolean; + flipVertical?: boolean; +}; + +// @public (undocumented) +function getClosestImageId(imageVolume: IImageVolume, worldPos: Point3, viewPlaneNormal: Point3, viewUp: Point3): string; + +// @public (undocumented) +function getClosestStackImageIndexForPoint(point: Point3, viewport: IStackViewport): number | null; + +// @public (undocumented) +export function getEnabledElement(element: HTMLDivElement | undefined): IEnabledElement | undefined; + +// @public (undocumented) +export function getEnabledElementByIds(viewportId: string, renderingEngineId: string): IEnabledElement; + +// @public (undocumented) +export function getEnabledElements(): IEnabledElement[]; + +// @public (undocumented) +function getImageSliceDataForVolumeViewport(viewport: IVolumeViewport): ImageSliceData; + +// @public (undocumented) +function getMetaData(type: string, query: string): any; + +// @public (undocumented) +function getMinMax(storedPixelData: number[]): { + min: number; + max: number; +}; + +// @public (undocumented) +export function getOrCreateCanvas(element: HTMLDivElement): HTMLCanvasElement; + +// @public (undocumented) +export function getRenderingEngine(id: string): IRenderingEngine | undefined; + +// @public (undocumented) +export function getRenderingEngines(): IRenderingEngine[] | undefined; + +// @public (undocumented) +function getRuntimeId(context?: unknown, separator?: string, max?: number): string; + +// @public (undocumented) +export function getShouldUseCPURendering(): boolean; + +// @public (undocumented) +function getSliceRange(volumeActor: VolumeActor, viewPlaneNormal: Point3, focalPoint: Point3): ActorSliceRange; + +// @public (undocumented) +function getSpacingInNormalDirection(imageVolume: IImageVolume, viewPlaneNormal: Point3): number; + +// @public (undocumented) +function getTargetVolumeAndSpacingInNormalDir(viewport: IVolumeViewport, camera: ICamera, targetVolumeId?: string): { + imageVolume: IImageVolume; + spacingInNormalDirection: number; +}; + +// @public (undocumented) +function getViewportImageCornersInWorld(viewport: IStackViewport | IVolumeViewport): Point3[]; + +// @public (undocumented) +function getViewportsWithImageURI(imageURI: string, renderingEngineId?: string): Array; + +// @public (undocumented) +function getViewportsWithVolumeId(volumeId: string, renderingEngineId?: string): Array; + +// @public (undocumented) +function getVolumeActorCorners(volumeActor: any): Array; + +// @public (undocumented) +function getVolumeViewportsContainingSameVolumes(targetViewport: IVolumeViewport, renderingEngineId?: string): Array; + +// @public (undocumented) +function hasNaNValues(input: number[] | number): boolean; + +// @public (undocumented) +interface ICache { + // (undocumented) + getCacheSize: () => number; + // (undocumented) + getImageLoadObject: (imageId: string) => IImageLoadObject | void; + // (undocumented) + getMaxCacheSize: () => number; + // (undocumented) + getVolumeLoadObject: (volumeId: string) => IVolumeLoadObject | void; + // (undocumented) + purgeCache: () => void; + // (undocumented) + putImageLoadObject: (imageId: string, imageLoadObject: IImageLoadObject) => Promise; + // (undocumented) + putVolumeLoadObject: (volumeId: string, volumeLoadObject: IVolumeLoadObject) => Promise; + // (undocumented) + setMaxCacheSize: (maxCacheSize: number) => void; +} + +// @public (undocumented) +interface ICachedImage { + // (undocumented) + image?: IImage; + // (undocumented) + imageId: string; + // (undocumented) + imageLoadObject: IImageLoadObject; + // (undocumented) + loaded: boolean; + // (undocumented) + sharedCacheKey?: string; + // (undocumented) + sizeInBytes: number; + // (undocumented) + timeStamp: number; +} + +// @public (undocumented) +interface ICachedVolume { + // (undocumented) + loaded: boolean; + // (undocumented) + sizeInBytes: number; + // (undocumented) + timeStamp: number; + // (undocumented) + volume?: IImageVolume; + // (undocumented) + volumeId: string; + // (undocumented) + volumeLoadObject: IVolumeLoadObject; +} + +// @public (undocumented) +interface ICamera { + // (undocumented) + clippingRange?: Point2; + // (undocumented) + flipHorizontal?: boolean; + // (undocumented) + flipVertical?: boolean; + // (undocumented) + focalPoint?: Point3; + // (undocumented) + parallelProjection?: boolean; + // (undocumented) + parallelScale?: number; + // (undocumented) + position?: Point3; + // (undocumented) + scale?: number; + // (undocumented) + viewAngle?: number; + // (undocumented) + viewPlaneNormal?: Point3; + // (undocumented) + viewUp?: Point3; +} + +// @public (undocumented) +interface IEnabledElement { + // (undocumented) + FrameOfReferenceUID: string; + // (undocumented) + renderingEngine: IRenderingEngine; + // (undocumented) + renderingEngineId: string; + // (undocumented) + viewport: IStackViewport | IVolumeViewport; + // (undocumented) + viewportId: string; +} + +// @public (undocumented) +interface IImage { + // (undocumented) + cachedLut?: { + windowWidth?: number | number[]; + windowCenter?: number | number[]; + invert?: boolean; + lutArray?: Uint8ClampedArray; + modalityLUT?: unknown; + voiLUT?: CPUFallbackLUT; + }; + // (undocumented) + color: boolean; + // (undocumented) + colormap?: CPUFallbackColormap; + // (undocumented) + columnPixelSpacing: number; + // (undocumented) + columns: number; + // (undocumented) + getCanvas: () => HTMLCanvasElement; + // (undocumented) + getPixelData: () => Array; + // (undocumented) + height: number; + // (undocumented) + imageId: string; + // (undocumented) + intercept: number; + // (undocumented) + invert: boolean; + // (undocumented) + isPreScaled?: boolean; + // (undocumented) + maxPixelValue: number; + // (undocumented) + minPixelValue: number; + // (undocumented) + modalityLUT?: CPUFallbackLUT; + // (undocumented) + numComps: number; + // (undocumented) + preScale?: { + scaled: boolean; + scalingParameters: { + modality?: string; + rescaleSlope?: number; + rescaleIntercept?: number; + suvbw?: number; + }; + }; + // (undocumented) + render?: (enabledElement: CPUFallbackEnabledElement, invalidated: boolean) => unknown; + // (undocumented) + rgba: boolean; + // (undocumented) + rowPixelSpacing: number; + // (undocumented) + rows: number; + // (undocumented) + scaling?: { + PET?: { + SUVlbmFactor?: number; + SUVbsaFactor?: number; + suvbwToSuvlbm?: number; + suvbwToSuvbsa?: number; + }; + }; + // (undocumented) + sharedCacheKey?: string; + // (undocumented) + sizeInBytes: number; + // (undocumented) + sliceThickness?: number; + // (undocumented) + slope: number; + // (undocumented) + stats?: { + lastStoredPixelDataToCanvasImageDataTime?: number; + lastGetPixelDataTime?: number; + lastPutImageDataTime?: number; + lastLutGenerateTime?: number; + lastRenderedViewport?: unknown; + lastRenderTime?: number; + }; + // (undocumented) + voiLUT?: CPUFallbackLUT; + // (undocumented) + width: number; + // (undocumented) + windowCenter: number[] | number; + // (undocumented) + windowWidth: number[] | number; +} + +// @public (undocumented) +interface IImageData { + // (undocumented) + dimensions: Point3; + // (undocumented) + direction: Mat3; + // (undocumented) + hasPixelSpacing?: boolean; + // (undocumented) + imageData: vtkImageData; + // (undocumented) + metadata: { + Modality: string; + }; + // (undocumented) + origin: Point3; + // (undocumented) + preScale?: { + scaled?: boolean; + scalingParameters?: { + modality?: string; + rescaleSlope?: number; + rescaleIntercept?: number; + suvbw?: number; + }; + }; + // (undocumented) + scalarData: Float32Array; + // (undocumented) + scaling?: Scaling; + // (undocumented) + spacing: Point3; +} + +// @public (undocumented) +interface IImageLoadObject { + // (undocumented) + cancelFn?: () => void; + // (undocumented) + decache?: () => void; + // (undocumented) + promise: Promise; +} + +// @public (undocumented) +interface IImageVolume { + // (undocumented) + cancelLoading?: () => void; + // (undocumented) + convertToCornerstoneImage?: (imageId: string, imageIdIndex: number) => IImageLoadObject; + // (undocumented) + dimensions: Point3; + // (undocumented) + direction: Mat3; + // (undocumented) + hasPixelSpacing: boolean; + // (undocumented) + imageData?: vtkImageData; + // (undocumented) + imageIds?: Array; + // (undocumented) + isPrescaled: boolean; + // (undocumented) + loadStatus?: Record; + // (undocumented) + metadata: Metadata; + // (undocumented) + numVoxels: number; + // (undocumented) + origin: Point3; + // (undocumented) + referencedVolumeId?: string; + // (undocumented) + scalarData: any; + // (undocumented) + scaling?: { + PET?: { + SUVlbmFactor?: number; + SUVbsaFactor?: number; + suvbwToSuvlbm?: number; + suvbwToSuvbsa?: number; + }; + }; + // (undocumented) + sizeInBytes?: number; + // (undocumented) + spacing: Point3; + // (undocumented) + readonly volumeId: string; + // (undocumented) + vtkOpenGLTexture: any; +} + +// @public (undocumented) +type ImageCacheImageAddedEvent = CustomEvent_2; + +// @public (undocumented) +type ImageCacheImageAddedEventDetail = { + image: ICachedImage; +}; + +// @public (undocumented) +type ImageCacheImageRemovedEvent = CustomEvent_2; + +// @public (undocumented) +type ImageCacheImageRemovedEventDetail = { + imageId: string; +}; + +// @public (undocumented) +function imageIdToURI(imageId: string): string; + +// @public (undocumented) +type ImageLoadedEvent = CustomEvent_2; + +// @public (undocumented) +type ImageLoadedEventDetail = { + image: IImage; +}; + +// @public (undocumented) +type ImageLoadedFailedEvent = CustomEvent_2; + +// @public (undocumented) +type ImageLoadedFailedEventDetail = { + imageId: string; + error: unknown; +}; + +declare namespace imageLoader { + export { + loadImage, + loadAndCacheImage, + loadAndCacheImages, + cancelLoadImage, + cancelLoadImages, + cancelLoadAll, + registerImageLoader, + registerUnknownImageLoader, + unregisterAllImageLoaders, + ImageLoaderOptions + } +} +export { imageLoader } + +// @public (undocumented) +type ImageLoaderFn = (imageId: string, options?: Record) => { + promise: Promise>; + cancelFn?: () => void | undefined; + decache?: () => void | undefined; +}; + +// @public (undocumented) +interface ImageLoaderOptions { + // (undocumented) + additionalDetails?: Record; + // (undocumented) + priority: number; + // (undocumented) + requestType: string; +} + +// @public (undocumented) +const imageLoadPoolManager: RequestPoolManager; +export { imageLoadPoolManager } +export { imageLoadPoolManager as requestPoolManager } + +// @public (undocumented) +type ImageLoadProgressEvent = CustomEvent_2; + +// @public (undocumented) +type ImageLoadProgressEventDetail = { + url: string; + imageId: string; + loaded: number; + total: number; + percent: number; +}; + +// @public (undocumented) +type ImageRenderedEvent = CustomEvent_2; + +// @public (undocumented) +type ImageRenderedEventDetail = { + element: HTMLDivElement; + viewportId: string; + renderingEngineId: string; + suppressEvents?: boolean; +}; + +// @public (undocumented) +export const imageRetrievalPoolManager: RequestPoolManager; + +// @public (undocumented) +type ImageSliceData = { + numberOfSlices: number; + imageIndex: number; +}; + +// @public (undocumented) +type ImageSpacingCalibratedEvent = CustomEvent_2; + +// @public (undocumented) +type ImageSpacingCalibratedEventDetail = { + element: HTMLDivElement; + viewportId: string; + renderingEngineId: string; + imageId: string; + rowScale: number; + columnScale: number; + imageData: vtkImageData; + worldToIndex: mat4; +}; + +// @public (undocumented) +function imageToWorldCoords(imageId: string, imageCoords: Point2): Point3 | undefined; + +// @public (undocumented) +export class ImageVolume implements IImageVolume { + constructor(props: IVolume); + // (undocumented) + cancelLoading: () => void; + // (undocumented) + dimensions: Point3; + // (undocumented) + direction: Mat3; + // (undocumented) + hasPixelSpacing: boolean; + // (undocumented) + imageData?: any; + // (undocumented) + imageIds?: Array; + // (undocumented) + isPrescaled: boolean; + // (undocumented) + loadStatus?: Record; + // (undocumented) + metadata: Metadata; + // (undocumented) + numVoxels: number; + // (undocumented) + origin: Point3; + // (undocumented) + referencedVolumeId?: string; + // (undocumented) + scalarData: Float32Array | Uint8Array; + // (undocumented) + scaling?: { + PET?: { + SUVlbmFactor?: number; + SUVbsaFactor?: number; + suvbwToSuvlbm?: number; + suvbwToSuvbsa?: number; + }; + }; + // (undocumented) + sizeInBytes?: number; + // (undocumented) + spacing: Point3; + // (undocumented) + readonly volumeId: string; + // (undocumented) + vtkOpenGLTexture: any; +} + +// @public (undocumented) +type ImageVolumeModifiedEvent = CustomEvent_2; + +// @public (undocumented) +type ImageVolumeModifiedEventDetail = { + imageVolume: IImageVolume; + FrameOfReferenceUID: string; +}; + +// @public (undocumented) +function indexWithinDimensions(index: Point3, dimensions: Point3): boolean; + +// @public (undocumented) +export function init(defaultConfiguration?: {}): Promise; + +// @public (undocumented) +enum InterpolationType { + // (undocumented) + FAST_LINEAR = 2, + // (undocumented) + LINEAR = 1, + // (undocumented) + NEAREST = 0 +} + +// @public (undocumented) +function invertRgbTransferFunction(rgbTransferFunction: any): void; + +// @public (undocumented) +interface IRegisterImageLoader { + // (undocumented) + registerImageLoader: (scheme: string, imageLoader: ImageLoaderFn) => void; +} + +// @public (undocumented) +interface IRenderingEngine { + // (undocumented) + _debugRender(): void; + // (undocumented) + destroy(): void; + // (undocumented) + disableElement(viewportId: string): void; + // (undocumented) + enableElement(viewportInputEntry: PublicViewportInput): void; + // (undocumented) + fillCanvasWithBackgroundColor(canvas: HTMLCanvasElement, backgroundColor: [number, number, number]): void; + // (undocumented) + getStackViewports(): Array; + // (undocumented) + getViewport(id: string): IStackViewport | IVolumeViewport; + // (undocumented) + getViewports(): Array; + // (undocumented) + getVolumeViewports(): Array; + // (undocumented) + hasBeenDestroyed: boolean; + // (undocumented) + id: string; + // (undocumented) + offScreenCanvasContainer: any; + // (undocumented) + offscreenMultiRenderWindow: any; + // (undocumented) + render(): void; + // (undocumented) + renderFrameOfReference(FrameOfReferenceUID: string): void; + // (undocumented) + renderViewport(viewportId: string): void; + // (undocumented) + renderViewports(viewportIds: Array): void; + // (undocumented) + resize(immediate?: boolean, resetPan?: boolean, resetZoom?: boolean): void; + // (undocumented) + setViewports(viewports: Array): void; +} + +// @public (undocumented) +export function isCornerstoneInitialized(): boolean; + +// @public (undocumented) +function isEqual(v1: number[] | Float32Array, v2: number[] | Float32Array, tolerance?: number): boolean; + +// @public (undocumented) +function isImageActor(actor: vtkActor | vtkVolume | vtkImageSlice): boolean; + +// @public (undocumented) +function isOpposite(v1: Point3, v2: Point3, tolerance?: number): boolean; + +// @public (undocumented) +interface IStackViewport extends IViewport { + // (undocumented) + calibrateSpacing(imageId: string): void; + // (undocumented) + canvasToWorld: (canvasPos: Point2) => Point3; + // (undocumented) + customRenderViewportToCanvas: () => { + canvas: HTMLCanvasElement; + element: HTMLDivElement; + viewportId: string; + renderingEngineId: string; + }; + // (undocumented) + getCamera(): ICamera; + // (undocumented) + getCurrentImageId: () => string; + // (undocumented) + getCurrentImageIdIndex: () => number; + // (undocumented) + getFrameOfReferenceUID: () => string; + // (undocumented) + getImageData(): IImageData | CPUIImageData; + // (undocumented) + getImageIds: () => string[]; + // (undocumented) + getProperties: () => StackViewportProperties; + // (undocumented) + getRenderer(): any; + // (undocumented) + hasImageId: (imageId: string) => boolean; + // (undocumented) + hasImageURI: (imageURI: string) => boolean; + // (undocumented) + modality: string; + // (undocumented) + resetCamera(resetPan?: boolean, resetZoom?: boolean): boolean; + // (undocumented) + resetProperties(): void; + // (undocumented) + resize: () => void; + // (undocumented) + scaling: Scaling; + // (undocumented) + setCamera(cameraInterface: ICamera): void; + // (undocumented) + setColormap(colormap: CPUFallbackColormapData): void; + // (undocumented) + setImageIdIndex(imageIdIndex: number): Promise; + // (undocumented) + setProperties({ voiRange, invert, interpolationType, rotation }: StackViewportProperties, suppressEvents?: boolean): void; + // (undocumented) + setStack(imageIds: Array, currentImageIdIndex?: number): Promise; + // (undocumented) + unsetColormap(): void; + // (undocumented) + worldToCanvas: (worldPos: Point3) => Point2; +} + +// @public (undocumented) +interface IStreamingImageVolume extends ImageVolume { + // (undocumented) + clearLoadCallbacks(): void; + // (undocumented) + convertToCornerstoneImage(imageId: string, imageIdIndex: number): any; + // (undocumented) + decache(completelyRemove: boolean): void; +} + +// @public (undocumented) +interface IStreamingVolumeProperties { + // (undocumented) + imageIds: Array; + // (undocumented) + loadStatus: { + loaded: boolean; + loading: boolean; + cachedFrames: Array; + callbacks: Array<() => void>; + }; +} + +// @public (undocumented) +interface IViewport { + // (undocumented) + _actors: Map; + // (undocumented) + addActor(actorEntry: ActorEntry): void; + // (undocumented) + addActors(actors: Array): void; + // (undocumented) + canvas: HTMLCanvasElement; + // (undocumented) + canvasToWorld: (canvasPos: Point2) => Point3; + // (undocumented) + customRenderViewportToCanvas: () => unknown; + // (undocumented) + defaultOptions: any; + // (undocumented) + element: HTMLDivElement; + // (undocumented) + getActor(actorUID: string): ActorEntry; + // (undocumented) + getActorByIndex(index: number): ActorEntry; + // (undocumented) + getActors(): Array; + // (undocumented) + getActorUIDByIndex(index: number): string; + // (undocumented) + getCamera(): ICamera; + // (undocumented) + getCanvas(): HTMLCanvasElement; + // (undocumented) + _getCorners(bounds: Array): Array[]; + // (undocumented) + getDefaultActor(): ActorEntry; + // (undocumented) + getFrameOfReferenceUID: () => string; + // (undocumented) + getPan(): Point2; + // (undocumented) + getRenderer(): void; + // (undocumented) + getRenderingEngine(): any; + // (undocumented) + getZoom(): number; + // (undocumented) + id: string; + // (undocumented) + isDisabled: boolean; + // (undocumented) + options: ViewportInputOptions; + // (undocumented) + removeAllActors(): void; + // (undocumented) + render(): void; + // (undocumented) + renderingEngineId: string; + // (undocumented) + reset(immediate: boolean): void; + // (undocumented) + setActors(actors: Array): void; + // (undocumented) + setCamera(cameraInterface: ICamera, storeAsInitialCamera?: boolean): void; + // (undocumented) + setOptions(options: ViewportInputOptions, immediate: boolean): void; + // (undocumented) + setPan(pan: Point2, storeAsInitialCamera?: boolean): any; + // (undocumented) + setZoom(zoom: number, storeAsInitialCamera?: boolean): any; + // (undocumented) + sHeight: number; + // (undocumented) + suppressEvents: boolean; + // (undocumented) + sWidth: number; + // (undocumented) + sx: number; + // (undocumented) + sy: number; + // (undocumented) + type: ViewportType; + // (undocumented) + worldToCanvas: (worldPos: Point3) => Point2; +} + +// @public (undocumented) +interface IViewportId { + // (undocumented) + renderingEngineId: string; + // (undocumented) + viewportId: string; +} + +// @public (undocumented) +interface IVolume { + // (undocumented) + dimensions: Point3; + // (undocumented) + direction: Mat3; + // (undocumented) + imageData?: vtkImageData; + // (undocumented) + metadata: Metadata; + // (undocumented) + origin: Point3; + // (undocumented) + referencedVolumeId?: string; + // (undocumented) + scalarData: Float32Array | Uint8Array; + // (undocumented) + scaling?: { + PET?: { + SUVlbmFactor?: number; + SUVbsaFactor?: number; + suvbwToSuvlbm?: number; + suvbwToSuvbsa?: number; + }; + }; + // (undocumented) + sizeInBytes?: number; + // (undocumented) + spacing: Point3; + // (undocumented) + volumeId: string; +} + +// @public (undocumented) +interface IVolumeInput { + // (undocumented) + actorUID?: string; + // (undocumented) + blendMode?: BlendModes; + // (undocumented) + callback?: VolumeInputCallback; + // (undocumented) + slabThickness?: number; + // (undocumented) + visibility?: boolean; + // (undocumented) + volumeId: string; +} + +// @public (undocumented) +interface IVolumeLoadObject { + // (undocumented) + cancelFn?: () => void; + // (undocumented) + decache?: () => void; + // (undocumented) + promise: Promise; +} + +// @public (undocumented) +interface IVolumeViewport extends IViewport { + // (undocumented) + addVolumes(volumeInputArray: Array, immediate?: boolean, suppressEvents?: boolean): Promise; + // (undocumented) + canvasToWorld: (canvasPos: Point2) => Point3; + // (undocumented) + flip(flipDirection: FlipDirection): void; + // (undocumented) + getBounds(): any; + // (undocumented) + getCurrentImageId: () => string; + // (undocumented) + getCurrentImageIdIndex: () => number; + // (undocumented) + getFrameOfReferenceUID: () => string; + // (undocumented) + getImageData(volumeId?: string): IImageData | undefined; + // (undocumented) + getIntensityFromWorld(point: Point3): number; + // (undocumented) + getProperties: () => any; + // (undocumented) + getSlabThickness(): number; + // (undocumented) + hasImageURI: (imageURI: string) => boolean; + // (undocumented) + hasVolumeId: (volumeId: string) => boolean; + // (undocumented) + removeVolumeActors(actorUIDs: Array, immediate?: boolean): void; + // (undocumented) + resetCamera(resetPan?: boolean, resetZoom?: boolean, resetToCenter?: boolean): boolean; + // (undocumented) + setBlendMode(blendMode: BlendModes, filterActorUIDs?: Array, immediate?: boolean): void; + // (undocumented) + setOrientation(orientation: OrientationAxis): void; + // (undocumented) + setProperties({ voiRange }: VolumeViewportProperties, volumeId?: string, suppressEvents?: boolean): void; + // (undocumented) + setSlabThickness(slabThickness: number, filterActorUIDs?: Array): void; + // (undocumented) + setVolumes(volumeInputArray: Array, immediate?: boolean, suppressEvents?: boolean): Promise; + // (undocumented) + useCPURendering: boolean; + // (undocumented) + worldToCanvas: (worldPos: Point3) => Point2; +} + +// @public (undocumented) +function linePlaneIntersection(p0: Point3, p1: Point3, plane: Plane): Point3; + +// @public (undocumented) +function loadAndCacheImage(imageId: string, options?: ImageLoaderOptions): Promise; + +// @public (undocumented) +function loadAndCacheImages(imageIds: Array, options?: ImageLoaderOptions): Promise[]; + +// @public (undocumented) +function loadImage(imageId: string, options?: ImageLoaderOptions): Promise; + +// @public (undocumented) +function loadImageToCanvas(canvas: HTMLCanvasElement, imageId: string, requestType?: RequestType, priority?: number): Promise; + +// @public (undocumented) +function loadVolume(volumeId: string, options?: VolumeLoaderOptions): Promise; + +// @public (undocumented) +type Mat3 = [ +number, +number, +number, +number, +number, +number, +number, +number, +number +]; + +// @public (undocumented) +type Metadata = { + BitsAllocated: number; + BitsStored: number; + SamplesPerPixel: number; + HighBit: number; + PhotometricInterpretation: string; + PixelRepresentation: number; + Modality: string; + SeriesInstanceUID?: string; + ImageOrientationPatient: Array; + PixelSpacing: Array; + FrameOfReferenceUID: string; + Columns: number; + Rows: number; + voiLut: Array; +}; + +declare namespace metaData { + export { + addProvider, + removeProvider, + removeAllProviders, + getMetaData as get + } +} +export { metaData } + +// @public (undocumented) +const metadataProvider: { + add: (imageId: string, payload: [number, number]) => void; + get: (type: string, imageId: string) => [number, number]; +}; + +// @public (undocumented) +const mprCameraValues: any; + +// @public (undocumented) +enum OrientationAxis { + // (undocumented) + ACQUISITION = "acquisition", + // (undocumented) + AXIAL = "axial", + // (undocumented) + CORONAL = "coronal", + // (undocumented) + SAGITTAL = "sagittal" +} + +// @public (undocumented) +type OrientationVectors = { + viewPlaneNormal: Point3; + viewUp: Point3; +}; + +declare namespace planar { + export { + linePlaneIntersection, + planeEquation, + threePlaneIntersection, + planeDistanceToPoint + } +} + +// @public (undocumented) +type Plane = [number, number, number, number]; + +// @public (undocumented) +function planeDistanceToPoint(plane: Plane, point: Point3, signed?: boolean): number; + +// @public (undocumented) +function planeEquation(normal: Point3, point: Point3 | vec3): Plane; + +// @public (undocumented) +type Point2 = [number, number]; + +// @public (undocumented) +type Point3 = [number, number, number]; + +// @public (undocumented) +type Point4 = [number, number, number, number]; + +// @public (undocumented) +type PreStackNewImageEvent = CustomEvent_2; + +// @public (undocumented) +type PreStackNewImageEventDetail = { + imageId: string; + imageIdIndex: number; + viewportId: string; + renderingEngineId: string; +}; + +// @public (undocumented) +type PTScaling = { + suvbwToSuvlbm?: number; + suvbwToSuvbsa?: number; +}; + +// @public (undocumented) +type PublicViewportInput = { + element: HTMLDivElement; + viewportId: string; + type: ViewportType; + defaultOptions?: ViewportInputOptions; +}; + +// @public (undocumented) +export function registerImageLoader(scheme: string, imageLoader: ImageLoaderFn): void; + +// @public (undocumented) +function registerUnknownImageLoader(imageLoader: ImageLoaderFn): ImageLoaderFn; + +// @public (undocumented) +function registerUnknownVolumeLoader(volumeLoader: Types.VolumeLoaderFn): Types.VolumeLoaderFn | undefined; + +// @public (undocumented) +function registerVolumeLoader(scheme: string, volumeLoader: Types.VolumeLoaderFn): void; + +// @public (undocumented) +function removeAllProviders(): void; + +// @public (undocumented) +function removeProvider(provider: (type: string, query: any) => { + any: any; +}): void; + +// @public (undocumented) +const RENDERING_DEFAULTS: { + MINIMUM_SLAB_THICKNESS: number; + MAXIMUM_RAY_DISTANCE: number; +}; + +// @public (undocumented) +export class RenderingEngine implements IRenderingEngine { + constructor(id?: string); + // (undocumented) + _debugRender(): void; + // (undocumented) + destroy(): void; + // (undocumented) + disableElement(viewportId: string): void; + // (undocumented) + _downloadOffScreenCanvas(): void; + // (undocumented) + enableElement(viewportInputEntry: PublicViewportInput): void; + // (undocumented) + fillCanvasWithBackgroundColor(canvas: HTMLCanvasElement, backgroundColor: [number, number, number]): void; + // (undocumented) + getStackViewports(): Array; + // (undocumented) + getViewport(viewportId: string): IStackViewport | IVolumeViewport; + // (undocumented) + getViewports(): Array; + // (undocumented) + getVolumeViewports(): Array; + // (undocumented) + hasBeenDestroyed: boolean; + // (undocumented) + readonly id: string; + // (undocumented) + readonly offScreenCanvasContainer: any; + // (undocumented) + offscreenMultiRenderWindow: any; + // (undocumented) + render(): void; + // (undocumented) + renderFrameOfReference: (FrameOfReferenceUID: string) => void; + // (undocumented) + renderViewport(viewportId: string): void; + // (undocumented) + renderViewports(viewportIds: Array): void; + // (undocumented) + resize(immediate?: boolean, keepCamera?: boolean): void; + // (undocumented) + setViewports(publicViewportInputEntries: Array): void; +} + +// @public (undocumented) +function renderToCanvas(canvas: HTMLCanvasElement, image: IImage, modality?: string): void; + +// @public (undocumented) +enum RequestType { + // (undocumented) + Interaction = "interaction", + // (undocumented) + Prefetch = "prefetch", + // (undocumented) + Thumbnail = "thumbnail" +} + +// @public (undocumented) +export function resetUseCPURendering(): void; + +// @public (undocumented) +function scaleRGBTransferFunction(rgbTransferFunction: any, scalingFactor: number): void; + +// @public (undocumented) +type Scaling = { + PET?: PTScaling; +}; + +// @public (undocumented) +type ScalingParameters = { + rescaleSlope: number; + rescaleIntercept: number; + modality: string; + suvbw?: number; + suvlbm?: number; + suvbsa?: number; +}; + +// @public (undocumented) +export class Settings { + constructor(base?: Settings); + // (undocumented) + static assert(subject: Settings): Settings; + // (undocumented) + dump(): Record; + // (undocumented) + extend(): Settings; + // (undocumented) + static extendRuntimeSettings(): Settings; + // (undocumented) + forEach(callback: (key: string, value: unknown) => void): void; + // (undocumented) + get(key: string): unknown; + // (undocumented) + static getDefaultSettings(subfield?: any): Settings | any; + // (undocumented) + static getObjectSettings(subject: unknown, from?: unknown): Settings; + // (undocumented) + static getRuntimeSettings(): Settings; + // (undocumented) + import(root: Record): void; + // (undocumented) + set(key: string, value: unknown): boolean; + // (undocumented) + unset(key: string): boolean; +} + +// @public (undocumented) +export function setUseCPURendering(status: boolean): void; + +// @public (undocumented) +export function setVolumesForViewports(renderingEngine: IRenderingEngine, volumeInputs: Array, viewportIds: Array, immediateRender?: boolean, suppressEvents?: boolean): Promise; + +// @public (undocumented) +function snapFocalPointToSlice(focalPoint: Point3, position: Point3, sliceRange: ActorSliceRange, viewPlaneNormal: Point3, spacingInNormalDirection: number, deltaFrames: number): { + newFocalPoint: Point3; + newPosition: Point3; +}; + +// @public (undocumented) +const spatialRegistrationMetadataProvider: { + add: (query: string[], payload: mat4) => void; + get: (type: string, query: string[]) => mat4; +}; + +// @public (undocumented) +type StackNewImageEvent = CustomEvent_2; + +// @public (undocumented) +type StackNewImageEventDetail = { + image: IImage; + imageId: string; + imageIdIndex: number; + viewportId: string; + renderingEngineId: string; +}; + +// @public (undocumented) +export class StackViewport extends Viewport implements IStackViewport { + constructor(props: ViewportInput); + // (undocumented) + addActor(actorEntry: ActorEntry): void; + // (undocumented) + addActors(actors: Array): void; + // (undocumented) + calibrateSpacing(imageId: string): void; + // (undocumented) + canvasToWorld: (canvasPos: Point2) => Point3; + // (undocumented) + customRenderViewportToCanvas: () => { + canvas: HTMLCanvasElement; + element: HTMLDivElement; + viewportId: string; + renderingEngineId: string; + }; + // (undocumented) + getActor(actorUID: string): ActorEntry; + // (undocumented) + getActors(): Array; + // (undocumented) + getCamera(): ICamera; + // (undocumented) + getCurrentImageId: () => string; + // (undocumented) + getCurrentImageIdIndex: () => number; + // (undocumented) + getDefaultActor(): ActorEntry; + // (undocumented) + getFrameOfReferenceUID: () => string | undefined; + // (undocumented) + getImageData(): IImageData | CPUIImageData; + // (undocumented) + getImageIds: () => Array; + // (undocumented) + getProperties: () => StackViewportProperties; + // (undocumented) + getRenderer(): any; + // (undocumented) + getTargetImageIdIndex: () => number; + // (undocumented) + hasImageId: (imageId: string) => boolean; + // (undocumented) + hasImageURI: (imageURI: string) => boolean; + // (undocumented) + modality: string; + // (undocumented) + removeAllActors(): void; + // (undocumented) + resetCamera(resetPan?: boolean, resetZoom?: boolean): boolean; + // (undocumented) + resetProperties(): void; + // (undocumented) + resize: () => void; + // (undocumented) + scaling: Scaling; + // (undocumented) + scroll(delta: number, debounce?: boolean, loop?: boolean): void; + // (undocumented) + setActors(actors: Array): void; + // (undocumented) + setCamera(cameraInterface: ICamera, storeAsInitialCamera?: boolean): void; + // (undocumented) + setColormap(colormap: CPUFallbackColormapData): void; + // (undocumented) + setImageIdIndex(imageIdIndex: number): Promise; + // (undocumented) + setProperties({ voiRange, invert, interpolationType, rotation, }?: StackViewportProperties, suppressEvents?: boolean): void; + // (undocumented) + setStack(imageIds: Array, currentImageIdIndex?: number): Promise; + // (undocumented) + unsetColormap(): void; + // (undocumented) + static get useCustomRenderingPipeline(): boolean; + // (undocumented) + worldToCanvas: (worldPos: Point3) => Point2; +} + +// @public (undocumented) +type StackViewportNewStackEvent = CustomEvent_2; + +// @public (undocumented) +type StackViewportNewStackEventDetail = { + imageIds: string[]; + viewportId: string; + element: HTMLDivElement; + currentImageIdIndex: number; +}; + +// @public (undocumented) +type StackViewportProperties = { + voiRange?: VOIRange; + invert?: boolean; + interpolationType?: InterpolationType; + rotation?: number; + suppressEvents?: boolean; +}; + +// @public (undocumented) +type StackViewportScrollEvent = CustomEvent_2; + +// @public (undocumented) +type StackViewportScrollEventDetail = { + newImageIdIndex: number; + imageId: string; + direction: number; +}; + +// @public (undocumented) +function threePlaneIntersection(firstPlane: Plane, secondPlane: Plane, thirdPlane: Plane): Point3; + +// @public (undocumented) +function toLowHighRange(windowWidth: number, windowCenter: number): { + lower: number; + upper: number; +}; + +// @public (undocumented) +function toWindowLevel(low: number, high: number): { + windowWidth: number; + windowCenter: number; +}; + +// @public (undocumented) +type TransformMatrix2D = [number, number, number, number, number, number]; + +// @public (undocumented) +function transformWorldToIndex(imageData: any, worldPos: Point3): any; + +// @public (undocumented) +export function triggerEvent(el: EventTarget, type: string, detail?: unknown): boolean; + +declare namespace Types { + export { + ICamera, + IStackViewport, + IVolumeViewport, + IEnabledElement, + ICache, + IVolume, + IViewportId, + IImageVolume, + IRenderingEngine, + ScalingParameters, + PTScaling, + Scaling, + IStreamingImageVolume, + IImage, + IImageData, + CPUIImageData, + CPUImageData, + EventTypes, + ImageLoaderFn, + VolumeLoaderFn, + IRegisterImageLoader, + IStreamingVolumeProperties, + IViewport, + StackViewportProperties, + VolumeViewportProperties, + PublicViewportInput, + VolumeActor, + Actor, + ActorEntry, + IImageLoadObject, + IVolumeLoadObject, + IVolumeInput, + VolumeInputCallback, + Metadata, + OrientationVectors, + Point2, + Point3, + Point4, + Mat3, + Plane, + ViewportInputOptions, + VOIRange, + VOI, + FlipDirection, + ICachedImage, + ICachedVolume, + CPUFallbackEnabledElement, + CPUFallbackViewport, + CPUFallbackTransform, + CPUFallbackColormapData, + CPUFallbackViewportDisplayedArea, + CPUFallbackColormapsData, + CPUFallbackColormap, + TransformMatrix2D, + CPUFallbackLookupTable, + CPUFallbackLUT, + CPUFallbackRenderingTools, + CustomEvent_2 as CustomEventType, + ActorSliceRange, + ImageSliceData + } +} +export { Types } + +// @public (undocumented) +function unregisterAllImageLoaders(): void; + +declare namespace utilities { + export { + invertRgbTransferFunction, + scaleRGBTransferFunction as scaleRgbTransferFunction, + triggerEvent, + imageIdToURI, + metadataProvider as calibratedPixelSpacingMetadataProvider, + uuidv4, + planar, + getMinMax, + getRuntimeId, + isEqual, + isOpposite, + createFloat32SharedArray, + createUint8SharedArray, + windowLevel, + getClosestImageId, + getSpacingInNormalDirection, + getTargetVolumeAndSpacingInNormalDir, + getVolumeActorCorners, + indexWithinDimensions, + getVolumeViewportsContainingSameVolumes, + getViewportsWithVolumeId, + transformWorldToIndex, + loadImageToCanvas, + renderToCanvas, + worldToImageCoords, + imageToWorldCoords, + getSliceRange, + snapFocalPointToSlice, + getImageSliceDataForVolumeViewport, + isImageActor, + getViewportsWithImageURI, + getClosestStackImageIndexForPoint, + calculateViewportsSpatialRegistration, + spatialRegistrationMetadataProvider, + getViewportImageCornersInWorld, + hasNaNValues + } +} +export { utilities } + +// @public (undocumented) +function uuidv4(): string; + +// @public (undocumented) +export class Viewport implements IViewport { + constructor(props: ViewportInput); + // (undocumented) + _actors: Map; + // (undocumented) + addActor(actorEntry: ActorEntry): void; + // (undocumented) + addActors(actors: Array, resetCameraPanAndZoom?: boolean): void; + // (undocumented) + readonly canvas: HTMLCanvasElement; + // (undocumented) + canvasToWorld: (canvasPos: Point2) => Point3; + // (undocumented) + customRenderViewportToCanvas: () => unknown; + // (undocumented) + readonly defaultOptions: any; + // (undocumented) + readonly element: HTMLDivElement; + // (undocumented) + protected flip({ flipHorizontal, flipVertical }: FlipDirection): void; + // (undocumented) + protected flipHorizontal: boolean; + // (undocumented) + protected flipVertical: boolean; + // (undocumented) + getActor(actorUID: string): ActorEntry; + // (undocumented) + getActorByIndex(index: number): ActorEntry; + // (undocumented) + getActors(): Array; + // (undocumented) + getActorUIDByIndex(index: number): string; + // (undocumented) + getCamera(): ICamera; + // (undocumented) + getCanvas(): HTMLCanvasElement; + // (undocumented) + _getCorners(bounds: Array): Array[]; + // (undocumented) + getDefaultActor(): ActorEntry; + // (undocumented) + _getEdges(bounds: Array): Array<[number[], number[]]>; + // (undocumented) + _getFocalPointForResetCamera(centeredFocalPoint: Point3, previousCamera: ICamera, { resetPan, resetToCenter }: { + resetPan?: boolean; + resetToCenter?: boolean; + }): Point3; + // (undocumented) + getFrameOfReferenceUID: () => string; + // (undocumented) + getPan(): Point2; + // (undocumented) + getProperties: () => void; + // (undocumented) + getRenderer(): any; + // (undocumented) + getRenderingEngine(): IRenderingEngine; + // (undocumented) + protected getVtkActiveCamera(): vtkCamera | vtkSlabCamera; + // (undocumented) + getZoom(): number; + // (undocumented) + protected hasPixelSpacing: boolean; + // (undocumented) + readonly id: string; + // (undocumented) + protected initialCamera: ICamera; + // (undocumented) + isDisabled: boolean; + // (undocumented) + _isInBounds(point: Point3, bounds: number[]): boolean; + // (undocumented) + options: ViewportInputOptions; + // (undocumented) + removeActor(actorUID: string): void; + // (undocumented) + removeActors(actorUIDs: Array): void; + // (undocumented) + removeAllActors(): void; + // (undocumented) + render(): void; + // (undocumented) + readonly renderingEngineId: string; + // (undocumented) + reset(immediate?: boolean): void; + // (undocumented) + protected resetCamera(resetPan?: boolean, resetZoom?: boolean, resetToCenter?: boolean, storeAsInitialCamera?: boolean): boolean; + // (undocumented) + protected resetCameraNoEvent(): void; + // (undocumented) + resize: () => void; + // (undocumented) + protected rotation: number; + // (undocumented) + setActors(actors: Array): void; + // (undocumented) + setCamera(cameraInterface: ICamera, storeAsInitialCamera?: boolean): void; + // (undocumented) + protected setCameraNoEvent(camera: ICamera): void; + // (undocumented) + protected setInitialCamera(camera: ICamera): void; + // (undocumented) + setOptions(options: ViewportInputOptions, immediate?: boolean): void; + // (undocumented) + setOrientationOfClippingPlanes(vtkPlanes: Array, slabThickness: number, viewPlaneNormal: Point3, focalPoint: Point3): void; + // (undocumented) + setPan(pan: Point2, storeAsInitialCamera?: boolean): void; + // (undocumented) + setZoom(value: number, storeAsInitialCamera?: boolean): void; + // (undocumented) + sHeight: number; + // (undocumented) + readonly suppressEvents: boolean; + // (undocumented) + sWidth: number; + // (undocumented) + sx: number; + // (undocumented) + sy: number; + // (undocumented) + triggerCameraModifiedEventIfNecessary(previousCamera: ICamera, updatedCamera: ICamera): void; + // (undocumented) + readonly type: ViewportType; + // (undocumented) + protected updateClippingPlanesForActors(updatedCamera: ICamera): void; + // (undocumented) + static get useCustomRenderingPipeline(): boolean; + // (undocumented) + worldToCanvas: (worldPos: Point3) => Point2; +} + +// @public (undocumented) +type ViewportInputOptions = { + background?: [number, number, number]; + orientation?: OrientationAxis | OrientationVectors; + suppressEvents?: boolean; +}; + +// @public (undocumented) +enum ViewportType { + // (undocumented) + ORTHOGRAPHIC = "orthographic", + // (undocumented) + PERSPECTIVE = "perspective", + // (undocumented) + STACK = "stack" +} + +// @public (undocumented) +type VOI = { + windowWidth: number; + windowCenter: number; +}; + +// @public (undocumented) +type VoiModifiedEvent = CustomEvent_2; + +// @public (undocumented) +type VoiModifiedEventDetail = { + viewportId: string; + range: VOIRange; + volumeId?: string; +}; + +// @public (undocumented) +type VOIRange = { + upper: number; + lower: number; +}; + +// @public (undocumented) +type VolumeActor = vtkVolume; + +// @public (undocumented) +type VolumeCacheVolumeAddedEvent = CustomEvent_2; + +// @public (undocumented) +type VolumeCacheVolumeAddedEventDetail = { + volume: ICachedVolume; +}; + +// @public (undocumented) +type VolumeCacheVolumeRemovedEvent = CustomEvent_2; + +// @public (undocumented) +type VolumeCacheVolumeRemovedEventDetail = { + volumeId: string; +}; + +// @public (undocumented) +type VolumeInputCallback = (params: { + volumeActor: VolumeActor; + volumeId: string; +}) => unknown; + +// @public (undocumented) +type VolumeLoadedEvent = CustomEvent_2; + +// @public (undocumented) +type VolumeLoadedEventDetail = { + volume: IImageVolume; +}; + +// @public (undocumented) +type VolumeLoadedFailedEvent = CustomEvent_2; + +// @public (undocumented) +type VolumeLoadedFailedEventDetail = { + volumeId: string; + error: unknown; +}; + +declare namespace volumeLoader { + export { + loadVolume, + createAndCacheVolume, + createAndCacheDerivedVolume, + createLocalVolume, + registerVolumeLoader, + registerUnknownVolumeLoader + } +} +export { volumeLoader } + +// @public (undocumented) +type VolumeLoaderFn = (volumeId: string, options?: Record) => { + promise: Promise>; + cancelFn?: () => void | undefined; + decache?: () => void | undefined; +}; + +// @public (undocumented) +type VolumeNewImageEvent = CustomEvent_2; + +// @public (undocumented) +type VolumeNewImageEventDetail = { + imageIndex: number; + numberOfSlices: number; + viewportId: string; + renderingEngineId: string; +}; + +// @public (undocumented) +export class VolumeViewport extends BaseVolumeViewport { + constructor(props: ViewportInput); + // (undocumented) + addVolumes(volumeInputArray: Array, immediate?: boolean, suppressEvents?: boolean): Promise; + // (undocumented) + getCurrentImageId: () => string | undefined; + // (undocumented) + getCurrentImageIdIndex: () => number | undefined; + // (undocumented) + getIntensityFromWorld(point: Point3): number; + // (undocumented) + getSlabThickness(): number; + // (undocumented) + resetCamera(resetPan?: boolean, resetZoom?: boolean, resetToCenter?: boolean): boolean; + // (undocumented) + setBlendMode(blendMode: BlendModes, filterActorUIDs?: any[], immediate?: boolean): void; + // (undocumented) + setOrientation(orientation: OrientationAxis, immediate?: boolean): void; + // (undocumented) + setSlabThickness(slabThickness: number, filterActorUIDs?: any[]): void; + // (undocumented) + setVolumes(volumeInputArray: Array, immediate?: boolean, suppressEvents?: boolean): Promise; +} + +// @public (undocumented) +type VolumeViewportProperties = { + voiRange?: VOIRange; +}; + +declare namespace windowLevel { + export { + toWindowLevel, + toLowHighRange + } +} + +// @public (undocumented) +function worldToImageCoords(imageId: string, worldCoords: Point3): Point2 | undefined; + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/core/src/RenderingEngine/BaseVolumeViewport.ts b/packages/core/src/RenderingEngine/BaseVolumeViewport.ts new file mode 100644 index 0000000000..25a3590582 --- /dev/null +++ b/packages/core/src/RenderingEngine/BaseVolumeViewport.ts @@ -0,0 +1,674 @@ +import vtkVolume from '@kitware/vtk.js/Rendering/Core/Volume'; + +import cache from '../cache'; +import ViewportType from '../enums/ViewportType'; +import Viewport from './Viewport'; +import { createVolumeActor } from './helpers'; +import volumeNewImageEventDispatcher, { + resetVolumeNewImageState, +} from './helpers/volumeNewImageEventDispatcher'; +import { loadVolume } from '../volumeLoader'; +import vtkSlabCamera from './vtkClasses/vtkSlabCamera'; +import { getShouldUseCPURendering } from '../init'; +import type { + Point2, + Point3, + IImageData, + IVolumeInput, + ActorEntry, + FlipDirection, + VolumeViewportProperties, +} from '../types'; +import type { ViewportInput } from '../types/IViewport'; +import type IVolumeViewport from '../types/IVolumeViewport'; +import { Events, BlendModes, OrientationAxis } from '../enums'; +import eventTarget from '../eventTarget'; +import { imageIdToURI, triggerEvent } from '../utilities'; +import type { vtkSlabCamera as vtkSlabCameraType } from './vtkClasses/vtkSlabCamera'; +import { VoiModifiedEventDetail } from '../types/EventTypes'; + +/** + * Abstract base class for volume viewports. VolumeViewports are used to render + * 3D volumes from which various orientations can be viewed. Since VolumeViewports + * use SharedVolumeMappers behind the scene, memory footprint of visualizations + * of the same volume in different orientations is very small. + * + * For setting volumes on viewports you need to use {@link addVolumesToViewports} + * which will add volumes to the specified viewports. + */ +abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport { + useCPURendering = false; + private _FrameOfReferenceUID: string; + + constructor(props: ViewportInput) { + super(props); + + this.useCPURendering = getShouldUseCPURendering(); + + if (this.useCPURendering) { + throw new Error( + 'VolumeViewports cannot be used whilst CPU Fallback Rendering is enabled.' + ); + } + + const renderer = this.getRenderer(); + + const camera = vtkSlabCamera.newInstance(); + renderer.setActiveCamera(camera); + + switch (this.type) { + case ViewportType.ORTHOGRAPHIC: + camera.setParallelProjection(true); + break; + case ViewportType.PERSPECTIVE: + camera.setParallelProjection(false); + break; + default: + throw new Error(`Unrecognized viewport type: ${this.type}`); + } + + this.initializeVolumeNewImageEventDispatcher(); + } + + static get useCustomRenderingPipeline(): boolean { + return false; + } + + private initializeVolumeNewImageEventDispatcher(): void { + const volumeNewImageHandlerBound = volumeNewImageHandler.bind(this); + const volumeNewImageCleanUpBound = volumeNewImageCleanUp.bind(this); + + function volumeNewImageHandler(cameraEvent) { + const { viewportId } = cameraEvent.detail; + + if (viewportId !== this.id || this.isDisabled) { + return; + } + + const viewportImageData = this.getImageData(); + + if (!viewportImageData) { + return; + } + + volumeNewImageEventDispatcher(cameraEvent); + } + + function volumeNewImageCleanUp(evt) { + const { viewportId } = evt.detail; + + if (viewportId !== this.id) { + return; + } + + this.element.removeEventListener( + Events.CAMERA_MODIFIED, + volumeNewImageHandlerBound + ); + + eventTarget.removeEventListener( + Events.ELEMENT_DISABLED, + volumeNewImageCleanUpBound + ); + + resetVolumeNewImageState(viewportId); + } + + this.element.removeEventListener( + Events.CAMERA_MODIFIED, + volumeNewImageHandlerBound + ); + this.element.addEventListener( + Events.CAMERA_MODIFIED, + volumeNewImageHandlerBound + ); + + eventTarget.addEventListener( + Events.ELEMENT_DISABLED, + volumeNewImageCleanUpBound + ); + } + + /** + * Sets the properties for the volume viewport on the volume + * (if fusion, it sets it for the first volume in the fusion) + * + * @param voiRange - Sets the lower and upper voi + * @param volumeId - The volume id to set the properties for (if undefined, the first volume) + * @param suppressEvents - If true, the viewport will not emit events + */ + public setProperties( + { voiRange }: VolumeViewportProperties = {}, + volumeId?: string, + suppressEvents = false + ): void { + if (volumeId !== undefined && !this.getActor(volumeId)) { + return; + } + + const actorEntries = this.getActors(); + + if (!actorEntries.length) { + return; + } + + let volumeActor; + + if (volumeId) { + const actorEntry = actorEntries.find((entry: ActorEntry) => { + return entry.uid === volumeId; + }); + + volumeActor = actorEntry?.actor as vtkVolume; + } + + // // set it for the first volume (if there are more than one - fusion) + if (!volumeActor) { + volumeActor = actorEntries[0].actor as vtkVolume; + volumeId = actorEntries[0].uid; + } + + if (!voiRange) { + return; + } + + // Todo: later when we have more properties, refactor the setVoiRange code below + const { lower, upper } = voiRange; + volumeActor.getProperty().getRGBTransferFunction(0).setRange(lower, upper); + + if (!suppressEvents) { + const eventDetail: VoiModifiedEventDetail = { + viewportId: this.id, + range: voiRange, + volumeId: volumeId, + }; + + triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail); + } + } + + /** + * Creates volume actors for all volumes defined in the `volumeInputArray`. + * For each entry, if a `callback` is supplied, it will be called with the new volume actor as input. + * For each entry, if a `blendMode` and/or `slabThickness` is defined, this will be set on the actor's + * `VolumeMapper`. + * + * @param volumeInputArray - The array of `VolumeInput`s which define the volumes to add. + * @param immediate - Whether the `Viewport` should be rendered as soon as volumes are added. + */ + public async setVolumes( + volumeInputArray: Array, + immediate = false, + suppressEvents = false + ): Promise { + const firstImageVolume = cache.getVolume(volumeInputArray[0].volumeId); + + if (!firstImageVolume) { + throw new Error( + `imageVolume with id: ${firstImageVolume.volumeId} does not exist` + ); + } + + const FrameOfReferenceUID = firstImageVolume.metadata.FrameOfReferenceUID; + + await this._isValidVolumeInputArray(volumeInputArray, FrameOfReferenceUID); + + this._FrameOfReferenceUID = FrameOfReferenceUID; + + const volumeActors = []; + + // One actor per volume + for (let i = 0; i < volumeInputArray.length; i++) { + const { volumeId, actorUID, slabThickness } = volumeInputArray[i]; + + const actor = await createVolumeActor( + volumeInputArray[i], + this.element, + this.id, + suppressEvents + ); + + // We cannot use only volumeId since then we cannot have for instance more + // than one representation of the same volume (since actors would have the + // same name, and we don't allow that) AND We cannot use only any uid, since + // we rely on the volume in the cache for mapper. So we prefer actorUID if + // it is defined, otherwise we use volumeId for the actor name. + const uid = actorUID || volumeId; + volumeActors.push({ + uid, + actor, + slabThickness, + referenceId: volumeId, + }); + } + + this._setVolumeActors(volumeActors); + + triggerEvent(this.element, Events.VOLUME_VIEWPORT_NEW_VOLUME, { + viewportId: this.id, + volumeActors, + }); + + if (immediate) { + this.render(); + } + } + + /** + * Creates and adds volume actors for all volumes defined in the `volumeInputArray`. + * For each entry, if a `callback` is supplied, it will be called with the new volume actor as input. + * + * @param volumeInputArray - The array of `VolumeInput`s which define the volumes to add. + * @param immediate - Whether the `Viewport` should be rendered as soon as volumes are added. + */ + public async addVolumes( + volumeInputArray: Array, + immediate = false, + suppressEvents = false + ): Promise { + const firstImageVolume = cache.getVolume(volumeInputArray[0].volumeId); + + if (!firstImageVolume) { + throw new Error( + `imageVolume with id: ${firstImageVolume.volumeId} does not exist` + ); + } + + const volumeActors = []; + + await this._isValidVolumeInputArray( + volumeInputArray, + this._FrameOfReferenceUID + ); + + // One actor per volume + for (let i = 0; i < volumeInputArray.length; i++) { + const { volumeId, visibility, actorUID, slabThickness } = + volumeInputArray[i]; + + const actor = await createVolumeActor( + volumeInputArray[i], + this.element, + this.id, + suppressEvents + ); + + if (visibility === false) { + actor.setVisibility(false); + } + + // We cannot use only volumeId since then we cannot have for instance more + // than one representation of the same volume (since actors would have the + // same name, and we don't allow that) AND We cannot use only any uid, since + // we rely on the volume in the cache for mapper. So we prefer actorUID if + // it is defined, otherwise we use volumeId for the actor name. + const uid = actorUID || volumeId; + volumeActors.push({ + uid, + actor, + slabThickness, + // although the actor UID is defined, we need to use the volumeId for the + // referenceId, since the actor UID is used to reference the actor in the + // viewport, however, the actor is created from its volumeId + // and if later we need to grab the referenced volume from cache, + // we can use the referenceId to get the volume from the cache + referenceId: volumeId, + }); + } + + this.addActors(volumeActors); + + if (immediate) { + // render + this.render(); + } + } + + /** + * It removes the volume actor from the Viewport. If the volume actor is not in + * the viewport, it does nothing. + * @param actorUIDs - Array of actor UIDs to remove. In case of simple volume it will + * be the volume Id, but in case of Segmentation it will be `{volumeId}-{representationType}` + * since the same volume can be rendered in multiple representations. + * @param immediate - If true, the Viewport will be rendered immediately + */ + public removeVolumeActors(actorUIDs: Array, immediate = false): void { + // Todo: This is actually removeActors + this.removeActors(actorUIDs); + + if (immediate) { + this.render(); + } + } + + /** + * It sets the orientation for the camera, the orientation can be one of the + * following: axial, sagittal, coronal, default. Use the Enums.OrientationAxis + * to set the orientation. The "default" orientation is the orientation that + * the volume was acquired in (scan axis) + * + * @param orientation - The orientation to set the camera to. + * @param immediate - Whether the `Viewport` should be rendered as soon as the camera is set. + */ + public setOrientation(orientation: OrientationAxis, immediate = true): void { + console.warn('Method "setOrientation" needs implementation'); + } + + private async _isValidVolumeInputArray( + volumeInputArray: Array, + FrameOfReferenceUID: string + ): Promise { + const numVolumes = volumeInputArray.length; + + // Check all other volumes exist and have the same FrameOfReference + for (let i = 1; i < numVolumes; i++) { + const volumeInput = volumeInputArray[i]; + + const imageVolume = await loadVolume(volumeInput.volumeId); + + if (!imageVolume) { + throw new Error( + `imageVolume with id: ${imageVolume.volumeId} does not exist` + ); + } + + if (FrameOfReferenceUID !== imageVolume.metadata.FrameOfReferenceUID) { + throw new Error( + `Volumes being added to viewport ${this.id} do not share the same FrameOfReferenceUID. This is not yet supported` + ); + } + } + + return true; + } + + /** + * gets the visible bounds of the viewport in the world coordinate system + */ + public getBounds(): number[] { + const renderer = this.getRenderer(); + const bounds = renderer.computeVisiblePropBounds(); + return bounds; + } + + /** + * Flip the viewport along the desired axis + * @param flipDirection - FlipDirection + */ + public flip(flipDirection: FlipDirection): void { + super.flip(flipDirection); + } + + public getFrameOfReferenceUID = (): string => { + return this._FrameOfReferenceUID; + }; + + /** + * Checks if the viewport has a volume actor with the given volumeId + * @param volumeId - the volumeId to look for + * @returns Boolean indicating if the volume is present in the viewport + */ + public hasVolumeId(volumeId: string): boolean { + // Note: this assumes that the uid of the volume is the same as the volumeId + // which is not guaranteed to be the case for SEG. + const actorEntries = this.getActors(); + return actorEntries.some((actorEntry) => { + return actorEntry.uid === volumeId; + }); + } + + /** + * Returns the image and its properties that is being shown inside the + * stack viewport. It returns, the image dimensions, image direction, + * image scalar data, vtkImageData object, metadata, and scaling (e.g., PET suvbw) + * Note: since the volume viewport supports fusion, to get the + * image data for a specific volume, use the optional volumeId + * argument. + * + * @param volumeId - The volumeId of the volume to get the image for. + * @returns IImageData: {dimensions, direction, scalarData, vtkImageData, metadata, scaling} + */ + public getImageData(volumeId?: string): IImageData | undefined { + const defaultActor = this.getDefaultActor(); + if (!defaultActor) { + return; + } + + const { uid: defaultActorUID } = defaultActor; + volumeId = volumeId ?? defaultActorUID; + + const { actor } = this.getActor(volumeId); + + if (!actor.isA('vtkVolume')) { + return; + } + + const volume = cache.getVolume(volumeId); + + const vtkImageData = actor.getMapper().getInputData(); + return { + dimensions: vtkImageData.getDimensions(), + spacing: vtkImageData.getSpacing(), + origin: vtkImageData.getOrigin(), + direction: vtkImageData.getDirection(), + scalarData: vtkImageData.getPointData().getScalars().getData(), + imageData: actor.getMapper().getInputData(), + metadata: { + Modality: volume?.metadata?.Modality, + }, + scaling: volume?.scaling, + hasPixelSpacing: true, + }; + } + + /** + * Attaches the volume actors to the viewport. + * + * @param volumeActorEntries - The volume actors to add the viewport. + * + */ + private _setVolumeActors(volumeActorEntries: Array): void { + this.setActors(volumeActorEntries); + } + + /** + * canvasToWorld Returns the world coordinates of the given `canvasPos` + * projected onto the plane defined by the `Viewport`'s `vtkCamera`'s focal point + * and the direction of projection. + * + * @param canvasPos - The position in canvas coordinates. + * @returns The corresponding world coordinates. + * @public + */ + public canvasToWorld = (canvasPos: Point2): Point3 => { + const vtkCamera = this.getVtkActiveCamera() as vtkSlabCameraType; + + /** + * NOTE: this is necessary because we want the coordinate transformation + * respect to the view plane (plane orthogonal to the camera and passing to + * the focal point). + * + * When vtk.js computes the coordinate transformations, it simply uses the + * camera matrix (no ray casting). + * + * However for the volume viewport the clipping range is set to be + * (-RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE, RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE). + * The clipping range is used in the camera method getProjectionMatrix(). + * The projection matrix is used then for viewToWorld/worldToView methods of + * the renderer. This means that vkt.js will not return the coordinates of + * the point on the view plane (i.e. the depth coordinate will correspond + * to the focal point). + * + * Therefore the clipping range has to be set to (distance, distance + 0.01), + * where now distance is the distance between the camera position and focal + * point. This is done internally, in our camera customization when the flag + * isPerformingCoordinateTransformation is set to true. + */ + + vtkCamera.setIsPerformingCoordinateTransformation(true); + + const renderer = this.getRenderer(); + const offscreenMultiRenderWindow = + this.getRenderingEngine().offscreenMultiRenderWindow; + const openGLRenderWindow = + offscreenMultiRenderWindow.getOpenGLRenderWindow(); + const size = openGLRenderWindow.getSize(); + const devicePixelRatio = window.devicePixelRatio || 1; + const canvasPosWithDPR = [ + canvasPos[0] * devicePixelRatio, + canvasPos[1] * devicePixelRatio, + ]; + const displayCoord = [ + canvasPosWithDPR[0] + this.sx, + canvasPosWithDPR[1] + this.sy, + ]; + + // The y axis display coordinates are inverted with respect to canvas coords + displayCoord[1] = size[1] - displayCoord[1]; + + const worldCoord = openGLRenderWindow.displayToWorld( + displayCoord[0], + displayCoord[1], + 0, + renderer + ); + + vtkCamera.setIsPerformingCoordinateTransformation(false); + + return [worldCoord[0], worldCoord[1], worldCoord[2]]; + }; + + /** + * Returns the canvas coordinates of the given `worldPos` + * projected onto the `Viewport`'s `canvas`. + * + * @param worldPos - The position in world coordinates. + * @returns The corresponding canvas coordinates. + * @public + */ + public worldToCanvas = (worldPos: Point3): Point2 => { + const vtkCamera = this.getVtkActiveCamera() as vtkSlabCameraType; + + /** + * NOTE: this is necessary because we want the coordinate trasformation + * respect to the view plane (plane orthogonal to the camera and passing to + * the focal point). + * + * When vtk.js computes the coordinate transformations, it simply uses the + * camera matrix (no ray casting). + * + * However for the volume viewport the clipping range is set to be + * (-RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE, RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE). + * The clipping range is used in the camera method getProjectionMatrix(). + * The projection matrix is used then for viewToWorld/worldToView methods of + * the renderer. This means that vkt.js will not return the coordinates of + * the point on the view plane (i.e. the depth coordinate will corresponded + * to the focal point). + * + * Therefore the clipping range has to be set to (distance, distance + 0.01), + * where now distance is the distance between the camera position and focal + * point. This is done internally, in our camera customization when the flag + * isPerformingCoordinateTransformation is set to true. + */ + + vtkCamera.setIsPerformingCoordinateTransformation(true); + + const renderer = this.getRenderer(); + const offscreenMultiRenderWindow = + this.getRenderingEngine().offscreenMultiRenderWindow; + const openGLRenderWindow = + offscreenMultiRenderWindow.getOpenGLRenderWindow(); + const size = openGLRenderWindow.getSize(); + const displayCoord = openGLRenderWindow.worldToDisplay( + ...worldPos, + renderer + ); + + // The y axis display coordinates are inverted with respect to canvas coords + displayCoord[1] = size[1] - displayCoord[1]; + + const canvasCoord = [ + displayCoord[0] - this.sx, + displayCoord[1] - this.sy, + ]; + + const devicePixelRatio = window.devicePixelRatio || 1; + const canvasCoordWithDPR = [ + canvasCoord[0] / devicePixelRatio, + canvasCoord[1] / devicePixelRatio, + ]; + + vtkCamera.setIsPerformingCoordinateTransformation(false); + + return canvasCoordWithDPR; + }; + + /* + * Checking if the imageURI is in the volumes that are being + * rendered by the viewport. imageURI is the imageId without the schema + * for instance for the imageId of streaming-wadors:http://..., the http://... is the imageURI. + * Why we don't check the imageId is because the same image can be shown in + * another viewport (StackViewport) with a different schema + * + * @param imageURI - The imageURI to check + * @returns True if the imageURI is in the volumes that are being rendered by the viewport + */ + public hasImageURI = (imageURI: string): boolean => { + const volumeActors = this.getActors().filter(({ actor }) => + actor.isA('vtkVolume') + ); + + return volumeActors.some(({ uid }) => { + const volume = cache.getVolume(uid); + + if (!volume || !volume.imageIds) { + return false; + } + + const volumeImageURIs = volume.imageIds.map(imageIdToURI); + + return volumeImageURIs.includes(imageURI); + }); + }; + + /** + * Reset the camera for the volume viewport + */ + resetCamera( + resetPan?: boolean, + resetZoom?: boolean, + resetToCenter?: boolean + ): boolean { + return super.resetCamera(resetPan, resetZoom, resetToCenter); + } + + getCurrentImageIdIndex = (): number => { + throw new Error('Method not implemented.'); + }; + + getCurrentImageId = (): string => { + throw new Error('Method not implemented.'); + }; + + getIntensityFromWorld(point: Point3): number { + throw new Error('Method not implemented.'); + } + + setBlendMode( + blendMode: BlendModes, + filterActorUIDs?: string[], + immediate?: boolean + ): void { + throw new Error('Method not implemented.'); + } + + setSlabThickness(slabThickness: number, filterActorUIDs?: string[]): void { + throw new Error('Method not implemented.'); + } + + getSlabThickness(): number { + throw new Error('Method not implemented.'); + } +} + +export default BaseVolumeViewport; diff --git a/packages/core/src/RenderingEngine/RenderingEngine.ts b/packages/core/src/RenderingEngine/RenderingEngine.ts index 9d5661346e..c7d6975846 100644 --- a/packages/core/src/RenderingEngine/RenderingEngine.ts +++ b/packages/core/src/RenderingEngine/RenderingEngine.ts @@ -5,6 +5,7 @@ import { triggerEvent, uuidv4 } from '../utilities'; import { vtkOffscreenMultiRenderWindow } from './vtkClasses'; import ViewportType from '../enums/ViewportType'; import VolumeViewport from './VolumeViewport'; +import BaseVolumeViewport from './BaseVolumeViewport'; import StackViewport from './StackViewport'; import viewportTypeUsesCustomRenderingPipeline from './helpers/viewportTypeUsesCustomRenderingPipeline'; import getOrCreateCanvas from './helpers/getOrCreateCanvas'; @@ -380,8 +381,8 @@ class RenderingEngine implements IRenderingEngine { const isVolumeViewport = ( viewport: IStackViewport | IVolumeViewport - ): viewport is VolumeViewport => { - return viewport instanceof VolumeViewport; + ): viewport is BaseVolumeViewport => { + return viewport instanceof BaseVolumeViewport; }; return viewports.filter(isVolumeViewport); diff --git a/packages/core/src/RenderingEngine/VolumeViewport.ts b/packages/core/src/RenderingEngine/VolumeViewport.ts index 112f1dc737..bf79d98578 100644 --- a/packages/core/src/RenderingEngine/VolumeViewport.ts +++ b/packages/core/src/RenderingEngine/VolumeViewport.ts @@ -1,37 +1,19 @@ import { vec3 } from 'gl-matrix'; import vtkPlane from '@kitware/vtk.js/Common/DataModel/Plane'; -import vtkVolume from '@kitware/vtk.js/Rendering/Core/Volume'; import cache from '../cache'; -import ViewportType from '../enums/ViewportType'; -import Viewport from './Viewport'; -import { createVolumeActor } from './helpers'; -import volumeNewImageEventDispatcher, { - resetVolumeNewImageState, -} from './helpers/volumeNewImageEventDispatcher'; -import { loadVolume } from '../volumeLoader'; -import vtkSlabCamera from './vtkClasses/vtkSlabCamera'; -import { getShouldUseCPURendering } from '../init'; import transformWorldToIndex from '../utilities/transformWorldToIndex'; import type { - Point2, Point3, - IImageData, IVolumeInput, ActorEntry, IImageVolume, - FlipDirection, - VolumeViewportProperties, OrientationVectors, } from '../types'; import type { ViewportInput } from '../types/IViewport'; -import type IVolumeViewport from '../types/IVolumeViewport'; import { RENDERING_DEFAULTS, MPR_CAMERA_VALUES, EPSILON } from '../constants'; -import { Events, BlendModes, OrientationAxis } from '../enums'; -import eventTarget from '../eventTarget'; -import type { vtkSlabCamera as vtkSlabCameraType } from './vtkClasses/vtkSlabCamera'; -import { imageIdToURI, triggerEvent } from '../utilities'; -import { VoiModifiedEventDetail } from '../types/EventTypes'; +import { BlendModes, OrientationAxis } from '../enums'; +import BaseVolumeViewport from './BaseVolumeViewport'; /** * An object representing a VolumeViewport. VolumeViewports are used to render @@ -42,40 +24,11 @@ import { VoiModifiedEventDetail } from '../types/EventTypes'; * For setting volumes on viewports you need to use {@link addVolumesToViewports} * which will add volumes to the specified viewports. */ -class VolumeViewport extends Viewport implements IVolumeViewport { - useCPURendering = false; - private _FrameOfReferenceUID: string; +class VolumeViewport extends BaseVolumeViewport { private _useAcquisitionPlaneForViewPlane = false; - constructor(props: ViewportInput) { super(props); - this.useCPURendering = getShouldUseCPURendering(); - - if (this.useCPURendering) { - throw new Error( - 'VolumeViewports cannot be used whilst CPU Fallback Rendering is enabled.' - ); - } - - const renderer = this.getRenderer(); - - const camera = vtkSlabCamera.newInstance(); - renderer.setActiveCamera(camera); - - switch (this.type) { - case ViewportType.ORTHOGRAPHIC: - camera.setParallelProjection(true); - break; - case ViewportType.PERSPECTIVE: - camera.setParallelProjection(false); - break; - default: - throw new Error(`Unrecognized viewport type: ${this.type}`); - } - - this.initializeVolumeNewImageEventDispatcher(); - const { orientation } = this.options; // if the camera is set to be acquisition axis then we need to skip @@ -83,7 +36,7 @@ class VolumeViewport extends Viewport implements IVolumeViewport { if (orientation && orientation !== OrientationAxis.ACQUISITION) { const { viewPlaneNormal, viewUp } = this._getOrientationVectors(orientation); - + const camera = this.getVtkActiveCamera(); camera.setDirectionOfProjection( -viewPlaneNormal[0], -viewPlaneNormal[1], @@ -98,123 +51,6 @@ class VolumeViewport extends Viewport implements IVolumeViewport { this._useAcquisitionPlaneForViewPlane = true; } - static get useCustomRenderingPipeline(): boolean { - return false; - } - - private initializeVolumeNewImageEventDispatcher(): void { - const volumeNewImageHandlerBound = volumeNewImageHandler.bind(this); - const volumeNewImageCleanUpBound = volumeNewImageCleanUp.bind(this); - - function volumeNewImageHandler(cameraEvent) { - const { viewportId } = cameraEvent.detail; - - if (viewportId !== this.id || this.isDisabled) { - return; - } - - const viewportImageData = this.getImageData(); - - if (!viewportImageData) { - return; - } - - volumeNewImageEventDispatcher(cameraEvent); - } - - function volumeNewImageCleanUp(evt) { - const { viewportId } = evt.detail; - - if (viewportId !== this.id) { - return; - } - - this.element.removeEventListener( - Events.CAMERA_MODIFIED, - volumeNewImageHandlerBound - ); - - eventTarget.removeEventListener( - Events.ELEMENT_DISABLED, - volumeNewImageCleanUpBound - ); - - resetVolumeNewImageState(viewportId); - } - - this.element.removeEventListener( - Events.CAMERA_MODIFIED, - volumeNewImageHandlerBound - ); - this.element.addEventListener( - Events.CAMERA_MODIFIED, - volumeNewImageHandlerBound - ); - - eventTarget.addEventListener( - Events.ELEMENT_DISABLED, - volumeNewImageCleanUpBound - ); - } - - /** - * Sets the properties for the volume viewport on the volume - * (if fusion, it sets it for the first volume in the fusion) - * - * @param voiRange - Sets the lower and upper voi - * @param volumeId - The volume id to set the properties for (if undefined, the first volume) - * @param suppressEvents - If true, the viewport will not emit events - */ - public setProperties( - { voiRange }: VolumeViewportProperties = {}, - volumeId?: string, - suppressEvents = false - ): void { - if (volumeId !== undefined && !this.getActor(volumeId)) { - return; - } - - const actorEntries = this.getActors(); - - if (!actorEntries.length) { - return; - } - - let volumeActor; - - if (volumeId) { - const actorEntry = actorEntries.find((entry: ActorEntry) => { - return entry.uid === volumeId; - }); - - volumeActor = actorEntry?.actor as vtkVolume; - } - - // // set it for the first volume (if there are more than one - fusion) - if (!volumeActor) { - volumeActor = actorEntries[0].actor as vtkVolume; - volumeId = actorEntries[0].uid; - } - - if (!voiRange) { - return; - } - - // Todo: later when we have more properties, refactor the setVoiRange code below - const { lower, upper } = voiRange; - volumeActor.getProperty().getRGBTransferFunction(0).setRange(lower, upper); - - if (!suppressEvents) { - const eventDetail: VoiModifiedEventDetail = { - viewportId: this.id, - range: voiRange, - volumeId: volumeId, - }; - - triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail); - } - } - /** * Creates volume actors for all volumes defined in the `volumeInputArray`. * For each entry, if a `callback` is supplied, it will be called with the new volume actor as input. @@ -242,49 +78,7 @@ class VolumeViewport extends Viewport implements IVolumeViewport { this._useAcquisitionPlaneForViewPlane = false; } - const FrameOfReferenceUID = firstImageVolume.metadata.FrameOfReferenceUID; - - await this._isValidVolumeInputArray(volumeInputArray, FrameOfReferenceUID); - - this._FrameOfReferenceUID = FrameOfReferenceUID; - - const volumeActors = []; - - // One actor per volume - for (let i = 0; i < volumeInputArray.length; i++) { - const { volumeId, actorUID, slabThickness } = volumeInputArray[i]; - - const actor = await createVolumeActor( - volumeInputArray[i], - this.element, - this.id, - suppressEvents - ); - - // We cannot use only volumeId since then we cannot have for instance more - // than one representation of the same volume (since actors would have the - // same name, and we don't allow that) AND We cannot use only any uid, since - // we rely on the volume in the cache for mapper. So we prefer actorUID if - // it is defined, otherwise we use volumeId for the actor name. - const uid = actorUID || volumeId; - volumeActors.push({ - uid, - actor, - slabThickness, - referenceId: volumeId, - }); - } - - this._setVolumeActors(volumeActors); - - triggerEvent(this.element, Events.VOLUME_VIEWPORT_NEW_VOLUME, { - viewportId: this.id, - volumeActors, - }); - - if (immediate) { - this.render(); - } + return super.setVolumes(volumeInputArray, immediate, suppressEvents); } /** @@ -312,71 +106,7 @@ class VolumeViewport extends Viewport implements IVolumeViewport { this._useAcquisitionPlaneForViewPlane = false; } - const volumeActors = []; - - await this._isValidVolumeInputArray( - volumeInputArray, - this._FrameOfReferenceUID - ); - - // One actor per volume - for (let i = 0; i < volumeInputArray.length; i++) { - const { volumeId, visibility, actorUID, slabThickness } = - volumeInputArray[i]; - - const actor = await createVolumeActor( - volumeInputArray[i], - this.element, - this.id, - suppressEvents - ); - - if (visibility === false) { - actor.setVisibility(false); - } - - // We cannot use only volumeId since then we cannot have for instance more - // than one representation of the same volume (since actors would have the - // same name, and we don't allow that) AND We cannot use only any uid, since - // we rely on the volume in the cache for mapper. So we prefer actorUID if - // it is defined, otherwise we use volumeId for the actor name. - const uid = actorUID || volumeId; - volumeActors.push({ - uid, - actor, - slabThickness, - // although the actor UID is defined, we need to use the volumeId for the - // referenceId, since the actor UID is used to reference the actor in the - // viewport, however, the actor is created from its volumeId - // and if later we need to grab the referenced volume from cache, - // we can use the referenceId to get the volume from the cache - referenceId: volumeId, - }); - } - - this.addActors(volumeActors); - - if (immediate) { - // render - this.render(); - } - } - - /** - * It removes the volume actor from the Viewport. If the volume actor is not in - * the viewport, it does nothing. - * @param actorUIDs - Array of actor UIDs to remove. In case of simple volume it will - * be the volume Id, but in case of Segmentation it will be `{volumeId}-{representationType}` - * since the same volume can be rendered in multiple representations. - * @param immediate - If true, the Viewport will be rendered immediately - */ - public removeVolumeActors(actorUIDs: Array, immediate = false): void { - // Todo: This is actually removeActors - this.removeActors(actorUIDs); - - if (immediate) { - this.render(); - } + return super.addVolumes(volumeInputArray, immediate, suppressEvents); } /** @@ -486,34 +216,6 @@ class VolumeViewport extends Viewport implements IVolumeViewport { this.resetCamera(); } - private async _isValidVolumeInputArray( - volumeInputArray: Array, - FrameOfReferenceUID: string - ): Promise { - const numVolumes = volumeInputArray.length; - - // Check all other volumes exist and have the same FrameOfReference - for (let i = 1; i < numVolumes; i++) { - const volumeInput = volumeInputArray[i]; - - const imageVolume = await loadVolume(volumeInput.volumeId); - - if (!imageVolume) { - throw new Error( - `imageVolume with id: ${imageVolume.volumeId} does not exist` - ); - } - - if (FrameOfReferenceUID !== imageVolume.metadata.FrameOfReferenceUID) { - throw new Error( - `Volumes being added to viewport ${this.id} do not share the same FrameOfReferenceUID. This is not yet supported` - ); - } - } - - return true; - } - /** * Given a point in world coordinates, return the intensity at that point * @param point - The point in world coordinates to get the intensity @@ -541,21 +243,30 @@ class VolumeViewport extends Viewport implements IVolumeViewport { return volume.scalarData[voxelIndex]; } - /** - * gets the visible bounds of the viewport in the world coordinate system - */ - public getBounds(): number[] { - const renderer = this.getRenderer(); - const bounds = renderer.computeVisiblePropBounds(); - return bounds; - } + public setBlendMode( + blendMode: BlendModes, + filterActorUIDs = [], + immediate = false + ): void { + let actorEntries = this.getActors(); - /** - * Flip the viewport along the desired axis - * @param flipDirection - FlipDirection - */ - public flip(flipDirection: FlipDirection): void { - super.flip(flipDirection); + if (filterActorUIDs && filterActorUIDs.length > 0) { + actorEntries = actorEntries.filter((actorEntry: ActorEntry) => { + return filterActorUIDs.includes(actorEntry.uid); + }); + } + + actorEntries.forEach((actorEntry) => { + const { actor } = actorEntry; + + const mapper = actor.getMapper(); + // @ts-ignore vtk incorrect typing + mapper.setBlendMode(blendMode); + }); + + if (immediate) { + this.render(); + } } /** @@ -619,36 +330,6 @@ class VolumeViewport extends Viewport implements IVolumeViewport { return true; } - public getFrameOfReferenceUID = (): string => { - return this._FrameOfReferenceUID; - }; - - public setBlendMode( - blendMode: BlendModes, - filterActorUIDs = [], - immediate = false - ): void { - let actorEntries = this.getActors(); - - if (filterActorUIDs && filterActorUIDs.length > 0) { - actorEntries = actorEntries.filter((actorEntry: ActorEntry) => { - return filterActorUIDs.includes(actorEntry.uid); - }); - } - - actorEntries.forEach((actorEntry) => { - const { actor } = actorEntry; - - const mapper = actor.getMapper(); - // @ts-ignore vtk incorrect typing - mapper.setBlendMode(blendMode); - }); - - if (immediate) { - this.render(); - } - } - /** * It sets the slabThickness of the actors of the viewport. If filterActorUIDs are * provided, only the actors with the given UIDs will be affected. If no @@ -698,206 +379,6 @@ class VolumeViewport extends Viewport implements IVolumeViewport { return slabThickness; } - /** - * Checks if the viewport has a volume actor with the given volumeId - * @param volumeId - the volumeId to look for - * @returns Boolean indicating if the volume is present in the viewport - */ - public hasVolumeId(volumeId: string): boolean { - // Note: this assumes that the uid of the volume is the same as the volumeId - // which is not guaranteed to be the case for SEG. - const actorEntries = this.getActors(); - return actorEntries.some((actorEntry) => { - return actorEntry.uid === volumeId; - }); - } - - /** - * Returns the image and its properties that is being shown inside the - * stack viewport. It returns, the image dimensions, image direction, - * image scalar data, vtkImageData object, metadata, and scaling (e.g., PET suvbw) - * Note: since the volume viewport supports fusion, to get the - * image data for a specific volume, use the optional volumeId - * argument. - * - * @param volumeId - The volumeId of the volume to get the image for. - * @returns IImageData: {dimensions, direction, scalarData, vtkImageData, metadata, scaling} - */ - public getImageData(volumeId?: string): IImageData | undefined { - const defaultActor = this.getDefaultActor(); - if (!defaultActor) { - return; - } - - const { uid: defaultActorUID } = defaultActor; - volumeId = volumeId ?? defaultActorUID; - - const { actor } = this.getActor(volumeId); - - if (!actor.isA('vtkVolume')) { - return; - } - - const volume = cache.getVolume(volumeId); - - const vtkImageData = actor.getMapper().getInputData(); - return { - dimensions: vtkImageData.getDimensions(), - spacing: vtkImageData.getSpacing(), - origin: vtkImageData.getOrigin(), - direction: vtkImageData.getDirection(), - scalarData: vtkImageData.getPointData().getScalars().getData(), - imageData: actor.getMapper().getInputData(), - metadata: { - Modality: volume?.metadata?.Modality, - }, - scaling: volume?.scaling, - hasPixelSpacing: true, - }; - } - - /** - * Attaches the volume actors to the viewport. - * - * @param volumeActorEntries - The volume actors to add the viewport. - * - */ - private _setVolumeActors(volumeActorEntries: Array): void { - this.setActors(volumeActorEntries); - } - - /** - * canvasToWorld Returns the world coordinates of the given `canvasPos` - * projected onto the plane defined by the `Viewport`'s `vtkCamera`'s focal point - * and the direction of projection. - * - * @param canvasPos - The position in canvas coordinates. - * @returns The corresponding world coordinates. - * @public - */ - public canvasToWorld = (canvasPos: Point2): Point3 => { - const vtkCamera = this.getVtkActiveCamera() as vtkSlabCameraType; - - /** - * NOTE: this is necessary because we want the coordinate transformation - * respect to the view plane (plane orthogonal to the camera and passing to - * the focal point). - * - * When vtk.js computes the coordinate transformations, it simply uses the - * camera matrix (no ray casting). - * - * However for the volume viewport the clipping range is set to be - * (-RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE, RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE). - * The clipping range is used in the camera method getProjectionMatrix(). - * The projection matrix is used then for viewToWorld/worldToView methods of - * the renderer. This means that vkt.js will not return the coordinates of - * the point on the view plane (i.e. the depth coordinate will correspond - * to the focal point). - * - * Therefore the clipping range has to be set to (distance, distance + 0.01), - * where now distance is the distance between the camera position and focal - * point. This is done internally, in our camera customization when the flag - * isPerformingCoordinateTransformation is set to true. - */ - - vtkCamera.setIsPerformingCoordinateTransformation(true); - - const renderer = this.getRenderer(); - const offscreenMultiRenderWindow = - this.getRenderingEngine().offscreenMultiRenderWindow; - const openGLRenderWindow = - offscreenMultiRenderWindow.getOpenGLRenderWindow(); - const size = openGLRenderWindow.getSize(); - const devicePixelRatio = window.devicePixelRatio || 1; - const canvasPosWithDPR = [ - canvasPos[0] * devicePixelRatio, - canvasPos[1] * devicePixelRatio, - ]; - const displayCoord = [ - canvasPosWithDPR[0] + this.sx, - canvasPosWithDPR[1] + this.sy, - ]; - - // The y axis display coordinates are inverted with respect to canvas coords - displayCoord[1] = size[1] - displayCoord[1]; - - const worldCoord = openGLRenderWindow.displayToWorld( - displayCoord[0], - displayCoord[1], - 0, - renderer - ); - - vtkCamera.setIsPerformingCoordinateTransformation(false); - - return [worldCoord[0], worldCoord[1], worldCoord[2]]; - }; - - /** - * Returns the canvas coordinates of the given `worldPos` - * projected onto the `Viewport`'s `canvas`. - * - * @param worldPos - The position in world coordinates. - * @returns The corresponding canvas coordinates. - * @public - */ - public worldToCanvas = (worldPos: Point3): Point2 => { - const vtkCamera = this.getVtkActiveCamera() as vtkSlabCameraType; - - /** - * NOTE: this is necessary because we want the coordinate trasformation - * respect to the view plane (plane orthogonal to the camera and passing to - * the focal point). - * - * When vtk.js computes the coordinate transformations, it simply uses the - * camera matrix (no ray casting). - * - * However for the volume viewport the clipping range is set to be - * (-RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE, RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE). - * The clipping range is used in the camera method getProjectionMatrix(). - * The projection matrix is used then for viewToWorld/worldToView methods of - * the renderer. This means that vkt.js will not return the coordinates of - * the point on the view plane (i.e. the depth coordinate will corresponded - * to the focal point). - * - * Therefore the clipping range has to be set to (distance, distance + 0.01), - * where now distance is the distance between the camera position and focal - * point. This is done internally, in our camera customization when the flag - * isPerformingCoordinateTransformation is set to true. - */ - - vtkCamera.setIsPerformingCoordinateTransformation(true); - - const renderer = this.getRenderer(); - const offscreenMultiRenderWindow = - this.getRenderingEngine().offscreenMultiRenderWindow; - const openGLRenderWindow = - offscreenMultiRenderWindow.getOpenGLRenderWindow(); - const size = openGLRenderWindow.getSize(); - const displayCoord = openGLRenderWindow.worldToDisplay( - ...worldPos, - renderer - ); - - // The y axis display coordinates are inverted with respect to canvas coords - displayCoord[1] = size[1] - displayCoord[1]; - - const canvasCoord = [ - displayCoord[0] - this.sx, - displayCoord[1] - this.sy, - ]; - - const devicePixelRatio = window.devicePixelRatio || 1; - const canvasCoordWithDPR = [ - canvasCoord[0] / devicePixelRatio, - canvasCoord[1] / devicePixelRatio, - ]; - - vtkCamera.setIsPerformingCoordinateTransformation(false); - - return canvasCoordWithDPR; - }; - /** * Uses viewport camera and volume actor to decide if the viewport * is looking at the volume in the direction of acquisition (imageIds). @@ -910,34 +391,6 @@ class VolumeViewport extends Viewport implements IVolumeViewport { return this._getImageIdIndex(); }; - /* - * Checking if the imageURI is in the volumes that are being - * rendered by the viewport. imageURI is the imageId without the schema - * for instance for the imageId of streaming-wadors:http://..., the http://... is the imageURI. - * Why we don't check the imageId is because the same image can be shown in - * another viewport (StackViewport) with a different schema - * - * @param imageURI - The imageURI to check - * @returns True if the imageURI is in the volumes that are being rendered by the viewport - */ - public hasImageURI = (imageURI: string): boolean => { - const volumeActors = this.getActors().filter(({ actor }) => - actor.isA('vtkVolume') - ); - - return volumeActors.some(({ uid }) => { - const volume = cache.getVolume(uid); - - if (!volume || !volume.imageIds) { - return false; - } - - const volumeImageURIs = volume.imageIds.map(imageIdToURI); - - return volumeImageURIs.includes(imageURI); - }); - }; - /** * Uses viewport camera and volume actor to decide if the viewport * is looking at the volume in the direction of acquisition (imageIds). diff --git a/packages/core/src/RenderingEngine/helpers/addVolumesToViewports.ts b/packages/core/src/RenderingEngine/helpers/addVolumesToViewports.ts index 50660bb759..282d05d2fa 100644 --- a/packages/core/src/RenderingEngine/helpers/addVolumesToViewports.ts +++ b/packages/core/src/RenderingEngine/helpers/addVolumesToViewports.ts @@ -1,4 +1,5 @@ import { VolumeViewport } from '../'; +import BaseVolumeViewport from '../BaseVolumeViewport'; import type { IVolumeInput, IRenderingEngine } from '../../types'; /** @@ -28,10 +29,10 @@ async function addVolumesToViewports( throw new Error(`Viewport with Id ${viewportId} does not exist`); } - // if not instance of VolumeViewport, throw - if (!(viewport instanceof VolumeViewport)) { + // if not instance of BaseVolumeViewport, throw + if (!(viewport instanceof BaseVolumeViewport)) { console.warn( - `Viewport with Id ${viewportId} is not a VolumeViewport. Cannot add volume to this viewport.` + `Viewport with Id ${viewportId} is not a BaseVolumeViewport. Cannot add volume to this viewport.` ); return; diff --git a/packages/core/src/RenderingEngine/helpers/setVolumesForViewports.ts b/packages/core/src/RenderingEngine/helpers/setVolumesForViewports.ts index 1fa880f519..19fadd21d4 100644 --- a/packages/core/src/RenderingEngine/helpers/setVolumesForViewports.ts +++ b/packages/core/src/RenderingEngine/helpers/setVolumesForViewports.ts @@ -1,4 +1,4 @@ -import { VolumeViewport } from '../'; +import BaseVolumeViewport from '../BaseVolumeViewport'; import type { IVolumeInput, IRenderingEngine, @@ -32,9 +32,9 @@ async function setVolumesForViewports( throw new Error(`Viewport with Id ${viewportId} does not exist`); } - // if not instance of VolumeViewport, throw - if (!(viewport instanceof VolumeViewport)) { - throw new Error('setVolumesForViewports only supports VolumeViewport'); + // if not instance of BaseVolumeViewport, throw + if (!(viewport instanceof BaseVolumeViewport)) { + throw new Error('setVolumesForViewports only supports VolumeViewport and VolumeViewport3D'); } }); diff --git a/packages/core/src/RenderingEngine/helpers/volumeNewImageEventDispatcher.ts b/packages/core/src/RenderingEngine/helpers/volumeNewImageEventDispatcher.ts index 9ab6244b93..1ba348170a 100644 --- a/packages/core/src/RenderingEngine/helpers/volumeNewImageEventDispatcher.ts +++ b/packages/core/src/RenderingEngine/helpers/volumeNewImageEventDispatcher.ts @@ -5,7 +5,7 @@ import { import { EventTypes } from '../../types'; import { Events } from '../../enums'; import { getRenderingEngine } from '../getRenderingEngine'; -import VolumeViewport from '../VolumeViewport'; +import BaseVolumeViewport from '../BaseVolumeViewport'; // Keeping track of previous imageIndex for each viewportId type VolumeImageState = Record; @@ -35,9 +35,9 @@ function volumeNewImageEventDispatcher( const renderingEngine = getRenderingEngine(renderingEngineId); const viewport = renderingEngine.getViewport(viewportId); - if (!(viewport instanceof VolumeViewport)) { + if (!(viewport instanceof BaseVolumeViewport)) { throw new Error( - `volumeNewImageEventDispatcher: viewport is not a VolumeViewport` + `volumeNewImageEventDispatcher: viewport is not a BaseVolumeViewport` ); } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index a15c2d0cde..304b31cf9e 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -9,6 +9,7 @@ import { } from './RenderingEngine'; import RenderingEngine from './RenderingEngine'; import VolumeViewport from './RenderingEngine/VolumeViewport'; +import BaseVolumeViewport from './RenderingEngine/BaseVolumeViewport'; import StackViewport from './RenderingEngine/StackViewport'; import Viewport from './RenderingEngine/Viewport'; import eventTarget from './eventTarget'; @@ -62,6 +63,7 @@ export { // Settings, // Rendering Engine + BaseVolumeViewport, VolumeViewport, Viewport, StackViewport, diff --git a/packages/tools/src/utilities/segmentation/createLabelmapVolumeForViewport.ts b/packages/tools/src/utilities/segmentation/createLabelmapVolumeForViewport.ts index 3460e17d3b..e30fa54dc8 100644 --- a/packages/tools/src/utilities/segmentation/createLabelmapVolumeForViewport.ts +++ b/packages/tools/src/utilities/segmentation/createLabelmapVolumeForViewport.ts @@ -45,7 +45,7 @@ export default async function createLabelmapVolumeForViewport(input: { const { viewport } = enabledElement; if (!(viewport instanceof VolumeViewport)) { - throw new Error('Segmentation not ready for stackViewport'); + throw new Error('Segmentation only supports VolumeViewport'); } const { uid } = viewport.getDefaultActor(); diff --git a/packages/tools/src/utilities/viewport/isViewportPreScaled.ts b/packages/tools/src/utilities/viewport/isViewportPreScaled.ts index c46e707462..880e28f4ef 100644 --- a/packages/tools/src/utilities/viewport/isViewportPreScaled.ts +++ b/packages/tools/src/utilities/viewport/isViewportPreScaled.ts @@ -2,14 +2,14 @@ import { cache, StackViewport, Types, - VolumeViewport, + BaseVolumeViewport, } from '@cornerstonejs/core'; function isViewportPreScaled( viewport: Types.IStackViewport | Types.IVolumeViewport, targetId: string ): boolean { - if (viewport instanceof VolumeViewport) { + if (viewport instanceof BaseVolumeViewport) { const volumeId = targetId.split('volumeId:')[1]; const volume = cache.getVolume(volumeId); return volume.scaling && Object.keys(volume.scaling).length > 0; From 6270d4b932370f78f285836ec009a466156f0d61 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 8 Dec 2022 00:18:32 +0000 Subject: [PATCH 2/7] Add viewport presets --- common/reviews/api/core.api.md | 31 +- .../api/streaming-image-volume-loader.api.md | 24 ++ common/reviews/api/tools.api.md | 24 ++ packages/core/src/constants/index.ts | 9 +- .../core/src/constants/viewportPresets.ts | 357 ++++++++++++++++++ packages/core/src/types/ViewportPreset.ts | 14 + packages/core/src/types/index.ts | 2 + 7 files changed, 459 insertions(+), 2 deletions(-) create mode 100644 packages/core/src/constants/viewportPresets.ts create mode 100644 packages/core/src/types/ViewportPreset.ts diff --git a/common/reviews/api/core.api.md b/common/reviews/api/core.api.md index 62de40822f..5b60165613 100644 --- a/common/reviews/api/core.api.md +++ b/common/reviews/api/core.api.md @@ -138,7 +138,8 @@ declare namespace CONSTANTS { colormapsData as CPU_COLORMAPS, RENDERING_DEFAULTS, mprCameraValues as MPR_CAMERA_VALUES, - EPSILON + EPSILON, + presets as VIEWPORT_PRESETS } } export { CONSTANTS } @@ -1599,6 +1600,9 @@ type Point3 = [number, number, number]; // @public (undocumented) type Point4 = [number, number, number, number]; +// @public (undocumented) +const presets: ViewportPreset[]; + // @public (undocumented) type PreStackNewImageEvent = CustomEvent_2; @@ -1957,6 +1961,7 @@ declare namespace Types { IVolumeLoadObject, IVolumeInput, VolumeInputCallback, + ViewportPreset, Metadata, OrientationVectors, Point2, @@ -2175,6 +2180,30 @@ type ViewportInputOptions = { suppressEvents?: boolean; }; +// @public (undocumented) +interface ViewportPreset { + // (undocumented) + ambient: string; + // (undocumented) + colorTransfer: string; + // (undocumented) + diffuse: string; + // (undocumented) + gradientOpacity: string; + // (undocumented) + interpolation: string; + // (undocumented) + name: string; + // (undocumented) + scalarOpacity: string; + // (undocumented) + shade: string; + // (undocumented) + specular: string; + // (undocumented) + specularPower: string; +} + // @public (undocumented) enum ViewportType { // (undocumented) diff --git a/common/reviews/api/streaming-image-volume-loader.api.md b/common/reviews/api/streaming-image-volume-loader.api.md index 49f733f34a..3341ac6d8e 100644 --- a/common/reviews/api/streaming-image-volume-loader.api.md +++ b/common/reviews/api/streaming-image-volume-loader.api.md @@ -1250,6 +1250,30 @@ type ViewportInputOptions = { suppressEvents?: boolean; }; +// @public (undocumented) +interface ViewportPreset { + // (undocumented) + ambient: string; + // (undocumented) + colorTransfer: string; + // (undocumented) + diffuse: string; + // (undocumented) + gradientOpacity: string; + // (undocumented) + interpolation: string; + // (undocumented) + name: string; + // (undocumented) + scalarOpacity: string; + // (undocumented) + shade: string; + // (undocumented) + specular: string; + // (undocumented) + specularPower: string; +} + // @public enum ViewportType { ORTHOGRAPHIC = 'orthographic', diff --git a/common/reviews/api/tools.api.md b/common/reviews/api/tools.api.md index e5069137cf..43d7887d4f 100644 --- a/common/reviews/api/tools.api.md +++ b/common/reviews/api/tools.api.md @@ -4606,6 +4606,30 @@ type ViewportInputOptions = { suppressEvents?: boolean; }; +// @public (undocumented) +interface ViewportPreset { + // (undocumented) + ambient: string; + // (undocumented) + colorTransfer: string; + // (undocumented) + diffuse: string; + // (undocumented) + gradientOpacity: string; + // (undocumented) + interpolation: string; + // (undocumented) + name: string; + // (undocumented) + scalarOpacity: string; + // (undocumented) + shade: string; + // (undocumented) + specular: string; + // (undocumented) + specularPower: string; +} + declare namespace visibility { export { setAnnotationVisibility, diff --git a/packages/core/src/constants/index.ts b/packages/core/src/constants/index.ts index 7e8b1e23c9..400ffbdfcf 100644 --- a/packages/core/src/constants/index.ts +++ b/packages/core/src/constants/index.ts @@ -2,5 +2,12 @@ import CPU_COLORMAPS from './cpuColormaps'; import RENDERING_DEFAULTS from './rendering'; import EPSILON from './epsilon'; import MPR_CAMERA_VALUES from './mprCameraValues'; +import VIEWPORT_PRESETS from './viewportPresets'; -export { CPU_COLORMAPS, RENDERING_DEFAULTS, MPR_CAMERA_VALUES, EPSILON }; +export { + CPU_COLORMAPS, + RENDERING_DEFAULTS, + MPR_CAMERA_VALUES, + EPSILON, + VIEWPORT_PRESETS, +}; diff --git a/packages/core/src/constants/viewportPresets.ts b/packages/core/src/constants/viewportPresets.ts new file mode 100644 index 0000000000..2c915b46f1 --- /dev/null +++ b/packages/core/src/constants/viewportPresets.ts @@ -0,0 +1,357 @@ +import { ViewportPreset } from '../types'; + +const presets: ViewportPreset[] = [ + { + name: 'CT-AAA', + gradientOpacity: '4 0 1 255 1', + specularPower: '10', + scalarOpacity: + '12 -3024 0 143.556 0 166.222 0.686275 214.389 0.696078 419.736 0.833333 3071 0.803922', + specular: '0.2', + shade: '1', + ambient: '0.1', + colorTransfer: + '24 -3024 0 0 0 143.556 0.615686 0.356863 0.184314 166.222 0.882353 0.603922 0.290196 214.389 1 1 1 419.736 1 0.937033 0.954531 3071 0.827451 0.658824 1', + diffuse: '0.9', + interpolation: '1', + }, + { + name: 'CT-AAA2', + gradientOpacity: '4 0 1 255 1', + specularPower: '10', + scalarOpacity: + '16 -3024 0 129.542 0 145.244 0.166667 157.02 0.5 169.918 0.627451 395.575 0.8125 1578.73 0.8125 3071 0.8125', + specular: '0.2', + shade: '1', + ambient: '0.1', + colorTransfer: + '32 -3024 0 0 0 129.542 0.54902 0.25098 0.14902 145.244 0.6 0.627451 0.843137 157.02 0.890196 0.47451 0.6 169.918 0.992157 0.870588 0.392157 395.575 1 0.886275 0.658824 1578.73 1 0.829256 0.957922 3071 0.827451 0.658824 1', + diffuse: '0.9', + interpolation: '1', + }, + { + name: 'CT-Bone', + gradientOpacity: '4 0 1 255 1', + specularPower: '10', + scalarOpacity: '8 -3024 0 -16.4458 0 641.385 0.715686 3071 0.705882', + specular: '0.2', + shade: '1', + ambient: '0.1', + colorTransfer: + '16 -3024 0 0 0 -16.4458 0.729412 0.254902 0.301961 641.385 0.905882 0.815686 0.552941 3071 1 1 1', + diffuse: '0.9', + interpolation: '1', + }, + { + name: 'CT-Bones', + gradientOpacity: '4 0 1 985.12 1', + specularPower: '1', + scalarOpacity: '8 -1000 0 152.19 0 278.93 0.190476 952 0.2', + specular: '0', + shade: '1', + ambient: '0.2', + colorTransfer: + '20 -1000 0.3 0.3 1 -488 0.3 1 0.3 463.28 1 0 0 659.15 1 0.912535 0.0374849 953 1 0.3 0.3', + diffuse: '1', + interpolation: '1', + }, + { + name: 'CT-Cardiac', + gradientOpacity: '4 0 1 255 1', + specularPower: '10', + scalarOpacity: + '12 -3024 0 -77.6875 0 94.9518 0.285714 179.052 0.553571 260.439 0.848214 3071 0.875', + specular: '0.2', + shade: '1', + ambient: '0.1', + colorTransfer: + '24 -3024 0 0 0 -77.6875 0.54902 0.25098 0.14902 94.9518 0.882353 0.603922 0.290196 179.052 1 0.937033 0.954531 260.439 0.615686 0 0 3071 0.827451 0.658824 1', + diffuse: '0.9', + interpolation: '1', + }, + { + name: 'CT-Cardiac2', + gradientOpacity: '4 0 1 255 1', + specularPower: '10', + scalarOpacity: + '12 -3024 0 42.8964 0 163.488 0.428571 277.642 0.776786 1587 0.754902 3071 0.754902', + specular: '0.2', + shade: '1', + ambient: '0.1', + colorTransfer: + '24 -3024 0 0 0 42.8964 0.54902 0.25098 0.14902 163.488 0.917647 0.639216 0.0588235 277.642 1 0.878431 0.623529 1587 1 1 1 3071 0.827451 0.658824 1', + diffuse: '0.9', + interpolation: '1', + }, + { + name: 'CT-Cardiac3', + gradientOpacity: '4 0 1 255 1', + specularPower: '10', + scalarOpacity: + '14 -3024 0 -86.9767 0 45.3791 0.169643 139.919 0.589286 347.907 0.607143 1224.16 0.607143 3071 0.616071', + specular: '0.2', + shade: '1', + ambient: '0.1', + colorTransfer: + '28 -3024 0 0 0 -86.9767 0 0.25098 1 45.3791 1 0 0 139.919 1 0.894893 0.894893 347.907 1 1 0.25098 1224.16 1 1 1 3071 0.827451 0.658824 1', + diffuse: '0.9', + interpolation: '1', + }, + { + name: 'CT-Chest-Contrast-Enhanced', + gradientOpacity: '4 0 1 255 1', + specularPower: '10', + scalarOpacity: + '10 -3024 0 67.0106 0 251.105 0.446429 439.291 0.625 3071 0.616071', + specular: '0.2', + shade: '1', + ambient: '0.1', + colorTransfer: + '20 -3024 0 0 0 67.0106 0.54902 0.25098 0.14902 251.105 0.882353 0.603922 0.290196 439.291 1 0.937033 0.954531 3071 0.827451 0.658824 1', + diffuse: '0.9', + interpolation: '1', + }, + { + name: 'CT-Chest-Vessels', + gradientOpacity: '4 0 1 255 1', + specularPower: '1', + scalarOpacity: + '10 -3024 0 -1278.35 0 22.8277 0.428571 439.291 0.625 3071 0.616071', + specular: '0', + shade: '1', + ambient: '0.2', + colorTransfer: + '20 -3024 0 0 0 -1278.35 0.54902 0.25098 0.14902 22.8277 0.882353 0.603922 0.290196 439.291 1 0.937033 0.954531 3071 0.827451 0.658824 1', + diffuse: '1', + interpolation: '1', + }, + { + name: 'CT-Coronary-Arteries', + gradientOpacity: '4 0 1 255 1', + specularPower: '1', + scalarOpacity: + '12 -2048 0 136.47 0 159.215 0.258929 318.43 0.571429 478.693 0.776786 3661 1', + specular: '0', + shade: '0', + ambient: '0.2', + colorTransfer: + '24 -2048 0 0 0 136.47 0 0 0 159.215 0.159804 0.159804 0.159804 318.43 0.764706 0.764706 0.764706 478.693 1 1 1 3661 1 1 1', + diffuse: '1', + interpolation: '1', + }, + { + name: 'CT-Coronary-Arteries-2', + gradientOpacity: '4 0 1 255 1', + specularPower: '1', + scalarOpacity: + '14 -2048 0 142.677 0 145.016 0.116071 192.174 0.5625 217.24 0.776786 384.347 0.830357 3661 0.830357', + specular: '0', + shade: '1', + ambient: '0.2', + colorTransfer: + '28 -2048 0 0 0 142.677 0 0 0 145.016 0.615686 0 0.0156863 192.174 0.909804 0.454902 0 217.24 0.972549 0.807843 0.611765 384.347 0.909804 0.909804 1 3661 1 1 1', + diffuse: '1', + interpolation: '1', + }, + { + name: 'CT-Coronary-Arteries-3', + gradientOpacity: '4 0 1 255 1', + specularPower: '10', + scalarOpacity: + '14 -2048 0 128.643 0 129.982 0.0982143 173.636 0.669643 255.884 0.857143 584.878 0.866071 3661 1', + specular: '0.2', + shade: '1', + ambient: '0.1', + colorTransfer: + '28 -2048 0 0 0 128.643 0 0 0 129.982 0.615686 0 0.0156863 173.636 0.909804 0.454902 0 255.884 0.886275 0.886275 0.886275 584.878 0.968627 0.968627 0.968627 3661 1 1 1', + diffuse: '0.9', + interpolation: '1', + }, + { + name: 'CT-Cropped-Volume-Bone', + gradientOpacity: '4 0 1 255 1', + specularPower: '1', + scalarOpacity: '10 -2048 0 -451 0 -450 1 1050 1 3661 1', + specular: '0', + shade: '0', + ambient: '0.2', + colorTransfer: + '20 -2048 0 0 0 -451 0 0 0 -450 0.0556356 0.0556356 0.0556356 1050 1 1 1 3661 1 1 1', + diffuse: '1', + interpolation: '1', + }, + { + name: 'CT-Fat', + gradientOpacity: '6 0 1 985.12 1 988 1', + specularPower: '1', + scalarOpacity: '14 -1000 0 -100 0 -99 0.15 -60 0.15 -59 0 101.2 0 952 0', + specular: '0', + shade: '0', + ambient: '0.2', + colorTransfer: + '36 -1000 0.3 0.3 1 -497.5 0.3 1 0.3 -99 0 0 1 -76.946 0 1 0 -65.481 0.835431 0.888889 0.0165387 83.89 1 0 0 463.28 1 0 0 659.15 1 0.912535 0.0374849 2952 1 0.300267 0.299886', + diffuse: '1', + interpolation: '1', + }, + { + name: 'CT-Liver-Vasculature', + gradientOpacity: '4 0 1 255 1', + specularPower: '1', + scalarOpacity: + '14 -2048 0 149.113 0 157.884 0.482143 339.96 0.660714 388.526 0.830357 1197.95 0.839286 3661 0.848214', + specular: '0', + shade: '0', + ambient: '0.2', + colorTransfer: + '28 -2048 0 0 0 149.113 0 0 0 157.884 0.501961 0.25098 0 339.96 0.695386 0.59603 0.36886 388.526 0.854902 0.85098 0.827451 1197.95 1 1 1 3661 1 1 1', + diffuse: '1', + interpolation: '1', + }, + { + name: 'CT-Lung', + gradientOpacity: '6 0 1 985.12 1 988 1', + specularPower: '1', + scalarOpacity: '12 -1000 0 -600 0 -599 0.15 -400 0.15 -399 0 2952 0', + specular: '0', + shade: '1', + ambient: '0.2', + colorTransfer: + '24 -1000 0.3 0.3 1 -600 0 0 1 -530 0.134704 0.781726 0.0724558 -460 0.929244 1 0.109473 -400 0.888889 0.254949 0.0240258 2952 1 0.3 0.3', + diffuse: '1', + interpolation: '1', + }, + { + name: 'CT-MIP', + gradientOpacity: '4 0 1 255 1', + specularPower: '10', + scalarOpacity: '8 -3024 0 -637.62 0 700 1 3071 1', + specular: '0.2', + shade: '1', + ambient: '0.1', + colorTransfer: '16 -3024 0 0 0 -637.62 1 1 1 700 1 1 1 3071 1 1 1', + diffuse: '0.9', + interpolation: '1', + }, + { + name: 'CT-Muscle', + gradientOpacity: '4 0 1 255 1', + specularPower: '10', + scalarOpacity: + '10 -3024 0 -155.407 0 217.641 0.676471 419.736 0.833333 3071 0.803922', + specular: '0.2', + shade: '1', + ambient: '0.1', + colorTransfer: + '20 -3024 0 0 0 -155.407 0.54902 0.25098 0.14902 217.641 0.882353 0.603922 0.290196 419.736 1 0.937033 0.954531 3071 0.827451 0.658824 1', + diffuse: '0.9', + interpolation: '1', + }, + { + name: 'CT-Pulmonary-Arteries', + gradientOpacity: '4 0 1 255 1', + specularPower: '1', + scalarOpacity: + '14 -2048 0 -568.625 0 -364.081 0.0714286 -244.813 0.401786 18.2775 0.607143 447.798 0.830357 3592.73 0.839286', + specular: '0', + shade: '1', + ambient: '0.2', + colorTransfer: + '28 -2048 0 0 0 -568.625 0 0 0 -364.081 0.396078 0.301961 0.180392 -244.813 0.611765 0.352941 0.0705882 18.2775 0.843137 0.0156863 0.156863 447.798 0.752941 0.752941 0.752941 3592.73 1 1 1', + diffuse: '1', + interpolation: '1', + }, + { + name: 'CT-Soft-Tissue', + gradientOpacity: '4 0 1 255 1', + specularPower: '1', + scalarOpacity: '10 -2048 0 -167.01 0 -160 1 240 1 3661 1', + specular: '0', + shade: '0', + ambient: '0.2', + colorTransfer: + '20 -2048 0 0 0 -167.01 0 0 0 -160 0.0556356 0.0556356 0.0556356 240 1 1 1 3661 1 1 1', + diffuse: '1', + interpolation: '1', + }, + { + name: 'CT-Air', + gradientOpacity: '4 0 1 255 1', + specularPower: '10', + scalarOpacity: '8 -3024 0.705882 -900.0 0.715686 -500.0 0 3071 0', + specular: '0.2', + shade: '1', + ambient: '0.1', + colorTransfer: + '16 -3024 1 1 1 -900.0 0.2 1.0 1.0 -500.0 0.3 0.3 1.0 3071 0 0 0 ', + diffuse: '0.9', + interpolation: '1', + }, + { + name: 'MR-Angio', + gradientOpacity: '4 0 1 255 1', + specularPower: '1', + scalarOpacity: + '12 -2048 0 151.354 0 158.279 0.4375 190.112 0.580357 200.873 0.732143 3661 0.741071', + specular: '0', + shade: '1', + ambient: '0.2', + colorTransfer: + '24 -2048 0 0 0 151.354 0 0 0 158.279 0.74902 0.376471 0 190.112 1 0.866667 0.733333 200.873 0.937255 0.937255 0.937255 3661 1 1 1', + diffuse: '1', + interpolation: '1', + }, + { + name: 'MR-Default', + gradientOpacity: '4 0 1 255 1', + specularPower: '1', + scalarOpacity: '12 0 0 20 0 40 0.15 120 0.3 220 0.375 1024 0.5', + specular: '0', + shade: '1', + ambient: '0.2', + colorTransfer: + '24 0 0 0 0 20 0.168627 0 0 40 0.403922 0.145098 0.0784314 120 0.780392 0.607843 0.380392 220 0.847059 0.835294 0.788235 1024 1 1 1', + diffuse: '1', + interpolation: '1', + }, + { + name: 'MR-MIP', + gradientOpacity: '4 0 1 255 1', + specularPower: '1', + scalarOpacity: '8 0 0 98.3725 0 416.637 1 2800 1', + specular: '0', + shade: '0', + ambient: '0.2', + colorTransfer: '16 0 1 1 1 98.3725 1 1 1 416.637 1 1 1 2800 1 1 1', + diffuse: '1', + interpolation: '1', + }, + { + name: 'MR-T2-Brain', + gradientOpacity: '4 0 1 160.25 1', + specularPower: '40', + scalarOpacity: '10 0 0 36.05 0 218.302 0.171429 412.406 1 641 1', + specular: '0.5', + shade: '1', + ambient: '0.3', + colorTransfer: + '16 0 0 0 0 98.7223 0.956863 0.839216 0.192157 412.406 0 0.592157 0.807843 641 1 1 1', + diffuse: '0.6', + interpolation: '1', + }, + { + name: 'DTI-FA-Brain', + gradientOpacity: '4 0 1 0.9950 1', + specularPower: '40', + scalarOpacity: + '16 0 0 0 0 0.3501 0.0158 0.49379 0.7619 0.6419 1 0.9920 1 0.9950 0 0.9950 0', + specular: '0.5', + shade: '1', + ambient: '0.3', + colorTransfer: + '28 0 1 0 0 0 1 0 0 0.24974 0.4941 1 0 0.49949 0 0.9882 1 0.7492 0.51764 0 1 0.9950 1 0 0 0.9950 1 0 0', + diffuse: '0.9', + interpolation: '1', + }, +]; + +export default presets; diff --git a/packages/core/src/types/ViewportPreset.ts b/packages/core/src/types/ViewportPreset.ts new file mode 100644 index 0000000000..485f30cec4 --- /dev/null +++ b/packages/core/src/types/ViewportPreset.ts @@ -0,0 +1,14 @@ +interface ViewportPreset { + name: string; + gradientOpacity: string; + specularPower: string; + scalarOpacity: string; + specular: string; + shade: string; + ambient: string; + colorTransfer: string; + diffuse: string; + interpolation: string; +} + +export default ViewportPreset; diff --git a/packages/core/src/types/index.ts b/packages/core/src/types/index.ts index 8a62d280ac..a2923cab1c 100644 --- a/packages/core/src/types/index.ts +++ b/packages/core/src/types/index.ts @@ -40,6 +40,7 @@ import type ICachedImage from './ICachedImage'; import type ICachedVolume from './ICachedVolume'; import type IStackViewport from './IStackViewport'; import type IVolumeViewport from './IVolumeViewport'; +import type ViewportPreset from './ViewportPreset'; // CPU types import type CPUFallbackEnabledElement from './CPUFallbackEnabledElement'; @@ -93,6 +94,7 @@ export type { IVolumeLoadObject, IVolumeInput, VolumeInputCallback, + ViewportPreset, // Metadata, OrientationVectors, From 9e0db3136d2e8a3afea6fffe9e36b955800d09bd Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 8 Dec 2022 00:22:07 +0000 Subject: [PATCH 3/7] Add utility function for applying preset to volume actor --- common/reviews/api/core.api.md | 6 +- packages/core/src/utilities/applyPreset.ts | 132 +++++++++++++++++++++ packages/core/src/utilities/index.ts | 2 + 3 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 packages/core/src/utilities/applyPreset.ts diff --git a/common/reviews/api/core.api.md b/common/reviews/api/core.api.md index 5b60165613..22ed360d4a 100644 --- a/common/reviews/api/core.api.md +++ b/common/reviews/api/core.api.md @@ -41,6 +41,9 @@ function addProvider(provider: (type: string, query: any) => any, priority?: num // @public (undocumented) export function addVolumesToViewports(renderingEngine: IRenderingEngine, volumeInputs: Array, viewportIds: Array, immediateRender?: boolean, suppressEvents?: boolean): Promise; +// @public (undocumented) +function applyPreset(actor: VolumeActor, preset: ViewportPreset): void; + // @public (undocumented) export abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport { constructor(props: ViewportInput); @@ -2033,7 +2036,8 @@ declare namespace utilities { calculateViewportsSpatialRegistration, spatialRegistrationMetadataProvider, getViewportImageCornersInWorld, - hasNaNValues + hasNaNValues, + applyPreset } } export { utilities } diff --git a/packages/core/src/utilities/applyPreset.ts b/packages/core/src/utilities/applyPreset.ts new file mode 100644 index 0000000000..e813579c4c --- /dev/null +++ b/packages/core/src/utilities/applyPreset.ts @@ -0,0 +1,132 @@ +import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction'; +import vtkPiecewiseFunction from '@kitware/vtk.js/Common/DataModel/PiecewiseFunction'; +import { ViewportPreset } from '../types'; +import { VolumeActor } from '../types/IActor'; + +/** + * Applies a preset to a volume actor. + * + * @param actor - The volume actor to apply the preset to. + * @param preset - The preset to apply. + */ +export default function applyPreset(actor: VolumeActor, preset: ViewportPreset) { + // Create color transfer function + const colorTransferArray = preset.colorTransfer + .split(' ') + .splice(1) + .map(parseFloat); + + const { shiftRange } = getShiftRange(colorTransferArray); + const min = shiftRange[0]; + const width = shiftRange[1] - shiftRange[0]; + const cfun = vtkColorTransferFunction.newInstance(); + const normColorTransferValuePoints = []; + for (let i = 0; i < colorTransferArray.length; i += 4) { + let value = colorTransferArray[i]; + const r = colorTransferArray[i + 1]; + const g = colorTransferArray[i + 2]; + const b = colorTransferArray[i + 3]; + + value = (value - min) / width; + normColorTransferValuePoints.push([value, r, g, b]); + } + + applyPointsToRGBFunction(normColorTransferValuePoints, shiftRange, cfun); + + actor.getProperty().setRGBTransferFunction(0, cfun); + + // Create scalar opacity function + const scalarOpacityArray = preset.scalarOpacity + .split(' ') + .splice(1) + .map(parseFloat); + + const ofun = vtkPiecewiseFunction.newInstance(); + const normPoints = []; + for (let i = 0; i < scalarOpacityArray.length; i += 2) { + let value = scalarOpacityArray[i]; + const opacity = scalarOpacityArray[i + 1]; + + value = (value - min) / width; + + normPoints.push([value, opacity]); + } + + applyPointsToPiecewiseFunction(normPoints, shiftRange, ofun); + + actor.getProperty().setScalarOpacity(0, ofun); + + const [ + gradientMinValue, + gradientMinOpacity, + gradientMaxValue, + gradientMaxOpacity, + ] = preset.gradientOpacity.split(' ').splice(1).map(parseFloat); + + actor.getProperty().setUseGradientOpacity(0, true); + actor.getProperty().setGradientOpacityMinimumValue(0, gradientMinValue); + actor.getProperty().setGradientOpacityMinimumOpacity(0, gradientMinOpacity); + actor.getProperty().setGradientOpacityMaximumValue(0, gradientMaxValue); + actor.getProperty().setGradientOpacityMaximumOpacity(0, gradientMaxOpacity); + + if (preset.interpolation === '1') { + actor.getProperty().setInterpolationTypeToFastLinear(); + //actor.getProperty().setInterpolationTypeToLinear() + } + + const ambient = parseFloat(preset.ambient); + const diffuse = parseFloat(preset.diffuse); + const specular = parseFloat(preset.specular); + const specularPower = parseFloat(preset.specularPower); + + actor.getProperty().setAmbient(ambient); + actor.getProperty().setDiffuse(diffuse); + actor.getProperty().setSpecular(specular); + actor.getProperty().setSpecularPower(specularPower); +} + +function getShiftRange(colorTransferArray) { + // Credit to paraview-glance + // https://github.com/Kitware/paraview-glance/blob/3fec8eeff31e9c19ad5b6bff8e7159bd745e2ba9/src/components/controls/ColorBy/script.js#L133 + + // shift range is original rgb/opacity range centered around 0 + let min = Infinity; + let max = -Infinity; + for (let i = 0; i < colorTransferArray.length; i += 4) { + min = Math.min(min, colorTransferArray[i]); + max = Math.max(max, colorTransferArray[i]); + } + + const center = (max - min) / 2; + + return { + shiftRange: [-center, center], + min, + max, + }; +} + +function applyPointsToRGBFunction(points, range, cfun) { + const width = range[1] - range[0]; + const rescaled = points.map(([x, r, g, b]) => [ + x * width + range[0], + r, + g, + b, + ]); + + cfun.removeAllPoints(); + rescaled.forEach(([x, r, g, b]) => cfun.addRGBPoint(x, r, g, b)); + + return rescaled; +} + +function applyPointsToPiecewiseFunction(points, range, pwf) { + const width = range[1] - range[0]; + const rescaled = points.map(([x, y]) => [x * width + range[0], y]); + + pwf.removeAllPoints(); + rescaled.forEach(([x, y]) => pwf.addPoint(x, y)); + + return rescaled; +} diff --git a/packages/core/src/utilities/index.ts b/packages/core/src/utilities/index.ts index 6ced41f4dd..20cbbc3bdc 100644 --- a/packages/core/src/utilities/index.ts +++ b/packages/core/src/utilities/index.ts @@ -32,6 +32,7 @@ import calculateViewportsSpatialRegistration from './calculateViewportsSpatialRe import spatialRegistrationMetadataProvider from './spatialRegistrationMetadataProvider'; import getViewportImageCornersInWorld from './getViewportImageCornersInWorld'; import hasNaNValues from './hasNaNValues'; +import applyPreset from './applyPreset'; // name spaces import * as planar from './planar'; @@ -74,4 +75,5 @@ export { spatialRegistrationMetadataProvider, getViewportImageCornersInWorld, hasNaNValues, + applyPreset, }; From cea93601dc3c6286c294b7eab292c545ae6f8e79 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 8 Dec 2022 00:24:53 +0000 Subject: [PATCH 4/7] Add new 3D volume viewport --- common/reviews/api/core.api.md | 4 ++- .../api/streaming-image-volume-loader.api.md | 2 ++ .../src/RenderingEngine/BaseVolumeViewport.ts | 3 ++ .../src/RenderingEngine/RenderingEngine.ts | 3 ++ .../src/RenderingEngine/VolumeViewport3D.ts | 36 +++++++++++++++++++ .../helpers/viewportTypeToViewportClass.ts | 2 ++ packages/core/src/RenderingEngine/index.ts | 2 ++ packages/core/src/enums/ViewportType.ts | 1 + 8 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 packages/core/src/RenderingEngine/VolumeViewport3D.ts diff --git a/common/reviews/api/core.api.md b/common/reviews/api/core.api.md index 22ed360d4a..dcd2ced819 100644 --- a/common/reviews/api/core.api.md +++ b/common/reviews/api/core.api.md @@ -2215,7 +2215,9 @@ enum ViewportType { // (undocumented) PERSPECTIVE = "perspective", // (undocumented) - STACK = "stack" + STACK = "stack", + // (undocumented) + VOLUME_3D = "volume3d" } // @public (undocumented) diff --git a/common/reviews/api/streaming-image-volume-loader.api.md b/common/reviews/api/streaming-image-volume-loader.api.md index 3341ac6d8e..6a0eaadce8 100644 --- a/common/reviews/api/streaming-image-volume-loader.api.md +++ b/common/reviews/api/streaming-image-volume-loader.api.md @@ -1279,6 +1279,8 @@ enum ViewportType { ORTHOGRAPHIC = 'orthographic', PERSPECTIVE = 'perspective', STACK = 'stack', + // (undocumented) + VOLUME_3D = 'volume3d', } // @public (undocumented) diff --git a/packages/core/src/RenderingEngine/BaseVolumeViewport.ts b/packages/core/src/RenderingEngine/BaseVolumeViewport.ts index 25a3590582..3506fbba04 100644 --- a/packages/core/src/RenderingEngine/BaseVolumeViewport.ts +++ b/packages/core/src/RenderingEngine/BaseVolumeViewport.ts @@ -60,6 +60,9 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport { case ViewportType.ORTHOGRAPHIC: camera.setParallelProjection(true); break; + case ViewportType.VOLUME_3D: + camera.setParallelProjection(true); + break; case ViewportType.PERSPECTIVE: camera.setParallelProjection(false); break; diff --git a/packages/core/src/RenderingEngine/RenderingEngine.ts b/packages/core/src/RenderingEngine/RenderingEngine.ts index c7d6975846..463d4391fd 100644 --- a/packages/core/src/RenderingEngine/RenderingEngine.ts +++ b/packages/core/src/RenderingEngine/RenderingEngine.ts @@ -21,6 +21,7 @@ import type { NormalizedViewportInput, } from '../types/IViewport'; import { OrientationAxis } from '../enums'; +import VolumeViewport3D from './VolumeViewport3D'; type ViewportDisplayCoords = { sxStartDisplayCoords: number; @@ -750,6 +751,8 @@ class RenderingEngine implements IRenderingEngine { ) { // 4.b Create a volume viewport viewport = new VolumeViewport(viewportInput); + } else if (type === ViewportType.VOLUME_3D) { + viewport = new VolumeViewport3D(viewportInput); } else { throw new Error(`Viewport Type ${type} is not supported`); } diff --git a/packages/core/src/RenderingEngine/VolumeViewport3D.ts b/packages/core/src/RenderingEngine/VolumeViewport3D.ts new file mode 100644 index 0000000000..5e350d2e6c --- /dev/null +++ b/packages/core/src/RenderingEngine/VolumeViewport3D.ts @@ -0,0 +1,36 @@ +import BaseVolumeViewport from './BaseVolumeViewport'; +import { RENDERING_DEFAULTS } from '../constants'; + +/** + * An object representing a 3-dimensional volume viewport. VolumeViewport3Ds are used to render + * 3D volumes in their entirety, and not just load a single slice at a time. + * + * For setting volumes on viewports you need to use {@link addVolumesToViewports} + * which will add volumes to the specified viewports. + */ +class VolumeViewport3D extends BaseVolumeViewport { + public resetCamera( + resetPan = true, + resetZoom = true, + resetToCenter = true + ): boolean { + super.resetCamera(resetPan, resetZoom, resetToCenter); + const activeCamera = this.getVtkActiveCamera(); + // Set large numbers to ensure everything is always rendered + if (activeCamera.getParallelProjection()) { + activeCamera.setClippingRange( + -RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE, + RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE + ); + } else { + activeCamera.setClippingRange( + RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS, + RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE + ); + } + + return; + } +} + +export default VolumeViewport3D; diff --git a/packages/core/src/RenderingEngine/helpers/viewportTypeToViewportClass.ts b/packages/core/src/RenderingEngine/helpers/viewportTypeToViewportClass.ts index f505190a0b..94d7881b23 100644 --- a/packages/core/src/RenderingEngine/helpers/viewportTypeToViewportClass.ts +++ b/packages/core/src/RenderingEngine/helpers/viewportTypeToViewportClass.ts @@ -2,11 +2,13 @@ import StackViewport from '../StackViewport'; import VolumeViewport from '../VolumeViewport'; import ViewportType from '../../enums/ViewportType'; +import VolumeViewport3D from '../VolumeViewport3D'; const viewportTypeToViewportClass = { [ViewportType.ORTHOGRAPHIC]: VolumeViewport, [ViewportType.PERSPECTIVE]: VolumeViewport, [ViewportType.STACK]: StackViewport, + [ViewportType.VOLUME_3D]: VolumeViewport3D, }; export default viewportTypeToViewportClass; diff --git a/packages/core/src/RenderingEngine/index.ts b/packages/core/src/RenderingEngine/index.ts index 2001352176..ede6d587ef 100644 --- a/packages/core/src/RenderingEngine/index.ts +++ b/packages/core/src/RenderingEngine/index.ts @@ -2,6 +2,7 @@ import RenderingEngine from './RenderingEngine'; import getRenderingEngine from './getRenderingEngine'; import VolumeViewport from './VolumeViewport'; import StackViewport from './StackViewport'; +import VolumeViewport3D from './VolumeViewport3D'; import { createVolumeActor, createVolumeMapper, @@ -12,6 +13,7 @@ export { getRenderingEngine, RenderingEngine, VolumeViewport, + VolumeViewport3D, createVolumeActor, createVolumeMapper, getOrCreateCanvas, diff --git a/packages/core/src/enums/ViewportType.ts b/packages/core/src/enums/ViewportType.ts index 893f8cebe1..791084ea3d 100644 --- a/packages/core/src/enums/ViewportType.ts +++ b/packages/core/src/enums/ViewportType.ts @@ -15,6 +15,7 @@ enum ViewportType { ORTHOGRAPHIC = 'orthographic', /** Perspective Viewport: Not Implemented yet */ PERSPECTIVE = 'perspective', + VOLUME_3D = 'volume3d', } export default ViewportType; From 7259e3b6113ea5e90b01bb7e0e7ddeaee4cf78b8 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 3 Nov 2022 17:27:59 +0000 Subject: [PATCH 5/7] Add example for VolumeViewport3D --- .../tools/examples/volumeViewport3D/index.ts | 159 ++++++++++++++++++ utils/ExampleRunner/example-info.json | 4 + 2 files changed, 163 insertions(+) create mode 100644 packages/tools/examples/volumeViewport3D/index.ts diff --git a/packages/tools/examples/volumeViewport3D/index.ts b/packages/tools/examples/volumeViewport3D/index.ts new file mode 100644 index 0000000000..6ad5e03b7c --- /dev/null +++ b/packages/tools/examples/volumeViewport3D/index.ts @@ -0,0 +1,159 @@ +import { + RenderingEngine, + Types, + Enums, + setVolumesForViewports, + volumeLoader, + utilities, + CONSTANTS, +} from '@cornerstonejs/core'; +import { + initDemo, + createImageIdsAndCacheMetaData, + setTitleAndDescription, +} from '../../../../utils/demo/helpers'; +import * as cornerstoneTools from '@cornerstonejs/tools'; +import { VolumeActor } from 'core/src/types'; + +// This is for debugging purposes +console.warn( + 'Click on index.ts to open source code for this example --------->' +); + +const { + ToolGroupManager, + TrackballRotateTool, + Enums: csToolsEnums, +} = cornerstoneTools; + +const { ViewportType } = Enums; +const { MouseBindings } = csToolsEnums; + +// Define a unique id for the volume +const volumeName = 'CT_VOLUME_ID'; // Id of the volume less loader prefix +const volumeLoaderScheme = 'cornerstoneStreamingImageVolume'; // Loader id which defines which volume loader to use +const volumeId = `${volumeLoaderScheme}:${volumeName}`; // VolumeId with loader id + volume id + +// ======== Set up page ======== // +setTitleAndDescription( + '3D Volume Rendering', + 'Here we demonstrate how to 3D render a volume.' +); + +const size = '500px'; +const content = document.getElementById('content'); +const viewportGrid = document.createElement('div'); + +viewportGrid.style.display = 'flex'; +viewportGrid.style.display = 'flex'; +viewportGrid.style.flexDirection = 'row'; + +const element1 = document.createElement('div'); +element1.oncontextmenu = () => false; + +element1.style.width = size; +element1.style.height = size; + +viewportGrid.appendChild(element1); + +content.appendChild(viewportGrid); + +const instructions = document.createElement('p'); +instructions.innerText = 'Click the image to rotate it.'; + +content.append(instructions); +// ============================= // + +/** + * Runs the demo + */ +async function run() { + // Init Cornerstone and related libraries + await initDemo(); + + const toolGroupId = 'TOOL_GROUP_ID'; + + // Add tools to Cornerstone3D + cornerstoneTools.addTool(TrackballRotateTool); + + // Define a tool group, which defines how mouse events map to tool commands for + // Any viewport using the group + const toolGroup = ToolGroupManager.createToolGroup(toolGroupId); + + // Add the tools to the tool group and specify which volume they are pointing at + toolGroup.addTool(TrackballRotateTool.toolName, { + configuration: { volumeId }, + }); + + // Set the initial state of the tools, here we set one tool active on left click. + // This means left click will draw that tool. + toolGroup.setToolActive(TrackballRotateTool.toolName, { + bindings: [ + { + mouseButton: MouseBindings.Primary, // Left Click + }, + ], + }); + + // Get Cornerstone imageIds and fetch metadata into RAM + const imageIds = await createImageIdsAndCacheMetaData({ + StudyInstanceUID: + '1.3.6.1.4.1.14519.5.2.1.7009.2403.334240657131972136850343327463', + SeriesInstanceUID: + '1.3.6.1.4.1.14519.5.2.1.7009.2403.226151125820845824875394858561', + wadoRsRoot: 'https://d3t6nz73ql33tx.cloudfront.net/dicomweb', + type: 'VOLUME', + }); + + // Instantiate a rendering engine + const renderingEngineId = 'myRenderingEngine'; + const renderingEngine = new RenderingEngine(renderingEngineId); + + // Create the viewports + const viewportIds = ['3D_VIEWPORT']; + + const viewportInputArray = [ + { + viewportId: viewportIds[0], + type: ViewportType.VOLUME_3D, + element: element1, + defaultOptions: { + orientation: Enums.OrientationAxis.SAGITTAL, + background: [0.2, 0, 0.2], + }, + }, + ]; + + renderingEngine.setViewports(viewportInputArray); + + // Set the tool group on the viewports + viewportIds.forEach((viewportId) => + toolGroup.addViewport(viewportId, renderingEngineId) + ); + + // Define a volume in memory + const volume = await volumeLoader.createAndCacheVolume(volumeId, { + imageIds, + }); + + // Set the volume to load + volume.load(); + + setVolumesForViewports(renderingEngine, [{ volumeId }], viewportIds).then( + () => { + viewportIds.forEach((viewportId) => { + const volumeActor = renderingEngine + .getViewport(viewportId) + .getDefaultActor().actor as VolumeActor; + + utilities.applyPreset( + volumeActor, + CONSTANTS.VIEWPORT_PRESETS.find((preset) => preset.name === 'CT-AAA') + ); + }); + } + ); + renderingEngine.render(); +} + +run(); diff --git a/utils/ExampleRunner/example-info.json b/utils/ExampleRunner/example-info.json index 551b5399b4..5b56155b00 100644 --- a/utils/ExampleRunner/example-info.json +++ b/utils/ExampleRunner/example-info.json @@ -166,6 +166,10 @@ "name": "Volume Viewport Orientation", "description": "Demonstrates you can switch between different orientation of a volume viewport" }, + "volumeViewport3D": { + "name": "3D Volume Rendering", + "description": "Here we demonstrate how to 3D render a volume." + }, "referenceCursors": { "name": "Referencing Cursors", "description": "Demonstrates how to synchronize the cursor between multiple viewports" From f039f346e31aacf36ddb200b2baaa3848af74464 Mon Sep 17 00:00:00 2001 From: Alireza Date: Thu, 8 Dec 2022 14:55:00 -0500 Subject: [PATCH 6/7] feat: add presets dropdown to demo --- .../examples/volumeViewport3D/index.ts | 68 +++++++++++++------ 1 file changed, 47 insertions(+), 21 deletions(-) rename packages/{tools => core}/examples/volumeViewport3D/index.ts (69%) diff --git a/packages/tools/examples/volumeViewport3D/index.ts b/packages/core/examples/volumeViewport3D/index.ts similarity index 69% rename from packages/tools/examples/volumeViewport3D/index.ts rename to packages/core/examples/volumeViewport3D/index.ts index 6ad5e03b7c..3bc39d5cf5 100644 --- a/packages/tools/examples/volumeViewport3D/index.ts +++ b/packages/core/examples/volumeViewport3D/index.ts @@ -11,6 +11,7 @@ import { initDemo, createImageIdsAndCacheMetaData, setTitleAndDescription, + addDropdownToToolbar, } from '../../../../utils/demo/helpers'; import * as cornerstoneTools from '@cornerstonejs/tools'; import { VolumeActor } from 'core/src/types'; @@ -30,9 +31,12 @@ const { ViewportType } = Enums; const { MouseBindings } = csToolsEnums; // Define a unique id for the volume +let renderingEngine; const volumeName = 'CT_VOLUME_ID'; // Id of the volume less loader prefix const volumeLoaderScheme = 'cornerstoneStreamingImageVolume'; // Loader id which defines which volume loader to use const volumeId = `${volumeLoaderScheme}:${volumeName}`; // VolumeId with loader id + volume id +const renderingEngineId = 'myRenderingEngine'; +const viewportId = '3D_VIEWPORT'; // ======== Set up page ======== // setTitleAndDescription( @@ -62,6 +66,26 @@ const instructions = document.createElement('p'); instructions.innerText = 'Click the image to rotate it.'; content.append(instructions); + +addDropdownToToolbar({ + options: { + values: CONSTANTS.VIEWPORT_PRESETS.map((preset) => preset.name), + defaultValue: 'CT-Bone', + }, + onSelectedValueChange: (presetName) => { + const volumeActor = renderingEngine + .getViewport(viewportId) + .getDefaultActor().actor as VolumeActor; + + utilities.applyPreset( + volumeActor, + CONSTANTS.VIEWPORT_PRESETS.find((preset) => preset.name === presetName) + ); + + renderingEngine.render(); + }, +}); + // ============================= // /** @@ -98,23 +122,21 @@ async function run() { // Get Cornerstone imageIds and fetch metadata into RAM const imageIds = await createImageIdsAndCacheMetaData({ StudyInstanceUID: - '1.3.6.1.4.1.14519.5.2.1.7009.2403.334240657131972136850343327463', + '1.3.6.1.4.1.14519.5.2.1.7009.2403.871108593056125491804754960339', SeriesInstanceUID: - '1.3.6.1.4.1.14519.5.2.1.7009.2403.226151125820845824875394858561', - wadoRsRoot: 'https://d3t6nz73ql33tx.cloudfront.net/dicomweb', + '1.3.6.1.4.1.14519.5.2.1.7009.2403.367700692008930469189923116409', + wadoRsRoot: 'https://domvja9iplmyu.cloudfront.net/dicomweb', type: 'VOLUME', }); // Instantiate a rendering engine - const renderingEngineId = 'myRenderingEngine'; - const renderingEngine = new RenderingEngine(renderingEngineId); + renderingEngine = new RenderingEngine(renderingEngineId); // Create the viewports - const viewportIds = ['3D_VIEWPORT']; const viewportInputArray = [ { - viewportId: viewportIds[0], + viewportId: viewportId, type: ViewportType.VOLUME_3D, element: element1, defaultOptions: { @@ -127,9 +149,7 @@ async function run() { renderingEngine.setViewports(viewportInputArray); // Set the tool group on the viewports - viewportIds.forEach((viewportId) => - toolGroup.addViewport(viewportId, renderingEngineId) - ); + toolGroup.addViewport(viewportId, renderingEngineId); // Define a volume in memory const volume = await volumeLoader.createAndCacheVolume(volumeId, { @@ -139,20 +159,26 @@ async function run() { // Set the volume to load volume.load(); - setVolumesForViewports(renderingEngine, [{ volumeId }], viewportIds).then( + setVolumesForViewports(renderingEngine, [{ volumeId }], [viewportId]).then( () => { - viewportIds.forEach((viewportId) => { - const volumeActor = renderingEngine - .getViewport(viewportId) - .getDefaultActor().actor as VolumeActor; - - utilities.applyPreset( - volumeActor, - CONSTANTS.VIEWPORT_PRESETS.find((preset) => preset.name === 'CT-AAA') - ); - }); + const volumeActor = renderingEngine + .getViewport(viewportId) + .getDefaultActor().actor as VolumeActor; + + utilities.applyPreset( + volumeActor, + CONSTANTS.VIEWPORT_PRESETS.find((preset) => preset.name === 'CT-Bone') + ); + + const renderer = viewport.getRenderer(); + renderer.getActiveCamera().elevation(-70); + viewport.setCamera({ parallelScale: 600 }); + + viewport.render(); } ); + + const viewport = renderingEngine.getViewport(viewportId); renderingEngine.render(); } From 7abc9e4aa11237f8acdc54117005b92c116123db Mon Sep 17 00:00:00 2001 From: Alireza Date: Thu, 8 Dec 2022 16:03:53 -0500 Subject: [PATCH 7/7] update example info json --- utils/ExampleRunner/example-info.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utils/ExampleRunner/example-info.json b/utils/ExampleRunner/example-info.json index 5b56155b00..78f86146f0 100644 --- a/utils/ExampleRunner/example-info.json +++ b/utils/ExampleRunner/example-info.json @@ -42,6 +42,10 @@ "name": "Volume Viewport API", "description": "Demonstrates how to interact with a Volume viewport (e.g. Set VOI Range, Change Camera Position / Orientation, Change Slab Thickness, Flip H/V, Rotate, Invert, Zoom/Pan, Reset)" }, + "volumeViewport3D": { + "name": "3D Volume Rendering", + "description": "Demonstrates how to 3D render a volume and apply a preset" + }, "volumeEvents": { "name": "Volume Viewport Events", "description": "Demonstrates the Events that are fired during interaction with a Volume Viewport" @@ -166,10 +170,6 @@ "name": "Volume Viewport Orientation", "description": "Demonstrates you can switch between different orientation of a volume viewport" }, - "volumeViewport3D": { - "name": "3D Volume Rendering", - "description": "Here we demonstrate how to 3D render a volume." - }, "referenceCursors": { "name": "Referencing Cursors", "description": "Demonstrates how to synchronize the cursor between multiple viewports"