@cornerstonejs/core
Version:
Cornerstone3D Core
61 lines (60 loc) • 2.76 kB
JavaScript
import transformWorldToIndex from './transformWorldToIndex.js';
import transformIndexToWorld from './transformIndexToWorld.js';
import uuidv4 from './uuidv4.js';
import { createLocalVolume } from '../loaders/volumeLoader.js';
import cache from '../cache/cache.js';
function createSubVolume(referencedVolumeId, boundsIJK, options = {}) {
const referencedVolume = cache.getVolume(referencedVolumeId);
if (!referencedVolume) {
throw new Error(`Referenced volume with id ${referencedVolumeId} does not exist.`);
}
const { metadata, spacing, direction, dimensions: refVolumeDim, } = referencedVolume;
const { minX, maxX, minY, maxY, minZ, maxZ } = boundsIJK;
const ijkTopLeft = [
Math.min(minX, maxX),
Math.min(minY, maxY),
Math.min(minZ, maxZ),
];
const boundingBoxOriginWorld = transformIndexToWorld(referencedVolume.imageData, ijkTopLeft);
const dimensions = [
Math.abs(maxX - minX) + 1,
Math.abs(maxY - minY) + 1,
Math.abs(maxZ - minZ) + 1,
];
const { targetBuffer } = options;
const subVolumeOptions = {
metadata,
dimensions,
spacing,
origin: boundingBoxOriginWorld,
direction,
targetBuffer,
scalarData: targetBuffer?.type === 'Float32Array'
? new Float32Array(dimensions[0] * dimensions[1] * dimensions[2])
: undefined,
};
const subVolume = createLocalVolume(uuidv4(), subVolumeOptions);
const subVolumeData = subVolume.voxelManager.getCompleteScalarDataArray();
const subVolumeSliceSize = dimensions[0] * dimensions[1];
const refVolumeSliceSize = refVolumeDim[0] * refVolumeDim[1];
const refVolumeData = referencedVolume.voxelManager.getCompleteScalarDataArray();
for (let z = 0; z < dimensions[2]; z++) {
for (let y = 0; y < dimensions[1]; y++) {
const rowStartWorld = transformIndexToWorld(subVolume.imageData, [
0,
y,
z,
]);
const refVolumeRowStartIJK = transformWorldToIndex(referencedVolume.imageData, rowStartWorld);
const refVolumeRowStartOffset = refVolumeRowStartIJK[2] * refVolumeSliceSize +
refVolumeRowStartIJK[1] * refVolumeDim[0] +
refVolumeRowStartIJK[0];
const rowData = refVolumeData.slice(refVolumeRowStartOffset, refVolumeRowStartOffset + dimensions[0]);
const subVolumeLineStartOffset = z * subVolumeSliceSize + y * dimensions[0];
subVolumeData.set(rowData, subVolumeLineStartOffset);
}
}
subVolume.voxelManager.setCompleteScalarDataArray(subVolumeData);
return subVolume;
}
export { createSubVolume as default, createSubVolume };