Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,21 @@ export function getVolumeImageIdIndexWorldPoint(
}

const dimensions = imageData.getDimensions();
const k = Math.min(Math.max(0, imageIdIndex), dimensions[2] - 1);
// Dynamic (4D) volumes flatten their imageIds across dimension groups while
// dimensions[2] is the slice count of a SINGLE group, so an image from any
// later group has a flattened index >= dimensions[2] — clamping that raw
// index would pin every such image to the final slice. Map it to its
// group-local slice first (the k axis repeats per group).
const flatToGroupLocal = (
imageVolume as {
flatImageIdIndexToImageIdIndex?: (flatImageIdIndex: number) => number;
}
).flatImageIdIndexToImageIdIndex;
const groupLocalIndex =
typeof flatToGroupLocal === 'function'
? flatToGroupLocal.call(imageVolume, Math.max(0, imageIdIndex))
: imageIdIndex;
const k = Math.min(Math.max(0, groupLocalIndex), dimensions[2] - 1);

return imageData.indexToWorld([
(dimensions[0] - 1) / 2,
Expand Down
22 changes: 22 additions & 0 deletions packages/core/test/planarSliceBasis.jest.js
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,28 @@ describe('resolvePlanarVolumeImageIdIndex', () => {
});

describe('getVolumeImageIdIndexWorldPoint', () => {
it('maps a flattened dynamic-volume index to its group-local slice', () => {
// A 4D volume flattens its imageIds across dimension groups (here 3
// groups of 6 slices) while dimensions[2] stays the per-group slice
// count, and exposes the flat -> group-local mapping.
const volume = createOrthonormalVolume();

volume.flatImageIdIndexToImageIdIndex = (flatImageIdIndex) =>
flatImageIdIndex % 6;

// Flattened index 14 = group 3, local slice 2 — NOT the last slice (5)
// that a raw clamp against dimensions[2] - 1 would produce.
expectPoint3Close(
getVolumeImageIdIndexWorldPoint(volume, 14),
[102.25, 203.5, 304]
);
// Indices inside the first group pass through the mapping unchanged.
expectPoint3Close(
getVolumeImageIdIndexWorldPoint(volume, 2),
[102.25, 203.5, 304]
);
});

it('returns the exact IJK slice center for an imageId-list index', () => {
const volume = createOrthonormalVolume();

Expand Down
Loading