@cornerstonejs/tools 3.3.3 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/eventListeners/segmentation/imageChangeEventListener.js +58 -55
- package/dist/esm/eventListeners/segmentation/labelmap/onLabelmapSegmentationDataModified.js +10 -8
- package/dist/esm/stateManagement/segmentation/SegmentationStateManager.d.ts +8 -0
- package/dist/esm/stateManagement/segmentation/SegmentationStateManager.js +44 -5
- package/dist/esm/stateManagement/segmentation/getCurrentLabelmapImageIdForViewport.d.ts +1 -0
- package/dist/esm/stateManagement/segmentation/getCurrentLabelmapImageIdForViewport.js +5 -1
- package/dist/esm/stateManagement/segmentation/helpers/getSegmentationActor.d.ts +1 -0
- package/dist/esm/stateManagement/segmentation/helpers/getSegmentationActor.js +16 -0
- package/dist/esm/stateManagement/segmentation/helpers/index.d.ts +2 -2
- package/dist/esm/stateManagement/segmentation/helpers/index.js +2 -2
- package/dist/esm/stateManagement/segmentation/segmentationState.d.ts +2 -2
- package/dist/esm/stateManagement/segmentation/segmentationState.js +2 -2
- package/dist/esm/tools/displayTools/Labelmap/addLabelmapToElement.js +6 -8
- package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.js +13 -11
- package/dist/esm/utilities/segmentation/getSegmentIndexAtWorldPoint.js +7 -2
- package/package.json +3 -3
|
@@ -3,9 +3,9 @@ import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
|
|
|
3
3
|
import { BaseVolumeViewport, getEnabledElement, Enums, getEnabledElementByIds, cache, utilities, } from '@cornerstonejs/core';
|
|
4
4
|
import { triggerSegmentationRender } from '../../stateManagement/segmentation/SegmentationRenderingEngine';
|
|
5
5
|
import { updateLabelmapSegmentationImageReferences } from '../../stateManagement/segmentation/updateLabelmapSegmentationImageReferences';
|
|
6
|
-
import {
|
|
6
|
+
import { getCurrentLabelmapImageIdsForViewport } from '../../stateManagement/segmentation/getCurrentLabelmapImageIdForViewport';
|
|
7
7
|
import { SegmentationRepresentations } from '../../enums';
|
|
8
|
-
import {
|
|
8
|
+
import { getLabelmapActorEntries } from '../../stateManagement/segmentation/helpers/getSegmentationActor';
|
|
9
9
|
import { getSegmentationRepresentations } from '../../stateManagement/segmentation/getSegmentationRepresentation';
|
|
10
10
|
const enable = function (element) {
|
|
11
11
|
if (!element) {
|
|
@@ -42,8 +42,8 @@ function _imageChangeEventListener(evt) {
|
|
|
42
42
|
updateLabelmapSegmentationImageReferences(viewportId, segmentationId);
|
|
43
43
|
});
|
|
44
44
|
const labelmapActors = labelmapRepresentations
|
|
45
|
-
.
|
|
46
|
-
return
|
|
45
|
+
.flatMap((representation) => {
|
|
46
|
+
return getLabelmapActorEntries(viewportId, representation.segmentationId);
|
|
47
47
|
})
|
|
48
48
|
.filter((actor) => actor !== undefined);
|
|
49
49
|
if (!labelmapActors.length) {
|
|
@@ -51,8 +51,8 @@ function _imageChangeEventListener(evt) {
|
|
|
51
51
|
}
|
|
52
52
|
labelmapActors.forEach((actor) => {
|
|
53
53
|
const validActor = labelmapRepresentations.find((representation) => {
|
|
54
|
-
const
|
|
55
|
-
return
|
|
54
|
+
const derivedImageIds = getCurrentLabelmapImageIdsForViewport(viewportId, representation.segmentationId);
|
|
55
|
+
return derivedImageIds?.includes(actor.referencedId);
|
|
56
56
|
});
|
|
57
57
|
if (!validActor) {
|
|
58
58
|
viewport.removeActors([actor.uid]);
|
|
@@ -61,61 +61,64 @@ function _imageChangeEventListener(evt) {
|
|
|
61
61
|
labelmapRepresentations.forEach((representation) => {
|
|
62
62
|
const { segmentationId } = representation;
|
|
63
63
|
const currentImageId = viewport.getCurrentImageId();
|
|
64
|
-
const
|
|
65
|
-
if (!
|
|
64
|
+
const derivedImageIds = getCurrentLabelmapImageIdsForViewport(viewportId, segmentationId);
|
|
65
|
+
if (!derivedImageIds) {
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
imageActor
|
|
68
|
+
const updateSegmentationActor = (derivedImageId) => {
|
|
69
|
+
const derivedImage = cache.getImage(derivedImageId);
|
|
70
|
+
if (!derivedImage) {
|
|
71
|
+
console.warn('No derived image found in the cache for segmentation representation', representation);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const segmentationActorInput = actors.find((actor) => actor.referencedId === derivedImageId);
|
|
75
|
+
if (!segmentationActorInput) {
|
|
76
|
+
const { dimensions, spacing, direction } = viewport.getImageDataMetadata(derivedImage);
|
|
77
|
+
const currentImage = cache.getImage(currentImageId) ||
|
|
78
|
+
{
|
|
79
|
+
imageId: currentImageId,
|
|
80
|
+
};
|
|
81
|
+
const { origin: currentOrigin } = viewport.getImageDataMetadata(currentImage);
|
|
82
|
+
const originToUse = currentOrigin;
|
|
83
|
+
const constructor = derivedImage.voxelManager.getConstructor();
|
|
84
|
+
const newPixelData = derivedImage.voxelManager.getScalarData();
|
|
85
|
+
const scalarArray = vtkDataArray.newInstance({
|
|
86
|
+
name: 'Pixels',
|
|
87
|
+
numberOfComponents: 1,
|
|
88
|
+
values: new constructor(newPixelData),
|
|
89
|
+
});
|
|
90
|
+
const imageData = vtkImageData.newInstance();
|
|
91
|
+
imageData.setDimensions(dimensions[0], dimensions[1], 1);
|
|
92
|
+
imageData.setSpacing(spacing);
|
|
93
|
+
imageData.setDirection(direction);
|
|
94
|
+
imageData.setOrigin(originToUse);
|
|
95
|
+
imageData.getPointData().setScalars(scalarArray);
|
|
96
|
+
imageData.modified();
|
|
97
|
+
viewport.addImages([
|
|
98
|
+
{
|
|
99
|
+
imageId: derivedImageId,
|
|
100
|
+
representationUID: `${segmentationId}-${SegmentationRepresentations.Labelmap}-${derivedImage.imageId}`,
|
|
101
|
+
callback: ({ imageActor }) => {
|
|
102
|
+
imageActor.getMapper().setInputData(imageData);
|
|
103
|
+
},
|
|
102
104
|
},
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
109
|
-
const segmentationImageData = segmentationActorInput.actor
|
|
110
|
-
.getMapper()
|
|
111
|
-
.getInputData();
|
|
112
|
-
if (segmentationImageData.setDerivedImage) {
|
|
113
|
-
segmentationImageData.setDerivedImage(derivedImage);
|
|
105
|
+
]);
|
|
106
|
+
triggerSegmentationRender(viewportId);
|
|
107
|
+
return;
|
|
114
108
|
}
|
|
115
109
|
else {
|
|
116
|
-
|
|
110
|
+
const segmentationImageData = segmentationActorInput.actor
|
|
111
|
+
.getMapper()
|
|
112
|
+
.getInputData();
|
|
113
|
+
if (segmentationImageData.setDerivedImage) {
|
|
114
|
+
segmentationImageData.setDerivedImage(derivedImage);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
utilities.updateVTKImageDataWithCornerstoneImage(segmentationImageData, derivedImage);
|
|
118
|
+
}
|
|
117
119
|
}
|
|
118
|
-
}
|
|
120
|
+
};
|
|
121
|
+
derivedImageIds.forEach(updateSegmentationActor);
|
|
119
122
|
viewport.render();
|
|
120
123
|
if (evt.type === Enums.Events.IMAGE_RENDERED) {
|
|
121
124
|
viewport.element.removeEventListener(Enums.Events.IMAGE_RENDERED, _imageChangeEventListener);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cache, utilities as csUtils, VolumeViewport, getEnabledElementByViewportId, StackViewport, } from '@cornerstonejs/core';
|
|
2
2
|
import * as SegmentationState from '../../../stateManagement/segmentation/segmentationState';
|
|
3
3
|
import { SegmentationRepresentations } from '../../../enums';
|
|
4
|
-
import {
|
|
4
|
+
import { getLabelmapActorEntries } from '../../../stateManagement/segmentation/helpers/getSegmentationActor';
|
|
5
5
|
const onLabelmapSegmentationDataModified = function (evt) {
|
|
6
6
|
const { segmentationId, modifiedSlicesToUse } = evt.detail;
|
|
7
7
|
const { representationData } = SegmentationState.getSegmentation(segmentationId);
|
|
@@ -68,15 +68,17 @@ function performStackLabelmapUpdate({ viewportIds, segmentationId }) {
|
|
|
68
68
|
if (viewport instanceof VolumeViewport) {
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
71
|
-
const
|
|
72
|
-
if (!
|
|
71
|
+
const actorEntries = getLabelmapActorEntries(viewportId, segmentationId);
|
|
72
|
+
if (!actorEntries?.length) {
|
|
73
73
|
return;
|
|
74
74
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
actorEntries.forEach((actorEntry, i) => {
|
|
76
|
+
const segImageData = actorEntry.actor.getMapper().getInputData();
|
|
77
|
+
const currentSegmentationImageIds = SegmentationState.getCurrentLabelmapImageIdsForViewport(viewportId, segmentationId);
|
|
78
|
+
const segmentationImage = cache.getImage(currentSegmentationImageIds[i]);
|
|
79
|
+
segImageData.modified();
|
|
80
|
+
csUtils.updateVTKImageDataWithCornerstoneImage(segImageData, segmentationImage);
|
|
81
|
+
});
|
|
80
82
|
});
|
|
81
83
|
});
|
|
82
84
|
}
|
|
@@ -5,6 +5,7 @@ export default class SegmentationStateManager {
|
|
|
5
5
|
private state;
|
|
6
6
|
readonly uid: string;
|
|
7
7
|
private _stackLabelmapImageIdReferenceMap;
|
|
8
|
+
private _labelmapImageIdReferenceMap;
|
|
8
9
|
constructor(uid?: string);
|
|
9
10
|
getState(): Readonly<SegmentationState>;
|
|
10
11
|
private updateState;
|
|
@@ -23,6 +24,7 @@ export default class SegmentationStateManager {
|
|
|
23
24
|
updateLabelmapSegmentationImageReferences(viewportId: any, segmentationId: any): string;
|
|
24
25
|
_updateAllLabelmapSegmentationImageReferences(viewportId: any, segmentationId: any): void;
|
|
25
26
|
getLabelmapImageIds(representationData: RepresentationsData): any;
|
|
27
|
+
getCurrentLabelmapImageIdsForViewport(viewportId: string, segmentationId: string): string[] | undefined;
|
|
26
28
|
getCurrentLabelmapImageIdForViewport(viewportId: string, segmentationId: string): string | undefined;
|
|
27
29
|
getStackSegmentationImageIdsForViewport(viewportId: string, segmentationId: string): string[];
|
|
28
30
|
private removeSegmentationRepresentationsInternal;
|
|
@@ -40,6 +42,11 @@ export default class SegmentationStateManager {
|
|
|
40
42
|
segmentationId: string;
|
|
41
43
|
type: SegmentationRepresentations;
|
|
42
44
|
}>;
|
|
45
|
+
_updateLabelmapImageIdReferenceMap({ segmentationId, referenceImageId, labelmapImageId, }: {
|
|
46
|
+
segmentationId: any;
|
|
47
|
+
referenceImageId: any;
|
|
48
|
+
labelmapImageId: any;
|
|
49
|
+
}): void;
|
|
43
50
|
_setActiveSegmentation(state: SegmentationState, viewportId: string, segmentationId: string): void;
|
|
44
51
|
setActiveSegmentation(viewportId: string, segmentationId: string): void;
|
|
45
52
|
getActiveSegmentation(viewportId: string): Segmentation | undefined;
|
|
@@ -70,6 +77,7 @@ export default class SegmentationStateManager {
|
|
|
70
77
|
viewportId: string;
|
|
71
78
|
representations: SegmentationRepresentation[];
|
|
72
79
|
}[];
|
|
80
|
+
private _generateMapKey;
|
|
73
81
|
}
|
|
74
82
|
declare function internalComputeVolumeLabelmapFromStack({ imageIds, options, }: {
|
|
75
83
|
imageIds: string[];
|
|
@@ -13,6 +13,7 @@ const initialDefaultState = {
|
|
|
13
13
|
export default class SegmentationStateManager {
|
|
14
14
|
constructor(uid) {
|
|
15
15
|
this._stackLabelmapImageIdReferenceMap = new Map();
|
|
16
|
+
this._labelmapImageIdReferenceMap = new Map();
|
|
16
17
|
uid ||= csUtils.uuidv4();
|
|
17
18
|
this.state = Object.freeze(csUtils.deepClone(initialDefaultState));
|
|
18
19
|
this.uid = uid;
|
|
@@ -32,6 +33,8 @@ export default class SegmentationStateManager {
|
|
|
32
33
|
return this.state.colorLUT.length;
|
|
33
34
|
}
|
|
34
35
|
resetState() {
|
|
36
|
+
this._stackLabelmapImageIdReferenceMap.clear();
|
|
37
|
+
this._labelmapImageIdReferenceMap.clear();
|
|
35
38
|
this.state = Object.freeze(csUtils.deepClone(initialDefaultState));
|
|
36
39
|
}
|
|
37
40
|
getSegmentation(segmentationId) {
|
|
@@ -158,7 +161,7 @@ export default class SegmentationStateManager {
|
|
|
158
161
|
}
|
|
159
162
|
}
|
|
160
163
|
_updateLabelmapSegmentationReferences(segmentationId, viewport, labelmapImageIds, updateCallback) {
|
|
161
|
-
const
|
|
164
|
+
const referenceImageId = viewport.getCurrentImageId();
|
|
162
165
|
let viewableLabelmapImageIdFound = false;
|
|
163
166
|
for (const labelmapImageId of labelmapImageIds) {
|
|
164
167
|
const viewableImageId = viewport.isReferenceViewable({ referencedImageId: labelmapImageId }, { asOverlay: true });
|
|
@@ -166,7 +169,12 @@ export default class SegmentationStateManager {
|
|
|
166
169
|
viewableLabelmapImageIdFound = true;
|
|
167
170
|
this._stackLabelmapImageIdReferenceMap
|
|
168
171
|
.get(segmentationId)
|
|
169
|
-
.set(
|
|
172
|
+
.set(referenceImageId, labelmapImageId);
|
|
173
|
+
this._updateLabelmapImageIdReferenceMap({
|
|
174
|
+
segmentationId,
|
|
175
|
+
referenceImageId,
|
|
176
|
+
labelmapImageId,
|
|
177
|
+
});
|
|
170
178
|
}
|
|
171
179
|
}
|
|
172
180
|
if (updateCallback) {
|
|
@@ -175,7 +183,7 @@ export default class SegmentationStateManager {
|
|
|
175
183
|
return viewableLabelmapImageIdFound
|
|
176
184
|
? this._stackLabelmapImageIdReferenceMap
|
|
177
185
|
.get(segmentationId)
|
|
178
|
-
.get(
|
|
186
|
+
.get(referenceImageId)
|
|
179
187
|
: undefined;
|
|
180
188
|
}
|
|
181
189
|
updateLabelmapSegmentationImageReferences(viewportId, segmentationId) {
|
|
@@ -212,13 +220,18 @@ export default class SegmentationStateManager {
|
|
|
212
220
|
const stackViewport = enabledElement.viewport;
|
|
213
221
|
this._updateLabelmapSegmentationReferences(segmentationId, stackViewport, labelmapImageIds, (stackViewport, segmentationId, labelmapImageIds) => {
|
|
214
222
|
const imageIds = stackViewport.getImageIds();
|
|
215
|
-
imageIds.forEach((
|
|
223
|
+
imageIds.forEach((referenceImageId, index) => {
|
|
216
224
|
for (const labelmapImageId of labelmapImageIds) {
|
|
217
225
|
const viewableImageId = stackViewport.isReferenceViewable({ referencedImageId: labelmapImageId, sliceIndex: index }, { asOverlay: true, withNavigation: true });
|
|
218
226
|
if (viewableImageId) {
|
|
219
227
|
this._stackLabelmapImageIdReferenceMap
|
|
220
228
|
.get(segmentationId)
|
|
221
|
-
.set(
|
|
229
|
+
.set(referenceImageId, labelmapImageId);
|
|
230
|
+
this._updateLabelmapImageIdReferenceMap({
|
|
231
|
+
segmentationId,
|
|
232
|
+
referenceImageId,
|
|
233
|
+
labelmapImageId,
|
|
234
|
+
});
|
|
222
235
|
}
|
|
223
236
|
}
|
|
224
237
|
});
|
|
@@ -240,6 +253,19 @@ export default class SegmentationStateManager {
|
|
|
240
253
|
}
|
|
241
254
|
return labelmapImageIds;
|
|
242
255
|
}
|
|
256
|
+
getCurrentLabelmapImageIdsForViewport(viewportId, segmentationId) {
|
|
257
|
+
const enabledElement = getEnabledElementByViewportId(viewportId);
|
|
258
|
+
if (!enabledElement) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const stackViewport = enabledElement.viewport;
|
|
262
|
+
const referenceImageId = stackViewport.getCurrentImageId();
|
|
263
|
+
const key = this._generateMapKey({
|
|
264
|
+
segmentationId,
|
|
265
|
+
referenceImageId,
|
|
266
|
+
});
|
|
267
|
+
return this._labelmapImageIdReferenceMap.get(key);
|
|
268
|
+
}
|
|
243
269
|
getCurrentLabelmapImageIdForViewport(viewportId, segmentationId) {
|
|
244
270
|
const enabledElement = getEnabledElementByViewportId(viewportId);
|
|
245
271
|
if (!enabledElement) {
|
|
@@ -330,6 +356,16 @@ export default class SegmentationStateManager {
|
|
|
330
356
|
}
|
|
331
357
|
return removedRepresentations;
|
|
332
358
|
}
|
|
359
|
+
_updateLabelmapImageIdReferenceMap({ segmentationId, referenceImageId, labelmapImageId, }) {
|
|
360
|
+
const key = this._generateMapKey({ segmentationId, referenceImageId });
|
|
361
|
+
if (!this._labelmapImageIdReferenceMap.has(key)) {
|
|
362
|
+
this._labelmapImageIdReferenceMap.set(key, [labelmapImageId]);
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
const currentValues = this._labelmapImageIdReferenceMap.get(key);
|
|
366
|
+
const newValues = Array.from(new Set([...currentValues, labelmapImageId]));
|
|
367
|
+
this._labelmapImageIdReferenceMap.set(key, newValues);
|
|
368
|
+
}
|
|
333
369
|
_setActiveSegmentation(state, viewportId, segmentationId) {
|
|
334
370
|
const viewport = state.viewportSegRepresentations[viewportId];
|
|
335
371
|
if (!viewport) {
|
|
@@ -435,6 +471,9 @@ export default class SegmentationStateManager {
|
|
|
435
471
|
});
|
|
436
472
|
return result;
|
|
437
473
|
}
|
|
474
|
+
_generateMapKey({ segmentationId, referenceImageId }) {
|
|
475
|
+
return `${segmentationId}-${referenceImageId}`;
|
|
476
|
+
}
|
|
438
477
|
}
|
|
439
478
|
async function internalComputeVolumeLabelmapFromStack({ imageIds, options, }) {
|
|
440
479
|
const segmentationImageIds = imageIds;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { defaultSegmentationStateManager } from './SegmentationStateManager';
|
|
2
2
|
export function getCurrentLabelmapImageIdForViewport(viewportId, segmentationId) {
|
|
3
|
+
const imageIds = getCurrentLabelmapImageIdsForViewport(viewportId, segmentationId);
|
|
4
|
+
return imageIds[0];
|
|
5
|
+
}
|
|
6
|
+
export function getCurrentLabelmapImageIdsForViewport(viewportId, segmentationId) {
|
|
3
7
|
const segmentationStateManager = defaultSegmentationStateManager;
|
|
4
|
-
return segmentationStateManager.
|
|
8
|
+
return segmentationStateManager.getCurrentLabelmapImageIdsForViewport(viewportId, segmentationId);
|
|
5
9
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Types } from '@cornerstonejs/core';
|
|
2
2
|
export declare function getLabelmapActorUID(viewportId: string, segmentationId: string): string | undefined;
|
|
3
|
+
export declare function getLabelmapActorEntries(viewportId: string, segmentationId: string): Types.ActorEntry[];
|
|
3
4
|
export declare function getLabelmapActorEntry(viewportId: string, segmentationId: string): Types.ActorEntry;
|
|
4
5
|
export declare function getSurfaceActorEntry(viewportId: string, segmentationId: string, segmentIndex?: number | string): Types.ActorEntry;
|
|
5
6
|
export declare function getSurfaceActorUID(viewportId: string, segmentationId: string, segmentIndex?: number | string): string | undefined;
|
|
@@ -13,10 +13,26 @@ function getActorEntry(viewportId, segmentationId, filterFn) {
|
|
|
13
13
|
const filteredActors = actors.filter(filterFn);
|
|
14
14
|
return filteredActors.length > 0 ? filteredActors[0] : undefined;
|
|
15
15
|
}
|
|
16
|
+
function getActorEntries(viewportId, filterFn) {
|
|
17
|
+
const enabledElement = getEnabledElementByViewportId(viewportId);
|
|
18
|
+
if (!enabledElement) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const { renderingEngine, viewport } = enabledElement;
|
|
22
|
+
if (!renderingEngine || !viewport) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const actors = viewport.getActors();
|
|
26
|
+
const filteredActors = actors.filter(filterFn);
|
|
27
|
+
return filteredActors.length > 0 ? filteredActors : undefined;
|
|
28
|
+
}
|
|
16
29
|
export function getLabelmapActorUID(viewportId, segmentationId) {
|
|
17
30
|
const actorEntry = getLabelmapActorEntry(viewportId, segmentationId);
|
|
18
31
|
return actorEntry?.uid;
|
|
19
32
|
}
|
|
33
|
+
export function getLabelmapActorEntries(viewportId, segmentationId) {
|
|
34
|
+
return getActorEntries(viewportId, (actor) => actor.representationUID?.startsWith(`${segmentationId}-${SegmentationRepresentations.Labelmap}`));
|
|
35
|
+
}
|
|
20
36
|
export function getLabelmapActorEntry(viewportId, segmentationId) {
|
|
21
37
|
return getActorEntry(viewportId, segmentationId, (actor) => actor.representationUID?.startsWith(`${segmentationId}-${SegmentationRepresentations.Labelmap}`));
|
|
22
38
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import validateSegmentationInput from './validateSegmentationInput';
|
|
2
|
-
import { getLabelmapActorEntry, getSurfaceActorEntry, getLabelmapActorUID, getSurfaceActorUID } from './getSegmentationActor';
|
|
3
|
-
export { validateSegmentationInput, getLabelmapActorEntry, getSurfaceActorEntry, getLabelmapActorUID, getSurfaceActorUID, };
|
|
2
|
+
import { getLabelmapActorEntries, getLabelmapActorEntry, getSurfaceActorEntry, getLabelmapActorUID, getSurfaceActorUID } from './getSegmentationActor';
|
|
3
|
+
export { validateSegmentationInput, getLabelmapActorEntries, getLabelmapActorEntry, getSurfaceActorEntry, getLabelmapActorUID, getSurfaceActorUID, };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import validateSegmentationInput from './validateSegmentationInput';
|
|
2
|
-
import { getLabelmapActorEntry, getSurfaceActorEntry, getLabelmapActorUID, getSurfaceActorUID, } from './getSegmentationActor';
|
|
3
|
-
export { validateSegmentationInput, getLabelmapActorEntry, getSurfaceActorEntry, getLabelmapActorUID, getSurfaceActorUID, };
|
|
2
|
+
import { getLabelmapActorEntries, getLabelmapActorEntry, getSurfaceActorEntry, getLabelmapActorUID, getSurfaceActorUID, } from './getSegmentationActor';
|
|
3
|
+
export { validateSegmentationInput, getLabelmapActorEntries, getLabelmapActorEntry, getSurfaceActorEntry, getLabelmapActorUID, getSurfaceActorUID, };
|
|
@@ -9,9 +9,9 @@ import { getNextColorLUTIndex } from './getNextColorLUTIndex';
|
|
|
9
9
|
import { removeColorLUT } from './removeColorLUT';
|
|
10
10
|
import { getViewportSegmentations } from './getViewportSegmentations';
|
|
11
11
|
import { getViewportIdsWithSegmentation } from './getViewportIdsWithSegmentation';
|
|
12
|
-
import { getCurrentLabelmapImageIdForViewport } from './getCurrentLabelmapImageIdForViewport';
|
|
12
|
+
import { getCurrentLabelmapImageIdForViewport, getCurrentLabelmapImageIdsForViewport } from './getCurrentLabelmapImageIdForViewport';
|
|
13
13
|
import { updateLabelmapSegmentationImageReferences } from './updateLabelmapSegmentationImageReferences';
|
|
14
14
|
import { getStackSegmentationImageIdsForViewport } from './getStackSegmentationImageIdsForViewport';
|
|
15
15
|
import { getSegmentationRepresentation, getSegmentationRepresentations, getSegmentationRepresentationsBySegmentationId } from './getSegmentationRepresentation';
|
|
16
16
|
declare function destroy(): void;
|
|
17
|
-
export { getColorLUT, getCurrentLabelmapImageIdForViewport, getNextColorLUTIndex, getSegmentation, getSegmentations, getStackSegmentationImageIdsForViewport, getViewportIdsWithSegmentation, getSegmentationRepresentation, getSegmentationRepresentations, removeColorLUT, getViewportSegmentations, removeSegmentation, removeLabelmapRepresentation, removeContourRepresentation, removeSurfaceRepresentation, removeSegmentationRepresentation, removeAllSegmentationRepresentations, removeAllSegmentations, addColorLUT, addSegmentations, updateLabelmapSegmentationImageReferences, getSegmentationRepresentationsBySegmentationId, destroy, };
|
|
17
|
+
export { getColorLUT, getCurrentLabelmapImageIdForViewport, getCurrentLabelmapImageIdsForViewport, getNextColorLUTIndex, getSegmentation, getSegmentations, getStackSegmentationImageIdsForViewport, getViewportIdsWithSegmentation, getSegmentationRepresentation, getSegmentationRepresentations, removeColorLUT, getViewportSegmentations, removeSegmentation, removeLabelmapRepresentation, removeContourRepresentation, removeSurfaceRepresentation, removeSegmentationRepresentation, removeAllSegmentationRepresentations, removeAllSegmentations, addColorLUT, addSegmentations, updateLabelmapSegmentationImageReferences, getSegmentationRepresentationsBySegmentationId, destroy, };
|
|
@@ -9,7 +9,7 @@ import { getNextColorLUTIndex } from './getNextColorLUTIndex';
|
|
|
9
9
|
import { removeColorLUT } from './removeColorLUT';
|
|
10
10
|
import { getViewportSegmentations } from './getViewportSegmentations';
|
|
11
11
|
import { getViewportIdsWithSegmentation } from './getViewportIdsWithSegmentation';
|
|
12
|
-
import { getCurrentLabelmapImageIdForViewport } from './getCurrentLabelmapImageIdForViewport';
|
|
12
|
+
import { getCurrentLabelmapImageIdForViewport, getCurrentLabelmapImageIdsForViewport, } from './getCurrentLabelmapImageIdForViewport';
|
|
13
13
|
import { updateLabelmapSegmentationImageReferences } from './updateLabelmapSegmentationImageReferences';
|
|
14
14
|
import { getStackSegmentationImageIdsForViewport } from './getStackSegmentationImageIdsForViewport';
|
|
15
15
|
import { getSegmentationRepresentation, getSegmentationRepresentations, getSegmentationRepresentationsBySegmentationId, } from './getSegmentationRepresentation';
|
|
@@ -17,4 +17,4 @@ import { defaultSegmentationStateManager } from './SegmentationStateManager';
|
|
|
17
17
|
function destroy() {
|
|
18
18
|
defaultSegmentationStateManager.resetState();
|
|
19
19
|
}
|
|
20
|
-
export { getColorLUT, getCurrentLabelmapImageIdForViewport, getNextColorLUTIndex, getSegmentation, getSegmentations, getStackSegmentationImageIdsForViewport, getViewportIdsWithSegmentation, getSegmentationRepresentation, getSegmentationRepresentations, removeColorLUT, getViewportSegmentations, removeSegmentation, removeLabelmapRepresentation, removeContourRepresentation, removeSurfaceRepresentation, removeSegmentationRepresentation, removeAllSegmentationRepresentations, removeAllSegmentations, addColorLUT, addSegmentations, updateLabelmapSegmentationImageReferences, getSegmentationRepresentationsBySegmentationId, destroy, };
|
|
20
|
+
export { getColorLUT, getCurrentLabelmapImageIdForViewport, getCurrentLabelmapImageIdsForViewport, getNextColorLUTIndex, getSegmentation, getSegmentations, getStackSegmentationImageIdsForViewport, getViewportIdsWithSegmentation, getSegmentationRepresentation, getSegmentationRepresentations, removeColorLUT, getViewportSegmentations, removeSegmentation, removeLabelmapRepresentation, removeContourRepresentation, removeSurfaceRepresentation, removeSegmentationRepresentation, removeAllSegmentationRepresentations, removeAllSegmentations, addColorLUT, addSegmentations, updateLabelmapSegmentationImageReferences, getSegmentationRepresentationsBySegmentationId, destroy, };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getEnabledElement, addVolumesToViewports, addImageSlicesToViewports, Enums, cache, BaseVolumeViewport, volumeLoader, utilities, } from '@cornerstonejs/core';
|
|
2
|
-
import {
|
|
2
|
+
import { getCurrentLabelmapImageIdsForViewport } from '../../../stateManagement/segmentation/getCurrentLabelmapImageIdForViewport';
|
|
3
3
|
import { getSegmentation } from '../../../stateManagement/segmentation/getSegmentation';
|
|
4
4
|
import { triggerSegmentationDataModified, triggerSegmentationModified, } from '../../../stateManagement/segmentation/triggerSegmentationEvents';
|
|
5
5
|
import { SegmentationRepresentations } from '../../../enums';
|
|
@@ -56,13 +56,11 @@ async function addLabelmapToElement(element, labelMapData, segmentationId, confi
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
else {
|
|
59
|
-
const
|
|
60
|
-
const stackInputs =
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
},
|
|
65
|
-
];
|
|
59
|
+
const segmentationImageIds = getCurrentLabelmapImageIdsForViewport(viewport.id, segmentationId);
|
|
60
|
+
const stackInputs = segmentationImageIds.map((imageId) => ({
|
|
61
|
+
imageId,
|
|
62
|
+
representationUID: `${segmentationId}-${SegmentationRepresentations.Labelmap}-${imageId}`,
|
|
63
|
+
}));
|
|
66
64
|
addImageSlicesToViewports(renderingEngine, stackInputs, [viewportId]);
|
|
67
65
|
}
|
|
68
66
|
triggerSegmentationDataModified(segmentationId);
|
|
@@ -3,13 +3,13 @@ import addLabelmapToElement from './addLabelmapToElement';
|
|
|
3
3
|
import removeLabelmapFromElement from './removeLabelmapFromElement';
|
|
4
4
|
import { getActiveSegmentation } from '../../../stateManagement/segmentation/activeSegmentation';
|
|
5
5
|
import { getColorLUT } from '../../../stateManagement/segmentation/getColorLUT';
|
|
6
|
-
import {
|
|
6
|
+
import { getCurrentLabelmapImageIdsForViewport } from '../../../stateManagement/segmentation/getCurrentLabelmapImageIdForViewport';
|
|
7
7
|
import { getSegmentation } from '../../../stateManagement/segmentation/getSegmentation';
|
|
8
8
|
import { segmentationStyle } from '../../../stateManagement/segmentation/SegmentationStyle';
|
|
9
9
|
import SegmentationRepresentations from '../../../enums/SegmentationRepresentations';
|
|
10
10
|
import { internalGetHiddenSegmentIndices } from '../../../stateManagement/segmentation/helpers/internalGetHiddenSegmentIndices';
|
|
11
11
|
import { getActiveSegmentIndex } from '../../../stateManagement/segmentation/getActiveSegmentIndex';
|
|
12
|
-
import {
|
|
12
|
+
import { getLabelmapActorEntries } from '../../../stateManagement/segmentation/helpers/getSegmentationActor';
|
|
13
13
|
import { getPolySeg } from '../../../config';
|
|
14
14
|
import { computeAndAddRepresentation } from '../../../utilities/segmentation/computeAndAddRepresentation';
|
|
15
15
|
import { triggerSegmentationDataModified } from '../../../stateManagement/segmentation/triggerSegmentationEvents';
|
|
@@ -42,7 +42,7 @@ async function render(viewport, representation) {
|
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
44
|
let labelmapData = segmentation.representationData[SegmentationRepresentations.Labelmap];
|
|
45
|
-
let
|
|
45
|
+
let labelmapActorEntries = getLabelmapActorEntries(viewport.id, segmentationId);
|
|
46
46
|
if (!labelmapData &&
|
|
47
47
|
getPolySeg()?.canComputeRequestedRepresentation(segmentationId, SegmentationRepresentations.Labelmap) &&
|
|
48
48
|
!polySegConversionInProgress) {
|
|
@@ -66,25 +66,27 @@ async function render(viewport, representation) {
|
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
68
68
|
if (viewport instanceof VolumeViewport) {
|
|
69
|
-
if (!
|
|
69
|
+
if (!labelmapActorEntries?.length) {
|
|
70
70
|
await _addLabelmapToViewport(viewport, labelmapData, segmentationId, config);
|
|
71
71
|
}
|
|
72
|
-
|
|
72
|
+
labelmapActorEntries = getLabelmapActorEntries(viewport.id, segmentationId);
|
|
73
73
|
}
|
|
74
74
|
else {
|
|
75
|
-
const
|
|
76
|
-
if (!
|
|
75
|
+
const labelmapImageIds = getCurrentLabelmapImageIdsForViewport(viewport.id, segmentationId);
|
|
76
|
+
if (!labelmapImageIds?.length) {
|
|
77
77
|
return;
|
|
78
78
|
}
|
|
79
|
-
if (!
|
|
79
|
+
if (!labelmapActorEntries) {
|
|
80
80
|
await _addLabelmapToViewport(viewport, labelmapData, segmentationId, config);
|
|
81
81
|
}
|
|
82
|
-
|
|
82
|
+
labelmapActorEntries = getLabelmapActorEntries(viewport.id, segmentationId);
|
|
83
83
|
}
|
|
84
|
-
if (!
|
|
84
|
+
if (!labelmapActorEntries?.length) {
|
|
85
85
|
return;
|
|
86
86
|
}
|
|
87
|
-
|
|
87
|
+
for (const labelmapActorEntry of labelmapActorEntries) {
|
|
88
|
+
_setLabelmapColorAndOpacity(viewport.id, labelmapActorEntry, representation);
|
|
89
|
+
}
|
|
88
90
|
}
|
|
89
91
|
function _setLabelmapColorAndOpacity(viewportId, labelmapActorEntry, segmentationRepresentation) {
|
|
90
92
|
const { segmentationId } = segmentationRepresentation;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseVolumeViewport, cache, utilities } from '@cornerstonejs/core';
|
|
2
2
|
import { SegmentationRepresentations } from '../../enums';
|
|
3
|
-
import { getSegmentation,
|
|
3
|
+
import { getSegmentation, getCurrentLabelmapImageIdsForViewport, } from '../../stateManagement/segmentation/segmentationState';
|
|
4
4
|
import { getAnnotation } from '../../stateManagement';
|
|
5
5
|
import { isPointInsidePolyline3D } from '../math/polyline';
|
|
6
6
|
import { getLabelmapActorEntry } from '../../stateManagement/segmentation/helpers/getSegmentationActor';
|
|
@@ -31,7 +31,12 @@ export function getSegmentIndexAtWorldForLabelmap(segmentation, worldPoint, { vi
|
|
|
31
31
|
const segmentIndex = segmentationVolume.imageData.getScalarValueFromWorld(worldPoint);
|
|
32
32
|
return segmentIndex;
|
|
33
33
|
}
|
|
34
|
-
const
|
|
34
|
+
const segmentationImageIds = getCurrentLabelmapImageIdsForViewport(viewport.id, segmentation.segmentationId);
|
|
35
|
+
if (segmentationImageIds.length > 1) {
|
|
36
|
+
console.warn('Segment selection for labelmaps with multiple imageIds in stack viewports is not supported yet.');
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const segmentationImageId = segmentationImageIds[0];
|
|
35
40
|
const image = cache.getImage(segmentationImageId);
|
|
36
41
|
if (!image) {
|
|
37
42
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/tools",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "Cornerstone3D Tools",
|
|
5
5
|
"types": "./dist/esm/index.d.ts",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"canvas": "^2.11.2"
|
|
104
104
|
},
|
|
105
105
|
"peerDependencies": {
|
|
106
|
-
"@cornerstonejs/core": "^3.
|
|
106
|
+
"@cornerstonejs/core": "^3.4.0",
|
|
107
107
|
"@kitware/vtk.js": "32.9.0",
|
|
108
108
|
"@types/d3-array": "^3.0.4",
|
|
109
109
|
"@types/d3-interpolate": "^3.0.1",
|
|
@@ -122,5 +122,5 @@
|
|
|
122
122
|
"type": "individual",
|
|
123
123
|
"url": "https://ohif.org/donate"
|
|
124
124
|
},
|
|
125
|
-
"gitHead": "
|
|
125
|
+
"gitHead": "822b0c3f30dc9d1d9a5e638f099ce463c689ee14"
|
|
126
126
|
}
|