fix(segmentation overlays): Allow for the addition of multiple segmentation overlays. (#5189)

This commit is contained in:
Joe Boccanfuso authored and GitHub committed 2025-07-10 09:33:39 -04:00
1 parent 32ab291305
commit 48473625f6
19 files changed
+187 -44

No files matched your search

@@ -650,25 +650,27 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
csToolsUtils.stackContextPrefetch.enable(element);
});
let imageIdsToSet = imageIds;
const overlayProcessingResult = this._processExtraDisplaySetsForViewport(viewport);
imageIdsToSet = overlayProcessingResult?.imageIds ?? imageIdsToSet;
const overlayProcessingResults = this._processExtraDisplaySetsForViewport(viewport);
const referencedImageId = presentations?.positionPresentation?.viewReference?.referencedImageId;
if (referencedImageId) {
initialImageIndexToUse = imageIdsToSet.indexOf(referencedImageId);
initialImageIndexToUse = imageIds.indexOf(referencedImageId);
}
if (initialImageIndexToUse === undefined || initialImageIndexToUse === null) {
initialImageIndexToUse = this._getInitialImageIndexForViewport(viewportInfo, imageIds) || 0;
}
return viewport.setStack(imageIdsToSet, initialImageIndexToUse).then(() => {
return viewport.setStack(imageIds, initialImageIndexToUse).then(() => {
viewport.setProperties({ ...properties });
this.setPresentations(viewport.id, presentations, viewportInfo);
if (overlayProcessingResult?.addOverlayFn) {
overlayProcessingResult.addOverlayFn();
if (overlayProcessingResults?.length) {
overlayProcessingResults.forEach(overlayProcessingResult => {
if (overlayProcessingResult?.addOverlayFn) {
overlayProcessingResult.addOverlayFn();
}
});
}
if (displayArea) {
@@ -874,28 +876,35 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
});
// For SEG and RT viewports
const { addOverlayFn, imageIds } = this._processExtraDisplaySetsForViewport(viewport) || {};
const overlayProcessingResults = this._processExtraDisplaySetsForViewport(viewport) || [];
if (!filteredVolumeInputArray.length && overlayProcessingResults?.length) {
overlayProcessingResults.forEach(({ imageIds, addOverlayFn }) => {
if (addOverlayFn) {
// if there is no volume input array, and there is an addOverlayFn, means we need to take
// care of the background overlay display set first then the addOverlayFn will add the
// SEG displaySet
const sampleImageId = imageIds[0];
const backgroundDisplaySet = displaySetService.getDisplaySetsBy(
displaySet =>
!displaySet.isOverlayDisplaySet &&
displaySet.images.some(image => image.imageId === sampleImageId)
);
if (!filteredVolumeInputArray.length && addOverlayFn) {
// if there is no volume input array, and there is an addOverlayFn, means we need to take
// care of the background overlay display set first then the addOverlayFn will add the
// SEG displaySet
const sampleImageId = imageIds[0];
const backgroundDisplaySet = displaySetService.getDisplaySetsBy(
displaySet =>
!displaySet.isOverlayDisplaySet &&
displaySet.images.some(image => image.imageId === sampleImageId)
);
if (backgroundDisplaySet.length !== 1) {
throw new Error('Background display set not found');
}
if (backgroundDisplaySet.length !== 1) {
throw new Error('Background display set not found');
}
}
});
}
await viewport.setVolumes(volumeInputArray);
if (addOverlayFn) {
addOverlayFn();
if (overlayProcessingResults?.length) {
overlayProcessingResults.forEach(({ addOverlayFn }) => {
if (addOverlayFn) {
addOverlayFn();
}
});
}
viewport.render();
@@ -934,30 +943,31 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
const displaySetInstanceUIDs = this.viewportsDisplaySets.get(viewport.id);
// Find overlay display sets (e.g. SEG, RTSTRUCT)
const overlayDisplaySet = displaySetInstanceUIDs
const overlayDisplaySets = displaySetInstanceUIDs
.map(displaySetService.getDisplaySetByUID)
.find(displaySet => displaySet?.isOverlayDisplaySet);
.filter(displaySet => displaySet?.isOverlayDisplaySet);
// if it is only the overlay displaySet, then we need to get the reference
// displaySet imageIds and set them as the imageIds for the viewport,
// here we can do some logic if the reference is missing
// then find the most similar match of displaySet instead
if (!overlayDisplaySet) {
if (!overlayDisplaySets?.length) {
return;
}
let imageIds;
if (overlayDisplaySet.referencedDisplaySetInstanceUID) {
const referenceDisplaySet = displaySetService.getDisplaySetByUID(
overlayDisplaySet.referencedDisplaySetInstanceUID
);
imageIds = referenceDisplaySet.images.map(image => image.imageId);
}
return {
imageIds,
addOverlayFn: () => this.addOverlayRepresentationForDisplaySet(overlayDisplaySet, viewport),
};
return overlayDisplaySets.map(overlayDisplaySet => {
let imageIds;
if (overlayDisplaySet.referencedDisplaySetInstanceUID) {
const referenceDisplaySet = displaySetService.getDisplaySetByUID(
overlayDisplaySet.referencedDisplaySetInstanceUID
);
imageIds = referenceDisplaySet.images.map(image => image.imageId);
}
return {
imageIds,
addOverlayFn: () => this.addOverlayRepresentationForDisplaySet(overlayDisplaySet, viewport),
};
});
}
private addOverlayRepresentationForDisplaySet(