UNPKG

@cornerstonejs/core

Version:
158 lines (157 loc) 5.38 kB
import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData.js'; import imageIdToURI from '../../utilities/imageIdToURI.js'; import VoxelManager from '../../utilities/VoxelManager.js'; import { vtkStreamingOpenGLTexture } from '../../RenderingEngine/vtkClasses/index.js'; import cache from '../cache.js'; export class ImageVolume { get numTimePoints() { return typeof this.numDimensionGroups === 'number' ? this.numDimensionGroups : 1; } constructor(props) { this._imageIdsIndexMap = new Map(); this._imageURIsIndexMap = new Map(); this.cornerstoneImageMetaData = null; this.isPreScaled = false; this.numFrames = null; const { imageIds, scaling, dimensions, spacing, origin, direction, dataType, volumeId, referencedVolumeId, metadata, referencedImageIds, additionalDetails, voxelManager, numberOfComponents, } = props; if (!dataType) { throw new Error('Data type is required, please provide a data type as string such as "Uint8Array", "Float32Array", etc.'); } let { imageData } = props; this.suppressWarnings = true; this.imageIds = imageIds; this.volumeId = volumeId; this.metadata = metadata; this.dimensions = dimensions; this.spacing = spacing; this.origin = origin; this.direction = direction; this.dataType = dataType; this.hasPixelSpacing = Number.isFinite(spacing[0]) && spacing[0] > 0 && Number.isFinite(spacing[1]) && spacing[1] > 0; this.vtkOpenGLTexture = vtkStreamingOpenGLTexture.newInstance(); this.vtkOpenGLTexture.setVolumeId(volumeId); this.voxelManager = voxelManager ?? VoxelManager.createImageVolumeVoxelManager({ dimensions, imageIds, numberOfComponents, id: volumeId, }); this.numVoxels = this.dimensions[0] * this.dimensions[1] * this.dimensions[2]; if (!imageData) { imageData = vtkImageData.newInstance(); imageData.setDimensions(dimensions); imageData.setSpacing(spacing); imageData.setDirection(direction); imageData.setOrigin(origin); } imageData.set({ dataType: dataType, voxelManager: this.voxelManager, id: volumeId, numberOfComponents: numberOfComponents || 1, }, this.suppressWarnings); imageData.set({ hasScalarVolume: false, }, this.suppressWarnings); this.imageData = imageData; this.numFrames = this._getNumFrames(); this._reprocessImageIds(); if (scaling) { this.scaling = scaling; } if (referencedVolumeId) { this.referencedVolumeId = referencedVolumeId; } if (referencedImageIds) { this.referencedImageIds = referencedImageIds; } if (additionalDetails) { this.additionalDetails = additionalDetails; } } get sizeInBytes() { return this.voxelManager.sizeInBytes; } get imageIds() { return this._imageIds; } set imageIds(newImageIds) { this._imageIds = newImageIds; this._reprocessImageIds(); } _reprocessImageIds() { this._imageIdsIndexMap.clear(); this._imageURIsIndexMap.clear(); this._imageIds.forEach((imageId, i) => { const imageURI = imageIdToURI(imageId); this._imageIdsIndexMap.set(imageId, i); this._imageURIsIndexMap.set(imageURI, i); }); } isDynamicVolume() { if (this.numTimePoints) { return this.numTimePoints > 1; } return false; } getImageIdIndex(imageId) { return this._imageIdsIndexMap.get(imageId); } getImageIdByIndex(imageIdIndex) { return this._imageIds[imageIdIndex]; } getImageURIIndex(imageURI) { return this._imageURIsIndexMap.get(imageURI); } load(callback) { } destroy() { this.imageData.delete(); this.imageData = null; this.voxelManager.clear(); this.vtkOpenGLTexture.releaseGraphicsResources(); this.vtkOpenGLTexture.delete(); } invalidate() { for (let i = 0; i < this.imageIds.length; i++) { this.vtkOpenGLTexture.setUpdatedFrame(i); } this.imageData.modified(); } modified() { this.imageData.modified(); this.vtkOpenGLTexture.modified(); this.numFrames = this._getNumFrames(); } removeFromCache() { cache.removeVolumeLoadObject(this.volumeId); } getScalarDataLength() { return this.voxelManager.getScalarDataLength(); } _getNumFrames() { if (!this.isDynamicVolume()) { return this.imageIds.length; } return this.numTimePoints; } imageIdIndexToFrameIndex(imageIdIndex) { return imageIdIndex % this.numFrames; } getCornerstoneImages() { const { imageIds } = this; return imageIds.map((imageId) => { return cache.getImage(imageId); }); } } export default ImageVolume;