Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | import { utilities as csUtils } from '@cornerstonejs/core';
import type { Types } from '@cornerstonejs/core';
import getBoundingBoxAroundShape from '../boundingBox/getBoundingBoxAroundShape';
import extend2DBoundingBoxInViewAxis from '../boundingBox/extend2DBoundingBoxInViewAxis';
type Options = {
numSlicesToProject?: number;
};
function getBoundsIJKFromRectangleAnnotations(
annotations,
referenceVolume,
options = {} as Options
) {
const AllBoundsIJK = [];
annotations.forEach((annotation) => {
const { data } = annotation;
const { points } = data.handles;
const { imageData, dimensions } = referenceVolume;
let pointsToUse = points;
// If the tool is a 2D tool but has projection points, use them
if (data.cachedStats?.projectionPoints) {
const { projectionPoints } = data.cachedStats;
pointsToUse = [].concat(...projectionPoints); // cannot use flat() because of typescript compiler right now
}
const rectangleCornersIJK = pointsToUse.map(
(world) => csUtils.transformWorldToIndex(imageData, world) as Types.Point3
);
let boundsIJK = getBoundingBoxAroundShape(rectangleCornersIJK, dimensions);
// If the tool is 2D but it is configured to project to X amount of slices
// Don't project the slices if projectionPoints have been used to define the extents
if (options.numSlicesToProject && !data.cachedStats?.projectionPoints) {
boundsIJK = extend2DBoundingBoxInViewAxis(
boundsIJK,
options.numSlicesToProject
);
}
AllBoundsIJK.push(boundsIJK);
});
if (AllBoundsIJK.length === 1) {
return AllBoundsIJK[0];
}
// Get the intersection of all the bounding boxes
// This is the bounding box that contains all the ROIs
const boundsIJK = AllBoundsIJK.reduce(
(accumulator, currentValue) => {
return {
iMin: Math.min(accumulator.iMin, currentValue.iMin),
jMin: Math.min(accumulator.jMin, currentValue.jMin),
kMin: Math.min(accumulator.kMin, currentValue.kMin),
iMax: Math.max(accumulator.iMax, currentValue.iMax),
jMax: Math.max(accumulator.jMax, currentValue.jMax),
kMax: Math.max(accumulator.kMax, currentValue.kMax),
};
},
{
iMin: Infinity,
jMin: Infinity,
kMin: Infinity,
iMax: -Infinity,
jMax: -Infinity,
kMax: -Infinity,
}
);
return boundsIJK;
}
export default getBoundsIJKFromRectangleAnnotations;
|