Skip to content

Commit 12b61ca

Browse files
committed
some wip
1 parent 5188892 commit 12b61ca

File tree

9 files changed

+119
-68
lines changed

9 files changed

+119
-68
lines changed

packages/adapters/examples/segmentationStack/demo.ts

+23
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,28 @@
11
/* eslint-disable */
22
const dicomMap = new Map();
33

4+
dicomMap.set(
5+
"1.3.6.1.4.1.14519.5.2.1.3671.4754.298665348758363466150039312520",
6+
{
7+
fetchDicom: {
8+
StudyInstanceUID:
9+
"1.3.6.1.4.1.14519.5.2.1.3671.4754.298665348758363466150039312520",
10+
SeriesInstanceUID:
11+
"1.3.6.1.4.1.14519.5.2.1.3671.4754.235188122843915982710753948536",
12+
wadoRsRoot: "https://d14fa38qiwhyfd.cloudfront.net/dicomweb"
13+
},
14+
fetchSegmentation: {
15+
StudyInstanceUID:
16+
"1.3.6.1.4.1.14519.5.2.1.3671.4754.298665348758363466150039312520",
17+
SeriesInstanceUID:
18+
"1.2.276.0.7230010.3.1.3.1426846371.15380.1513205183.303",
19+
SOPInstanceUID:
20+
"1.2.276.0.7230010.3.1.4.1426846371.15380.1513205183.304",
21+
wadoRsRoot: "https://d14fa38qiwhyfd.cloudfront.net/dicomweb"
22+
}
23+
}
24+
);
25+
426
dicomMap.set(
527
"1.3.6.1.4.1.14519.5.2.1.256467663913010332776401703474716742458",
628
{
@@ -22,6 +44,7 @@ dicomMap.set(
2244
}
2345
}
2446
);
47+
2548
dicomMap.set("1.3.12.2.1107.5.2.32.35162.30000015050317233592200000046", {
2649
fetchDicom: {
2750
StudyInstanceUID:

packages/tools/src/eventListeners/segmentation/imageChangeEventListener.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
} from '@cornerstonejs/core';
1212
import { triggerSegmentationRender } from '../../stateManagement/segmentation/SegmentationRenderingEngine';
1313
import { updateLabelmapSegmentationImageReferences } from '../../stateManagement/segmentation/updateLabelmapSegmentationImageReferences';
14-
import { getCurrentLabelmapImageIdForViewportOverlapping } from '../../stateManagement/segmentation/getCurrentLabelmapImageIdForViewport';
14+
import { getCurrentLabelmapImageIdsForViewport } from '../../stateManagement/segmentation/getCurrentLabelmapImageIdForViewport';
1515
import { SegmentationRepresentations } from '../../enums';
1616
import { getLabelmapActorEntries } from '../../stateManagement/segmentation/helpers/getSegmentationActor';
1717
import { getSegmentationRepresentations } from '../../stateManagement/segmentation/getSegmentationRepresentation';
@@ -114,7 +114,7 @@ function _imageChangeEventListener(evt) {
114114
// if cannot find a representation for this actor means it has stuck around
115115
// form previous renderings and should be removed
116116
const validActor = labelmapRepresentations.find((representation) => {
117-
const derivedImageIds = getCurrentLabelmapImageIdForViewportOverlapping(
117+
const derivedImageIds = getCurrentLabelmapImageIdsForViewport(
118118
viewportId,
119119
representation.segmentationId
120120
);
@@ -130,7 +130,7 @@ function _imageChangeEventListener(evt) {
130130
labelmapRepresentations.forEach((representation) => {
131131
const { segmentationId } = representation;
132132
const currentImageId = viewport.getCurrentImageId();
133-
const derivedImageIds = getCurrentLabelmapImageIdForViewportOverlapping(
133+
const derivedImageIds = getCurrentLabelmapImageIdsForViewport(
134134
viewportId,
135135
segmentationId
136136
);
@@ -139,7 +139,7 @@ function _imageChangeEventListener(evt) {
139139
return;
140140
}
141141

142-
derivedImageIds.forEach((derivedImageId) => {
142+
const updateSegmentationActor = (derivedImageId) => {
143143
const derivedImage = cache.getImage(derivedImageId);
144144

145145
if (!derivedImage) {
@@ -231,7 +231,9 @@ function _imageChangeEventListener(evt) {
231231
);
232232
}
233233
}
234-
});
234+
};
235+
236+
derivedImageIds.forEach(updateSegmentationActor);
235237

236238
viewport.render();
237239

packages/tools/src/eventListeners/segmentation/labelmap/onLabelmapSegmentationDataModified.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -139,15 +139,15 @@ function performStackLabelmapUpdate({ viewportIds, segmentationId }) {
139139

140140
const actorEntries = getLabelmapActorEntries(viewportId, segmentationId);
141141

142-
if (!actorEntries) {
142+
if (!actorEntries?.length) {
143143
return;
144144
}
145145

146146
actorEntries.forEach((actorEntry) => {
147147
const segImageData = actorEntry.actor.getMapper().getInputData();
148148

149149
const currentSegmentationImageId =
150-
SegmentationState.getCurrentLabelmapImageIdForViewport(
150+
SegmentationState.getCurrentLabelmapImageIdsForViewport(
151151
viewportId,
152152
segmentationId
153153
);

packages/tools/src/stateManagement/segmentation/SegmentationStateManager.ts

+44-44
Original file line numberDiff line numberDiff line change
@@ -75,38 +75,6 @@ export default class SegmentationStateManager {
7575
this.uid = uid;
7676
}
7777

78-
/**
79-
* Generates a key for the _labelmapImageIdReferenceMap
80-
* @param param0.segmentationId
81-
* @param param0.imageId
82-
*/
83-
generateMapKey({ segmentationId, imageId }) {
84-
return `${segmentationId}-${imageId}`;
85-
}
86-
87-
/**
88-
* Updates the _labelmapImageIdReferenceMap according to the correct key and preserving old values
89-
* @param param0.segmentationId
90-
* @param param0.imageId
91-
* @param param0.labelmapImageId
92-
*/
93-
_updateLabelmapImageIdReferenceMap({
94-
segmentationId,
95-
imageId,
96-
labelmapImageId,
97-
}) {
98-
const key = this.generateMapKey({ segmentationId, imageId });
99-
100-
if (!this._labelmapImageIdReferenceMap.has(key)) {
101-
this._labelmapImageIdReferenceMap.set(key, [labelmapImageId]);
102-
return;
103-
}
104-
105-
const currentValues = this._labelmapImageIdReferenceMap.get(key);
106-
const newValues = Array.from(new Set([...currentValues, labelmapImageId]));
107-
this._labelmapImageIdReferenceMap.set(key, newValues);
108-
}
109-
11078
/**
11179
* Returns a copy of the current state of the segmentation.
11280
*/
@@ -488,7 +456,7 @@ export default class SegmentationStateManager {
488456
labelmapImageIds,
489457
updateCallback
490458
): string | undefined {
491-
const currentImageId = viewport.getCurrentImageId();
459+
const referenceImageId = viewport.getCurrentImageId();
492460

493461
let viewableLabelmapImageIdFound = false;
494462
for (const labelmapImageId of labelmapImageIds) {
@@ -501,10 +469,10 @@ export default class SegmentationStateManager {
501469
viewableLabelmapImageIdFound = true;
502470
this._stackLabelmapImageIdReferenceMap
503471
.get(segmentationId)
504-
.set(currentImageId, labelmapImageId);
472+
.set(referenceImageId, labelmapImageId);
505473
this._updateLabelmapImageIdReferenceMap({
506474
segmentationId,
507-
imageId: currentImageId,
475+
referenceImageId,
508476
labelmapImageId,
509477
});
510478
}
@@ -517,7 +485,7 @@ export default class SegmentationStateManager {
517485
return viewableLabelmapImageIdFound
518486
? this._stackLabelmapImageIdReferenceMap
519487
.get(segmentationId)
520-
.get(currentImageId)
488+
.get(referenceImageId)
521489
: undefined;
522490
}
523491

@@ -585,7 +553,7 @@ export default class SegmentationStateManager {
585553
labelmapImageIds,
586554
(stackViewport, segmentationId, labelmapImageIds) => {
587555
const imageIds = stackViewport.getImageIds();
588-
imageIds.forEach((imageId, index) => {
556+
imageIds.forEach((referenceImageId, index) => {
589557
for (const labelmapImageId of labelmapImageIds) {
590558
const viewableImageId = stackViewport.isReferenceViewable(
591559
{ referencedImageId: labelmapImageId, sliceIndex: index },
@@ -595,10 +563,10 @@ export default class SegmentationStateManager {
595563
if (viewableImageId) {
596564
this._stackLabelmapImageIdReferenceMap
597565
.get(segmentationId)
598-
.set(imageId, labelmapImageId);
566+
.set(referenceImageId, labelmapImageId);
599567
this._updateLabelmapImageIdReferenceMap({
600568
segmentationId,
601-
imageId,
569+
referenceImageId,
602570
labelmapImageId,
603571
});
604572
}
@@ -638,13 +606,13 @@ export default class SegmentationStateManager {
638606
}
639607

640608
/**
641-
* Retrieves the stack labelmap imageId associated with the current imageId
609+
* Retrieves the stack labelmap imageIds associated with the current imageId
642610
* that is rendered on the viewport.
643611
* @param viewportId - The ID of the viewport.
644612
* @param segmentationId - The UID of the segmentation representation.
645613
* @returns A Map object containing the image ID reference map, or undefined if the enabled element is not found.
646614
*/
647-
getCurrentLabelmapImageIdForViewportOverlapping(
615+
getCurrentLabelmapImageIdsForViewport(
648616
viewportId: string,
649617
segmentationId: string
650618
): string[] | undefined {
@@ -655,11 +623,11 @@ export default class SegmentationStateManager {
655623
}
656624

657625
const stackViewport = enabledElement.viewport as Types.IStackViewport;
658-
const currentImageId = stackViewport.getCurrentImageId();
626+
const referenceImageId = stackViewport.getCurrentImageId();
659627

660-
const key = this.generateMapKey({
628+
const key = this._generateMapKey({
661629
segmentationId,
662-
imageId: currentImageId,
630+
referenceImageId,
663631
});
664632
return this._labelmapImageIdReferenceMap.get(key);
665633
}
@@ -891,6 +859,29 @@ export default class SegmentationStateManager {
891859
return removedRepresentations;
892860
}
893861

862+
/**
863+
* Updates the _labelmapImageIdReferenceMap according to the correct key and preserving old values
864+
* @param segmentationId
865+
* @param referenceImageId
866+
* @param labelmapImageId
867+
*/
868+
_updateLabelmapImageIdReferenceMap({
869+
segmentationId,
870+
referenceImageId,
871+
labelmapImageId,
872+
}) {
873+
const key = this._generateMapKey({ segmentationId, referenceImageId });
874+
875+
if (!this._labelmapImageIdReferenceMap.has(key)) {
876+
this._labelmapImageIdReferenceMap.set(key, [labelmapImageId]);
877+
return;
878+
}
879+
880+
const currentValues = this._labelmapImageIdReferenceMap.get(key);
881+
const newValues = Array.from(new Set([...currentValues, labelmapImageId]));
882+
this._labelmapImageIdReferenceMap.set(key, newValues);
883+
}
884+
894885
_setActiveSegmentation(
895886
state: SegmentationState,
896887
viewportId: string,
@@ -1158,6 +1149,15 @@ export default class SegmentationStateManager {
11581149

11591150
return result;
11601151
}
1152+
1153+
/**
1154+
* Generates a key for the _labelmapImageIdReferenceMap
1155+
* @param segmentationId - The ID of the segmentation
1156+
* @param referenceImageId - The reference image ID - this is the imageId that is currently being displayed in the viewport (not the derived imageId)
1157+
*/
1158+
private _generateMapKey({ segmentationId, referenceImageId }) {
1159+
return `${segmentationId}-${referenceImageId}`;
1160+
}
11611161
}
11621162

11631163
async function internalComputeVolumeLabelmapFromStack({

packages/tools/src/stateManagement/segmentation/getCurrentLabelmapImageIdForViewport.ts

+18-4
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,38 @@ import { defaultSegmentationStateManager } from './SegmentationStateManager';
66
* @param viewportId - The ID of the viewport.
77
* @param segmentationId - The ID of the segmentation.
88
* @returns An array of labelmap image IDs.
9+
*
10+
* @deprecated Use getCurrentLabelmapImageIdsForViewport instead. since we
11+
* have added support for multiple imageIds in the same viewport for the
12+
* same labelmap representation (overlapping segments usecase)
913
*/
1014
export function getCurrentLabelmapImageIdForViewport(
1115
viewportId: string,
1216
segmentationId: string
1317
) {
14-
const segmentationStateManager = defaultSegmentationStateManager;
15-
return segmentationStateManager.getCurrentLabelmapImageIdForViewport(
18+
const imageIds = getCurrentLabelmapImageIdsForViewport(
1619
viewportId,
1720
segmentationId
1821
);
22+
23+
return imageIds[0];
1924
}
2025

21-
export function getCurrentLabelmapImageIdForViewportOverlapping(
26+
/**
27+
* Retrieves the labelmap image IDs for a specific viewport and segmentation representation.
28+
* If the segmentation has multiple imageIds for in the current view of the same segmentation
29+
* this function will return an array of imageIds.
30+
*
31+
* @param viewportId - The ID of the viewport.
32+
* @param segmentationId - The ID of the segmentation.
33+
* @returns An array of labelmap image IDs.
34+
*/
35+
export function getCurrentLabelmapImageIdsForViewport(
2236
viewportId: string,
2337
segmentationId: string
2438
) {
2539
const segmentationStateManager = defaultSegmentationStateManager;
26-
return segmentationStateManager.getCurrentLabelmapImageIdForViewportOverlapping(
40+
return segmentationStateManager.getCurrentLabelmapImageIdsForViewport(
2741
viewportId,
2842
segmentationId
2943
);

packages/tools/src/stateManagement/segmentation/segmentationState.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ import { getNextColorLUTIndex } from './getNextColorLUTIndex';
1919
import { removeColorLUT } from './removeColorLUT';
2020
import { getViewportSegmentations } from './getViewportSegmentations';
2121
import { getViewportIdsWithSegmentation } from './getViewportIdsWithSegmentation';
22-
import { getCurrentLabelmapImageIdForViewport } from './getCurrentLabelmapImageIdForViewport';
22+
import {
23+
getCurrentLabelmapImageIdForViewport,
24+
getCurrentLabelmapImageIdsForViewport,
25+
} from './getCurrentLabelmapImageIdForViewport';
2326
import { updateLabelmapSegmentationImageReferences } from './updateLabelmapSegmentationImageReferences';
2427
import { getStackSegmentationImageIdsForViewport } from './getStackSegmentationImageIdsForViewport';
2528
import {
@@ -37,6 +40,7 @@ export {
3740
// get
3841
getColorLUT,
3942
getCurrentLabelmapImageIdForViewport,
43+
getCurrentLabelmapImageIdsForViewport,
4044
getNextColorLUTIndex,
4145
getSegmentation,
4246
getSegmentations,

packages/tools/src/tools/displayTools/Labelmap/addLabelmapToElement.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import type {
1414
LabelmapSegmentationDataStack,
1515
LabelmapSegmentationDataVolume,
1616
} from '../../../types/LabelmapTypes';
17-
import { getCurrentLabelmapImageIdForViewportOverlapping } from '../../../stateManagement/segmentation/getCurrentLabelmapImageIdForViewport';
17+
import { getCurrentLabelmapImageIdsForViewport } from '../../../stateManagement/segmentation/getCurrentLabelmapImageIdForViewport';
1818
import { getSegmentation } from '../../../stateManagement/segmentation/getSegmentation';
1919
import {
2020
triggerSegmentationDataModified,
@@ -136,11 +136,10 @@ async function addLabelmapToElement(
136136
} else {
137137
// We can use the current imageId in the viewport to get the segmentation imageId
138138
// which later is used to create the actor and mapper.
139-
const segmentationImageIds =
140-
getCurrentLabelmapImageIdForViewportOverlapping(
141-
viewport.id,
142-
segmentationId
143-
);
139+
const segmentationImageIds = getCurrentLabelmapImageIdsForViewport(
140+
viewport.id,
141+
segmentationId
142+
);
144143

145144
const stackInputs: Types.IStackInput[] = segmentationImageIds.map(
146145
(imageId) => ({

packages/tools/src/tools/displayTools/Labelmap/labelmapDisplay.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import addLabelmapToElement from './addLabelmapToElement';
1818
import removeLabelmapFromElement from './removeLabelmapFromElement';
1919
import { getActiveSegmentation } from '../../../stateManagement/segmentation/activeSegmentation';
2020
import { getColorLUT } from '../../../stateManagement/segmentation/getColorLUT';
21-
import { getCurrentLabelmapImageIdForViewportOverlapping } from '../../../stateManagement/segmentation/getCurrentLabelmapImageIdForViewport';
21+
import { getCurrentLabelmapImageIdsForViewport } from '../../../stateManagement/segmentation/getCurrentLabelmapImageIdForViewport';
2222
import { getSegmentation } from '../../../stateManagement/segmentation/getSegmentation';
2323
import { canComputeRequestedRepresentation } from '../../../stateManagement/segmentation/polySeg/canComputeRequestedRepresentation';
2424
import { computeAndAddLabelmapRepresentation } from '../../../stateManagement/segmentation/polySeg/Labelmap/computeAndAddLabelmapRepresentation';
@@ -136,7 +136,7 @@ async function render(
136136
}
137137

138138
if (viewport instanceof VolumeViewport) {
139-
if (!labelmapActorEntries) {
139+
if (!labelmapActorEntries?.length) {
140140
// only add the labelmap to ToolGroup viewports if it is not already added
141141
await _addLabelmapToViewport(
142142
viewport,
@@ -149,7 +149,7 @@ async function render(
149149
labelmapActorEntries = getLabelmapActorEntries(viewport.id, segmentationId);
150150
} else {
151151
// stack segmentation
152-
const labelmapImageIds = getCurrentLabelmapImageIdForViewportOverlapping(
152+
const labelmapImageIds = getCurrentLabelmapImageIdsForViewport(
153153
viewport.id,
154154
segmentationId
155155
);
@@ -173,7 +173,7 @@ async function render(
173173
labelmapActorEntries = getLabelmapActorEntries(viewport.id, segmentationId);
174174
}
175175

176-
if (!labelmapActorEntries) {
176+
if (!labelmapActorEntries?.length) {
177177
return;
178178
}
179179

0 commit comments

Comments
 (0)