@cornerstonejs/tools 3.7.17 → 3.8.1
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/enums/Events.d.ts +2 -0
- package/dist/esm/enums/Events.js +2 -0
- package/dist/esm/stateManagement/segmentation/SegmentationStateManager.d.ts +1 -0
- package/dist/esm/stateManagement/segmentation/SegmentationStateManager.js +8 -5
- package/dist/esm/stateManagement/segmentation/config/segmentationColor.js +2 -1
- package/dist/esm/stateManagement/segmentation/getCurrentLabelmapImageIdForViewport.d.ts +1 -0
- package/dist/esm/stateManagement/segmentation/getCurrentLabelmapImageIdForViewport.js +4 -0
- package/dist/esm/stateManagement/segmentation/index.d.ts +3 -1
- package/dist/esm/stateManagement/segmentation/index.js +3 -1
- package/dist/esm/tools/base/AnnotationTool.d.ts +2 -0
- package/dist/esm/tools/base/AnnotationTool.js +2 -0
- package/dist/esm/tools/segmentation/BrushTool.d.ts +1 -1
- package/dist/esm/tools/segmentation/BrushTool.js +45 -17
- package/dist/esm/tools/segmentation/LabelmapBaseTool.d.ts +15 -2
- package/dist/esm/tools/segmentation/LabelmapBaseTool.js +69 -16
- package/dist/esm/tools/segmentation/strategies/BrushStrategy.d.ts +8 -4
- package/dist/esm/tools/segmentation/strategies/BrushStrategy.js +8 -30
- package/dist/esm/tools/segmentation/strategies/compositions/determineSegmentIndex.d.ts +0 -1
- package/dist/esm/tools/segmentation/strategies/compositions/determineSegmentIndex.js +6 -25
- package/dist/esm/tools/segmentation/strategies/compositions/index.d.ts +0 -1
- package/dist/esm/tools/segmentation/strategies/compositions/islandRemovalComposition.js +2 -2
- package/dist/esm/tools/segmentation/strategies/compositions/preview.js +38 -46
- package/dist/esm/tools/segmentation/strategies/compositions/regionFill.js +2 -2
- package/dist/esm/tools/segmentation/strategies/compositions/setValue.js +23 -17
- package/dist/esm/tools/segmentation/strategies/utils/getStrategyData.js +3 -0
- package/dist/esm/tools/segmentation/strategies/utils/handleUseSegmentCenterIndex.d.ts +5 -0
- package/dist/esm/tools/segmentation/strategies/utils/handleUseSegmentCenterIndex.js +84 -0
- package/dist/esm/types/LabelmapToolOperationData.d.ts +1 -1
- package/dist/esm/utilities/segmentation/createLabelmapMemo.d.ts +6 -19
- package/dist/esm/utilities/segmentation/createLabelmapMemo.js +6 -18
- package/dist/esm/utilities/segmentation/islandRemoval.js +2 -2
- package/package.json +3 -3
|
@@ -22,6 +22,8 @@ declare enum Events {
|
|
|
22
22
|
SEGMENTATION_REMOVED = "CORNERSTONE_TOOLS_SEGMENTATION_REMOVED",
|
|
23
23
|
SEGMENTATION_REPRESENTATION_REMOVED = "CORNERSTONE_TOOLS_SEGMENTATION_REPRESENTATION_REMOVED",
|
|
24
24
|
SEGMENTATION_DATA_MODIFIED = "CORNERSTONE_TOOLS_SEGMENTATION_DATA_MODIFIED",
|
|
25
|
+
HISTORY_UNDO = "CORNERSTONE_TOOLS_HISTORY_UNDO",
|
|
26
|
+
HISTORY_REDO = "CORNERSTONE_TOOLS_HISTORY_REDO",
|
|
25
27
|
KEY_DOWN = "CORNERSTONE_TOOLS_KEY_DOWN",
|
|
26
28
|
KEY_UP = "CORNERSTONE_TOOLS_KEY_UP",
|
|
27
29
|
MOUSE_DOWN = "CORNERSTONE_TOOLS_MOUSE_DOWN",
|
package/dist/esm/enums/Events.js
CHANGED
|
@@ -23,6 +23,8 @@ var Events;
|
|
|
23
23
|
Events["SEGMENTATION_REMOVED"] = "CORNERSTONE_TOOLS_SEGMENTATION_REMOVED";
|
|
24
24
|
Events["SEGMENTATION_REPRESENTATION_REMOVED"] = "CORNERSTONE_TOOLS_SEGMENTATION_REPRESENTATION_REMOVED";
|
|
25
25
|
Events["SEGMENTATION_DATA_MODIFIED"] = "CORNERSTONE_TOOLS_SEGMENTATION_DATA_MODIFIED";
|
|
26
|
+
Events["HISTORY_UNDO"] = "CORNERSTONE_TOOLS_HISTORY_UNDO";
|
|
27
|
+
Events["HISTORY_REDO"] = "CORNERSTONE_TOOLS_HISTORY_REDO";
|
|
26
28
|
Events["KEY_DOWN"] = "CORNERSTONE_TOOLS_KEY_DOWN";
|
|
27
29
|
Events["KEY_UP"] = "CORNERSTONE_TOOLS_KEY_UP";
|
|
28
30
|
Events["MOUSE_DOWN"] = "CORNERSTONE_TOOLS_MOUSE_DOWN";
|
|
@@ -24,6 +24,7 @@ export default class SegmentationStateManager {
|
|
|
24
24
|
updateLabelmapSegmentationImageReferences(viewportId: any, segmentationId: any): string;
|
|
25
25
|
_updateAllLabelmapSegmentationImageReferences(viewportId: any, segmentationId: any): void;
|
|
26
26
|
getLabelmapImageIds(representationData: RepresentationsData): any;
|
|
27
|
+
getLabelmapImageIdsForImageId(imageId: string, segmentationId: string): string[];
|
|
27
28
|
getCurrentLabelmapImageIdsForViewport(viewportId: string, segmentationId: string): string[] | undefined;
|
|
28
29
|
getCurrentLabelmapImageIdForViewport(viewportId: string, segmentationId: string): string | undefined;
|
|
29
30
|
getStackSegmentationImageIdsForViewport(viewportId: string, segmentationId: string): string[];
|
|
@@ -253,6 +253,13 @@ export default class SegmentationStateManager {
|
|
|
253
253
|
}
|
|
254
254
|
return labelmapImageIds;
|
|
255
255
|
}
|
|
256
|
+
getLabelmapImageIdsForImageId(imageId, segmentationId) {
|
|
257
|
+
const key = this._generateMapKey({
|
|
258
|
+
segmentationId,
|
|
259
|
+
referenceImageId: imageId,
|
|
260
|
+
});
|
|
261
|
+
return this._labelmapImageIdReferenceMap.get(key);
|
|
262
|
+
}
|
|
256
263
|
getCurrentLabelmapImageIdsForViewport(viewportId, segmentationId) {
|
|
257
264
|
const enabledElement = getEnabledElementByViewportId(viewportId);
|
|
258
265
|
if (!enabledElement) {
|
|
@@ -260,11 +267,7 @@ export default class SegmentationStateManager {
|
|
|
260
267
|
}
|
|
261
268
|
const stackViewport = enabledElement.viewport;
|
|
262
269
|
const referenceImageId = stackViewport.getCurrentImageId();
|
|
263
|
-
|
|
264
|
-
segmentationId,
|
|
265
|
-
referenceImageId,
|
|
266
|
-
});
|
|
267
|
-
return this._labelmapImageIdReferenceMap.get(key);
|
|
270
|
+
return this.getLabelmapImageIdsForImageId(referenceImageId, segmentationId);
|
|
268
271
|
}
|
|
269
272
|
getCurrentLabelmapImageIdForViewport(viewportId, segmentationId) {
|
|
270
273
|
const enabledElement = getEnabledElementByViewportId(viewportId);
|
|
@@ -34,7 +34,8 @@ function getSegmentIndexColor(viewportId, segmentationId, segmentIndex) {
|
|
|
34
34
|
let colorValue = colorLUT[segmentIndex];
|
|
35
35
|
if (!colorValue) {
|
|
36
36
|
if (typeof segmentIndex !== 'number') {
|
|
37
|
-
|
|
37
|
+
console.warn(`Can't create colour for LUT index ${segmentIndex}`);
|
|
38
|
+
return null;
|
|
38
39
|
}
|
|
39
40
|
colorValue = colorLUT[segmentIndex] = [0, 0, 0, 0];
|
|
40
41
|
}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export declare function getCurrentLabelmapImageIdForViewport(viewportId: string, segmentationId: string): string;
|
|
2
2
|
export declare function getCurrentLabelmapImageIdsForViewport(viewportId: string, segmentationId: string): string[];
|
|
3
|
+
export declare function getLabelmapImageIdsForImageId(imageId: string, segmentationId: string): string[];
|
|
@@ -7,3 +7,7 @@ export function getCurrentLabelmapImageIdsForViewport(viewportId, segmentationId
|
|
|
7
7
|
const segmentationStateManager = defaultSegmentationStateManager;
|
|
8
8
|
return segmentationStateManager.getCurrentLabelmapImageIdsForViewport(viewportId, segmentationId);
|
|
9
9
|
}
|
|
10
|
+
export function getLabelmapImageIdsForImageId(imageId, segmentationId) {
|
|
11
|
+
const segmentationStateManager = defaultSegmentationStateManager;
|
|
12
|
+
return segmentationStateManager.getLabelmapImageIdsForImageId(imageId, segmentationId);
|
|
13
|
+
}
|
|
@@ -19,10 +19,12 @@ import * as strategies from './../../tools/segmentation/strategies';
|
|
|
19
19
|
import { removeAllSegmentations, removeSegmentation } from './removeSegmentation';
|
|
20
20
|
import { segmentationStyle } from './SegmentationStyle';
|
|
21
21
|
import { defaultSegmentationStateManager } from './SegmentationStateManager';
|
|
22
|
+
import { getCurrentLabelmapImageIdsForViewport, getLabelmapImageIdsForImageId } from './getCurrentLabelmapImageIdForViewport';
|
|
23
|
+
import { getActiveSegmentation } from './getActiveSegmentation';
|
|
22
24
|
declare const helpers: {
|
|
23
25
|
clearSegmentValue: typeof clearSegmentValue;
|
|
24
26
|
convertStackToVolumeLabelmap: typeof convertStackToVolumeLabelmap;
|
|
25
27
|
computeVolumeLabelmapFromStack: typeof computeVolumeLabelmapFromStack;
|
|
26
28
|
convertVolumeToStackLabelmap: typeof convertVolumeToStackLabelmap;
|
|
27
29
|
};
|
|
28
|
-
export { removeSegmentationRepresentation, removeContourRepresentation, removeLabelmapRepresentation, removeSurfaceRepresentation, removeAllSegmentations, removeSegmentation, removeSegmentationRepresentations, addLabelmapRepresentationToViewport, addLabelmapRepresentationToViewportMap, addSegmentationRepresentations, removeAllSegmentationRepresentations, addContourRepresentationToViewport, addContourRepresentationToViewportMap, addSurfaceRepresentationToViewport, addSurfaceRepresentationToViewportMap, addSegmentations, updateSegmentations, state, activeSegmentation, segmentLocking, config, segmentIndex, triggerSegmentationEvents, helpers, removeSegment, getLabelmapImageIds, addRepresentationData, strategies, segmentationStyle, defaultSegmentationStateManager, };
|
|
30
|
+
export { removeSegmentationRepresentation, removeContourRepresentation, removeLabelmapRepresentation, removeSurfaceRepresentation, removeAllSegmentations, removeSegmentation, removeSegmentationRepresentations, addLabelmapRepresentationToViewport, addLabelmapRepresentationToViewportMap, addSegmentationRepresentations, removeAllSegmentationRepresentations, addContourRepresentationToViewport, addContourRepresentationToViewportMap, addSurfaceRepresentationToViewport, addSurfaceRepresentationToViewportMap, addSegmentations, updateSegmentations, state, activeSegmentation, segmentLocking, config, segmentIndex, triggerSegmentationEvents, helpers, removeSegment, getLabelmapImageIds, addRepresentationData, strategies, segmentationStyle, defaultSegmentationStateManager, getCurrentLabelmapImageIdsForViewport, getLabelmapImageIdsForImageId, getActiveSegmentation, };
|
|
@@ -19,10 +19,12 @@ import * as strategies from './../../tools/segmentation/strategies';
|
|
|
19
19
|
import { removeAllSegmentations, removeSegmentation, } from './removeSegmentation';
|
|
20
20
|
import { segmentationStyle } from './SegmentationStyle';
|
|
21
21
|
import { defaultSegmentationStateManager } from './SegmentationStateManager';
|
|
22
|
+
import { getCurrentLabelmapImageIdsForViewport, getLabelmapImageIdsForImageId, } from './getCurrentLabelmapImageIdForViewport';
|
|
23
|
+
import { getActiveSegmentation } from './getActiveSegmentation';
|
|
22
24
|
const helpers = {
|
|
23
25
|
clearSegmentValue,
|
|
24
26
|
convertStackToVolumeLabelmap,
|
|
25
27
|
computeVolumeLabelmapFromStack,
|
|
26
28
|
convertVolumeToStackLabelmap,
|
|
27
29
|
};
|
|
28
|
-
export { removeSegmentationRepresentation, removeContourRepresentation, removeLabelmapRepresentation, removeSurfaceRepresentation, removeAllSegmentations, removeSegmentation, removeSegmentationRepresentations, addLabelmapRepresentationToViewport, addLabelmapRepresentationToViewportMap, addSegmentationRepresentations, removeAllSegmentationRepresentations, addContourRepresentationToViewport, addContourRepresentationToViewportMap, addSurfaceRepresentationToViewport, addSurfaceRepresentationToViewportMap, addSegmentations, updateSegmentations, state, activeSegmentation, segmentLocking, config, segmentIndex, triggerSegmentationEvents, helpers, removeSegment, getLabelmapImageIds, addRepresentationData, strategies, segmentationStyle, defaultSegmentationStateManager, };
|
|
30
|
+
export { removeSegmentationRepresentation, removeContourRepresentation, removeLabelmapRepresentation, removeSurfaceRepresentation, removeAllSegmentations, removeSegmentation, removeSegmentationRepresentations, addLabelmapRepresentationToViewport, addLabelmapRepresentationToViewportMap, addSegmentationRepresentations, removeAllSegmentationRepresentations, addContourRepresentationToViewport, addContourRepresentationToViewportMap, addSurfaceRepresentationToViewport, addSurfaceRepresentationToViewportMap, addSegmentations, updateSegmentations, state, activeSegmentation, segmentLocking, config, segmentIndex, triggerSegmentationEvents, helpers, removeSegment, getLabelmapImageIds, addRepresentationData, strategies, segmentationStyle, defaultSegmentationStateManager, getCurrentLabelmapImageIdsForViewport, getLabelmapImageIdsForImageId, getActiveSegmentation, };
|
|
@@ -53,6 +53,8 @@ declare abstract class AnnotationTool extends AnnotationDisplayTool {
|
|
|
53
53
|
deleting?: boolean;
|
|
54
54
|
}): {
|
|
55
55
|
restoreMemo: () => void;
|
|
56
|
+
id: string;
|
|
57
|
+
operationType: string;
|
|
56
58
|
};
|
|
57
59
|
protected createMemo(element: any, annotation: any, options?: any): void;
|
|
58
60
|
protected static hydrateBase<T extends AnnotationTool>(ToolClass: new () => T, enabledElement: Types.IEnabledElement, points: Types.Point3[], options?: {
|
|
@@ -259,6 +259,8 @@ class AnnotationTool extends AnnotationDisplayTool {
|
|
|
259
259
|
currentAnnotation.invalidated = true;
|
|
260
260
|
triggerAnnotationModified(currentAnnotation, element, ChangeTypes.History);
|
|
261
261
|
},
|
|
262
|
+
id: annotationUID,
|
|
263
|
+
operationType: 'annotation',
|
|
262
264
|
};
|
|
263
265
|
DefaultHistoryMemo.push(annotationMemo);
|
|
264
266
|
return annotationMemo;
|
|
@@ -17,8 +17,8 @@ declare class BrushTool extends LabelmapBaseTool {
|
|
|
17
17
|
private _endCallback;
|
|
18
18
|
getStatistics(element: any, segmentIndices?: any): any;
|
|
19
19
|
rejectPreview(element?: HTMLDivElement): void;
|
|
20
|
-
interpolate(element: any, config: any): void;
|
|
21
20
|
acceptPreview(element?: HTMLDivElement): void;
|
|
21
|
+
interpolate(element: any, config: any): void;
|
|
22
22
|
private _activateDraw;
|
|
23
23
|
private _deactivateDraw;
|
|
24
24
|
invalidateBrushCursor(): void;
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { getEnabledElement } from '@cornerstonejs/core';
|
|
1
|
+
import { getEnabledElement, eventTarget } from '@cornerstonejs/core';
|
|
2
2
|
import { vec3, vec2 } from 'gl-matrix';
|
|
3
|
+
import { Events, ToolModes, StrategyCallbacks } from '../../enums';
|
|
3
4
|
import { fillInsideSphere, thresholdInsideSphere, thresholdInsideSphereIsland, } from './strategies/fillSphere';
|
|
4
5
|
import { eraseInsideSphere } from './strategies/eraseSphere';
|
|
5
6
|
import { thresholdInsideCircle, fillInsideCircle, } from './strategies/fillCircle';
|
|
6
7
|
import { eraseInsideCircle } from './strategies/eraseCircle';
|
|
7
|
-
import { Events, ToolModes, StrategyCallbacks } from '../../enums';
|
|
8
8
|
import { drawCircle as drawCircleSvg } from '../../drawingSvg';
|
|
9
9
|
import { resetElementCursor, hideElementCursor, } from '../../cursors/elementCursor';
|
|
10
10
|
import triggerAnnotationRenderForViewportUIDs from '../../utilities/triggerAnnotationRenderForViewportIds';
|
|
11
11
|
import LabelmapBaseTool from './LabelmapBaseTool';
|
|
12
|
+
import { getStrategyData } from './strategies/utils/getStrategyData';
|
|
12
13
|
class BrushTool extends LabelmapBaseTool {
|
|
13
14
|
constructor(toolProps = {}, defaultToolProps = {
|
|
14
15
|
supportedInteractionTypes: ['Mouse', 'Touch'],
|
|
@@ -25,6 +26,7 @@ class BrushTool extends LabelmapBaseTool {
|
|
|
25
26
|
defaultStrategy: 'FILL_INSIDE_CIRCLE',
|
|
26
27
|
activeStrategy: 'FILL_INSIDE_CIRCLE',
|
|
27
28
|
brushSize: 25,
|
|
29
|
+
useCenterSegmentIndex: false,
|
|
28
30
|
preview: {
|
|
29
31
|
enabled: false,
|
|
30
32
|
previewColors: {
|
|
@@ -112,7 +114,10 @@ class BrushTool extends LabelmapBaseTool {
|
|
|
112
114
|
const { previewTimeMs, previewMoveDistance, dragMoveDistance } = this.configuration.preview;
|
|
113
115
|
const { currentPoints, element } = evt.detail;
|
|
114
116
|
const { canvas } = currentPoints;
|
|
115
|
-
const {
|
|
117
|
+
const { startPoint, timer, timerStart, isDrag } = this._previewData;
|
|
118
|
+
if (isDrag) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
116
121
|
const delta = vec2.distance(canvas, startPoint);
|
|
117
122
|
const time = Date.now() - timerStart;
|
|
118
123
|
if (delta > previewMoveDistance ||
|
|
@@ -121,7 +126,7 @@ class BrushTool extends LabelmapBaseTool {
|
|
|
121
126
|
window.clearTimeout(timer);
|
|
122
127
|
this._previewData.timer = null;
|
|
123
128
|
}
|
|
124
|
-
if (
|
|
129
|
+
if (!isDrag) {
|
|
125
130
|
this.rejectPreview(element);
|
|
126
131
|
}
|
|
127
132
|
}
|
|
@@ -137,11 +142,32 @@ class BrushTool extends LabelmapBaseTool {
|
|
|
137
142
|
}
|
|
138
143
|
};
|
|
139
144
|
this.previewCallback = () => {
|
|
145
|
+
if (this._previewData.isDrag) {
|
|
146
|
+
this._previewData.timer = null;
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
140
149
|
this._previewData.timer = null;
|
|
141
|
-
|
|
150
|
+
const operationData = this.getOperationData(this._previewData.element);
|
|
151
|
+
const enabledElement = getEnabledElement(this._previewData.element);
|
|
152
|
+
if (!enabledElement) {
|
|
142
153
|
return;
|
|
143
154
|
}
|
|
144
|
-
|
|
155
|
+
const { viewport } = enabledElement;
|
|
156
|
+
const activeStrategy = this.configuration.activeStrategy;
|
|
157
|
+
const strategyData = getStrategyData({
|
|
158
|
+
operationData,
|
|
159
|
+
viewport,
|
|
160
|
+
strategy: activeStrategy,
|
|
161
|
+
});
|
|
162
|
+
if (!operationData) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const memo = this.createMemo(operationData.segmentationId, strategyData.segmentationVoxelManager);
|
|
166
|
+
this._previewData.preview = this.applyActiveStrategyCallback(getEnabledElement(this._previewData.element), {
|
|
167
|
+
...operationData,
|
|
168
|
+
...strategyData,
|
|
169
|
+
memo,
|
|
170
|
+
}, StrategyCallbacks.Preview);
|
|
145
171
|
};
|
|
146
172
|
this._dragCallback = (evt) => {
|
|
147
173
|
const eventData = evt.detail;
|
|
@@ -153,11 +179,14 @@ class BrushTool extends LabelmapBaseTool {
|
|
|
153
179
|
const delta = vec2.distance(currentPoints.canvas, this._previewData.startPoint);
|
|
154
180
|
const { dragTimeMs, dragMoveDistance } = this.configuration.preview;
|
|
155
181
|
if (!this._previewData.isDrag &&
|
|
156
|
-
this._previewData.preview &&
|
|
157
182
|
Date.now() - this._previewData.timerStart < dragTimeMs &&
|
|
158
183
|
delta < dragMoveDistance) {
|
|
159
184
|
return;
|
|
160
185
|
}
|
|
186
|
+
if (this._previewData.timer) {
|
|
187
|
+
window.clearTimeout(this._previewData.timer);
|
|
188
|
+
this._previewData.timer = null;
|
|
189
|
+
}
|
|
161
190
|
this._previewData.preview = this.applyActiveStrategy(enabledElement, this.getOperationData(element));
|
|
162
191
|
this._previewData.element = element;
|
|
163
192
|
this._previewData.timerStart = Date.now() + dragTimeMs;
|
|
@@ -171,8 +200,8 @@ class BrushTool extends LabelmapBaseTool {
|
|
|
171
200
|
const operationData = this.getOperationData(element);
|
|
172
201
|
if (!this._previewData.preview && !this._previewData.isDrag) {
|
|
173
202
|
this.applyActiveStrategy(enabledElement, operationData);
|
|
203
|
+
this.doneEditMemo();
|
|
174
204
|
}
|
|
175
|
-
this.doneEditMemo();
|
|
176
205
|
this._deactivateDraw(element);
|
|
177
206
|
resetElementCursor(element);
|
|
178
207
|
this.updateCursor(evt);
|
|
@@ -266,30 +295,28 @@ class BrushTool extends LabelmapBaseTool {
|
|
|
266
295
|
return stats;
|
|
267
296
|
}
|
|
268
297
|
rejectPreview(element = this._previewData.element) {
|
|
269
|
-
if (!element
|
|
298
|
+
if (!element) {
|
|
270
299
|
return;
|
|
271
300
|
}
|
|
301
|
+
this.doneEditMemo();
|
|
272
302
|
const enabledElement = getEnabledElement(element);
|
|
273
303
|
this.applyActiveStrategyCallback(enabledElement, this.getOperationData(element), StrategyCallbacks.RejectPreview);
|
|
274
304
|
this._previewData.preview = null;
|
|
275
305
|
this._previewData.isDrag = false;
|
|
276
306
|
}
|
|
277
|
-
|
|
307
|
+
acceptPreview(element = this._previewData.element) {
|
|
278
308
|
if (!element) {
|
|
279
309
|
return;
|
|
280
310
|
}
|
|
281
|
-
|
|
282
|
-
this._previewData.preview = this.applyActiveStrategyCallback(enabledElement, this.getOperationData(element), StrategyCallbacks.Interpolate, config.configuration);
|
|
283
|
-
this._previewData.isDrag = true;
|
|
311
|
+
super.acceptPreview(element);
|
|
284
312
|
}
|
|
285
|
-
|
|
313
|
+
interpolate(element, config) {
|
|
286
314
|
if (!element) {
|
|
287
315
|
return;
|
|
288
316
|
}
|
|
289
317
|
const enabledElement = getEnabledElement(element);
|
|
290
|
-
this.applyActiveStrategyCallback(enabledElement, this.getOperationData(element), StrategyCallbacks.
|
|
291
|
-
this._previewData.isDrag =
|
|
292
|
-
this._previewData.preview = null;
|
|
318
|
+
this._previewData.preview = this.applyActiveStrategyCallback(enabledElement, this.getOperationData(element), StrategyCallbacks.Interpolate, config.configuration);
|
|
319
|
+
this._previewData.isDrag = true;
|
|
293
320
|
}
|
|
294
321
|
invalidateBrushCursor() {
|
|
295
322
|
if (this._hoverData === undefined) {
|
|
@@ -339,6 +366,7 @@ class BrushTool extends LabelmapBaseTool {
|
|
|
339
366
|
const circleUID = '0';
|
|
340
367
|
drawCircleSvg(svgDrawingHelper, annotationUID, circleUID, center, radius, {
|
|
341
368
|
color,
|
|
369
|
+
lineDash: this.centerSegmentIndexInfo.segmentIndex === 0 ? [1, 2] : null,
|
|
342
370
|
});
|
|
343
371
|
const { dynamicRadiusInCanvas } = this.configuration?.threshold || {
|
|
344
372
|
dynamicRadiusInCanvas: 0,
|
|
@@ -42,6 +42,12 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
42
42
|
volumeId?: string;
|
|
43
43
|
referencedVolumeId?: string;
|
|
44
44
|
} | null;
|
|
45
|
+
protected centerSegmentIndexInfo: {
|
|
46
|
+
segmentIndex: number;
|
|
47
|
+
hasSegmentIndex: boolean;
|
|
48
|
+
hasPreviewIndex: boolean;
|
|
49
|
+
changedIndices: number[];
|
|
50
|
+
};
|
|
45
51
|
protected _hoverData?: {
|
|
46
52
|
brushCursor: any;
|
|
47
53
|
segmentationId: string;
|
|
@@ -52,9 +58,16 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
52
58
|
viewport: Types.IViewport;
|
|
53
59
|
};
|
|
54
60
|
static previewData?: PreviewData;
|
|
61
|
+
protected memoMap: Map<string, LabelmapMemo.LabelmapMemo>;
|
|
62
|
+
protected acceptedMemoIds: Map<string, {
|
|
63
|
+
element: HTMLDivElement;
|
|
64
|
+
segmentIndex: number;
|
|
65
|
+
}>;
|
|
66
|
+
protected memo: LabelmapMemo.LabelmapMemo;
|
|
55
67
|
constructor(toolProps: any, defaultToolProps: any);
|
|
68
|
+
protected _historyRedoHandler(evt: any): void;
|
|
56
69
|
protected get _previewData(): PreviewData;
|
|
57
|
-
createMemo(
|
|
70
|
+
createMemo(segmentationId: string, segmentationVoxelManager: any): LabelmapMemo.LabelmapMemo;
|
|
58
71
|
protected createEditData(element: any): EditDataReturnType;
|
|
59
72
|
protected getEditData({ viewport, representationData, segmentsLocked, segmentationId, }: {
|
|
60
73
|
viewport: any;
|
|
@@ -89,7 +102,7 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
89
102
|
protected getOperationData(element?: any): ModifiedLabelmapToolOperationData;
|
|
90
103
|
addPreview(element?: HTMLDivElement, options?: {
|
|
91
104
|
acceptReject: boolean;
|
|
92
|
-
}):
|
|
105
|
+
}): any;
|
|
93
106
|
rejectPreview(element?: HTMLDivElement): void;
|
|
94
107
|
acceptPreview(element?: HTMLDivElement): void;
|
|
95
108
|
static viewportContoursToLabelmap(viewport: Types.IViewport, options?: {
|
|
@@ -8,7 +8,7 @@ import { getClosestImageIdForStackViewport } from '../../utilities/annotationHyd
|
|
|
8
8
|
import { getCurrentLabelmapImageIdForViewport } from '../../stateManagement/segmentation/getCurrentLabelmapImageIdForViewport';
|
|
9
9
|
import { getSegmentIndexColor } from '../../stateManagement/segmentation/config/segmentationColor';
|
|
10
10
|
import { getActiveSegmentIndex } from '../../stateManagement/segmentation/getActiveSegmentIndex';
|
|
11
|
-
import { StrategyCallbacks } from '../../enums';
|
|
11
|
+
import { StrategyCallbacks, Events } from '../../enums';
|
|
12
12
|
import * as LabelmapMemo from '../../utilities/segmentation/createLabelmapMemo';
|
|
13
13
|
import { getAllAnnotations, removeAnnotation, } from '../../stateManagement/annotation/annotationState';
|
|
14
14
|
import { filterAnnotationsForDisplay } from '../../utilities/planar';
|
|
@@ -26,13 +26,54 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
26
26
|
}; }
|
|
27
27
|
constructor(toolProps, defaultToolProps) {
|
|
28
28
|
super(toolProps, defaultToolProps);
|
|
29
|
+
this.memoMap = new Map();
|
|
30
|
+
this.acceptedMemoIds = new Map();
|
|
31
|
+
this.centerSegmentIndexInfo = {
|
|
32
|
+
segmentIndex: null,
|
|
33
|
+
hasSegmentIndex: false,
|
|
34
|
+
hasPreviewIndex: false,
|
|
35
|
+
changedIndices: [],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
_historyRedoHandler(evt) {
|
|
39
|
+
const { id, operationType } = evt.detail;
|
|
40
|
+
if (operationType !== 'labelmap') {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (this.acceptedMemoIds.has(id)) {
|
|
44
|
+
this._hoverData = null;
|
|
45
|
+
const memoData = this.acceptedMemoIds.get(id);
|
|
46
|
+
const element = memoData?.element;
|
|
47
|
+
const operationData = this.getOperationData(element);
|
|
48
|
+
operationData.segmentIndex = memoData?.segmentIndex;
|
|
49
|
+
if (element) {
|
|
50
|
+
this.applyActiveStrategyCallback(getEnabledElement(element), operationData, StrategyCallbacks.AcceptPreview);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
this._previewData.isDrag = true;
|
|
29
54
|
}
|
|
30
55
|
get _previewData() {
|
|
31
56
|
return LabelmapBaseTool.previewData;
|
|
32
57
|
}
|
|
33
|
-
createMemo(
|
|
34
|
-
|
|
35
|
-
|
|
58
|
+
createMemo(segmentationId, segmentationVoxelManager) {
|
|
59
|
+
const voxelManagerId = segmentationVoxelManager.id;
|
|
60
|
+
if (this.memo &&
|
|
61
|
+
this.memo.segmentationVoxelManager === segmentationVoxelManager) {
|
|
62
|
+
return this.memo;
|
|
63
|
+
}
|
|
64
|
+
let memo = this.memoMap.get(voxelManagerId);
|
|
65
|
+
if (!memo) {
|
|
66
|
+
memo = LabelmapMemo.createLabelmapMemo(segmentationId, segmentationVoxelManager);
|
|
67
|
+
this.memoMap.set(voxelManagerId, memo);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
if (memo.redoVoxelManager) {
|
|
71
|
+
memo = LabelmapMemo.createLabelmapMemo(segmentationId, segmentationVoxelManager);
|
|
72
|
+
this.memoMap.set(voxelManagerId, memo);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
this.memo = memo;
|
|
76
|
+
return memo;
|
|
36
77
|
}
|
|
37
78
|
createEditData(element) {
|
|
38
79
|
const enabledElement = getEnabledElement(element);
|
|
@@ -154,20 +195,25 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
154
195
|
if (!configColor && !segmentColor) {
|
|
155
196
|
return;
|
|
156
197
|
}
|
|
198
|
+
let previewColor = null, previewSegmentIndex = null;
|
|
199
|
+
if (this.configuration.preview.enabled) {
|
|
200
|
+
previewColor = configColor || lightenColor(...segmentColor);
|
|
201
|
+
previewSegmentIndex = 255;
|
|
202
|
+
}
|
|
157
203
|
const operationData = {
|
|
158
204
|
...editData,
|
|
159
205
|
points: data?.handles?.points,
|
|
160
206
|
segmentIndex,
|
|
161
207
|
viewPlaneNormal,
|
|
208
|
+
previewOnHover: !this._previewData.isDrag,
|
|
162
209
|
toolGroupId: this.toolGroupId,
|
|
163
210
|
segmentationId,
|
|
164
211
|
viewUp,
|
|
212
|
+
centerSegmentIndexInfo: this.centerSegmentIndexInfo,
|
|
165
213
|
activeStrategy: this.configuration.activeStrategy,
|
|
166
214
|
configuration: this.configuration,
|
|
167
|
-
previewColor
|
|
168
|
-
|
|
169
|
-
: null,
|
|
170
|
-
preview: this._previewData?.preview,
|
|
215
|
+
previewColor,
|
|
216
|
+
previewSegmentIndex,
|
|
171
217
|
createMemo: this.createMemo.bind(this),
|
|
172
218
|
};
|
|
173
219
|
return operationData;
|
|
@@ -182,14 +228,15 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
182
228
|
this.rejectPreview(element);
|
|
183
229
|
}
|
|
184
230
|
const enabledElement = getEnabledElement(element);
|
|
185
|
-
|
|
231
|
+
const results = this.applyActiveStrategyCallback(enabledElement, this.getOperationData(element), StrategyCallbacks.AddPreview);
|
|
186
232
|
_previewData.isDrag = true;
|
|
187
|
-
return
|
|
233
|
+
return results;
|
|
188
234
|
}
|
|
189
235
|
rejectPreview(element = this._previewData.element) {
|
|
190
|
-
if (!element
|
|
236
|
+
if (!element) {
|
|
191
237
|
return;
|
|
192
238
|
}
|
|
239
|
+
this.doneEditMemo();
|
|
193
240
|
const enabledElement = getEnabledElement(element);
|
|
194
241
|
this.applyActiveStrategyCallback(enabledElement, this.getOperationData(element), StrategyCallbacks.RejectPreview);
|
|
195
242
|
this._previewData.preview = null;
|
|
@@ -199,12 +246,18 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
199
246
|
if (!element) {
|
|
200
247
|
return;
|
|
201
248
|
}
|
|
202
|
-
this.
|
|
249
|
+
const operationData = this.getOperationData(element);
|
|
250
|
+
if (this.memo && this.memo.id) {
|
|
251
|
+
this.acceptedMemoIds.set(this.memo.id, {
|
|
252
|
+
element,
|
|
253
|
+
segmentIndex: operationData.segmentIndex,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
203
256
|
const enabledElement = getEnabledElement(element);
|
|
204
|
-
this.applyActiveStrategyCallback(enabledElement,
|
|
205
|
-
this._previewData.isDrag = false;
|
|
206
|
-
this._previewData.preview = null;
|
|
257
|
+
this.applyActiveStrategyCallback(enabledElement, operationData, StrategyCallbacks.AcceptPreview);
|
|
207
258
|
this.doneEditMemo();
|
|
259
|
+
this._previewData.preview = null;
|
|
260
|
+
this._previewData.isDrag = false;
|
|
208
261
|
}
|
|
209
262
|
static viewportContoursToLabelmap(viewport, options) {
|
|
210
263
|
const removeContours = options?.removeContours ?? true;
|
|
@@ -227,7 +280,7 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
227
280
|
});
|
|
228
281
|
const preview = brushInstance.addPreview(viewport.element);
|
|
229
282
|
const { memo, segmentationId } = preview;
|
|
230
|
-
const previewVoxels = memo?.voxelManager
|
|
283
|
+
const previewVoxels = memo?.voxelManager;
|
|
231
284
|
const segmentationVoxels = previewVoxels.sourceVoxelManager || previewVoxels;
|
|
232
285
|
const { dimensions } = previewVoxels;
|
|
233
286
|
const imageData = viewport
|
|
@@ -5,6 +5,12 @@ import type vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
|
|
|
5
5
|
import type { LabelmapMemo } from '../../../utilities/segmentation/createLabelmapMemo';
|
|
6
6
|
export type InitializedOperationData = LabelmapToolOperationDataAny & {
|
|
7
7
|
operationName?: string;
|
|
8
|
+
centerSegmentIndexInfo: {
|
|
9
|
+
segmentIndex: number;
|
|
10
|
+
hasSegmentIndex: boolean;
|
|
11
|
+
hasPreviewIndex: boolean;
|
|
12
|
+
changedIndices: number[];
|
|
13
|
+
};
|
|
8
14
|
enabledElement: Types.IEnabledElement;
|
|
9
15
|
centerIJK?: Types.Point3;
|
|
10
16
|
centerWorld: Types.Point3;
|
|
@@ -14,7 +20,6 @@ export type InitializedOperationData = LabelmapToolOperationDataAny & {
|
|
|
14
20
|
imageVoxelManager: Types.IVoxelManager<number> | Types.IVoxelManager<Types.RGB>;
|
|
15
21
|
segmentationVoxelManager: Types.IVoxelManager<number>;
|
|
16
22
|
segmentationImageData: vtkImageData;
|
|
17
|
-
previewVoxelManager: Types.IVoxelManager<number>;
|
|
18
23
|
previewSegmentIndex?: number;
|
|
19
24
|
previewColor?: [number, number, number, number];
|
|
20
25
|
brushStrategy: BrushStrategy;
|
|
@@ -42,7 +47,6 @@ export type Composition = CompositionFunction | CompositionInstance;
|
|
|
42
47
|
export default class BrushStrategy {
|
|
43
48
|
static COMPOSITIONS: {
|
|
44
49
|
determineSegmentIndex: {
|
|
45
|
-
initialize: (operationData: InitializedOperationData) => void;
|
|
46
50
|
onInteractionStart: (operationData: InitializedOperationData) => void;
|
|
47
51
|
};
|
|
48
52
|
dynamicThreshold: {
|
|
@@ -112,12 +116,12 @@ export default class BrushStrategy {
|
|
|
112
116
|
protected _acceptPreview: [];
|
|
113
117
|
protected _onInteractionStart: any[];
|
|
114
118
|
constructor(name: any, ...initializers: Composition[]);
|
|
115
|
-
fill: (enabledElement: Types.IEnabledElement, operationData: LabelmapToolOperationDataAny) =>
|
|
119
|
+
fill: (enabledElement: Types.IEnabledElement, operationData: LabelmapToolOperationDataAny) => InitializedOperationData;
|
|
116
120
|
protected initialize(enabledElement: Types.IEnabledElement, operationData: LabelmapToolOperationDataAny, operationName?: string): InitializedOperationData;
|
|
117
121
|
onInteractionStart: (enabledElement: Types.IEnabledElement, operationData: LabelmapToolOperationDataAny) => void;
|
|
118
122
|
onInteractionEnd: (enabledElement: Types.IEnabledElement, operationData: LabelmapToolOperationDataAny) => void;
|
|
119
123
|
rejectPreview: (enabledElement: Types.IEnabledElement, operationData: LabelmapToolOperationDataAny) => void;
|
|
120
|
-
addPreview: (enabledElement: any, operationData: LabelmapToolOperationDataAny) =>
|
|
124
|
+
addPreview: (enabledElement: any, operationData: LabelmapToolOperationDataAny) => InitializedOperationData;
|
|
121
125
|
acceptPreview: (enabledElement: Types.IEnabledElement, operationData: LabelmapToolOperationDataAny) => void;
|
|
122
126
|
preview: (enabledElement: Types.IEnabledElement, operationData: LabelmapToolOperationDataAny) => unknown;
|
|
123
127
|
interpolate: (enabledElement: Types.IEnabledElement, operationData: LabelmapToolOperationDataAny) => unknown;
|
|
@@ -3,7 +3,6 @@ import { triggerSegmentationDataModified } from '../../../stateManagement/segmen
|
|
|
3
3
|
import compositions from './compositions';
|
|
4
4
|
import { getStrategyData } from './utils/getStrategyData';
|
|
5
5
|
import { StrategyCallbacks } from '../../../enums';
|
|
6
|
-
const { VoxelManager } = csUtils;
|
|
7
6
|
export default class BrushStrategy {
|
|
8
7
|
static { this.COMPOSITIONS = compositions; }
|
|
9
8
|
static { this.childFunctions = {
|
|
@@ -33,29 +32,12 @@ export default class BrushStrategy {
|
|
|
33
32
|
if (!initializedData) {
|
|
34
33
|
return;
|
|
35
34
|
}
|
|
36
|
-
const { configuration = {}, centerIJK } = initializedData;
|
|
37
|
-
if (csUtils.isEqual(centerIJK, configuration.centerIJK)) {
|
|
38
|
-
return operationData.preview;
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
configuration.centerIJK = centerIJK;
|
|
42
|
-
}
|
|
43
35
|
this._fill.forEach((func) => func(initializedData));
|
|
44
|
-
const { segmentationVoxelManager,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (!previewSegmentIndex || !previewVoxelManager.modifiedSlices.size) {
|
|
48
|
-
segmentationVoxelManager.resetModifiedSlices();
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
return initializedData.preview || initializedData;
|
|
36
|
+
const { segmentationVoxelManager, segmentIndex } = initializedData;
|
|
37
|
+
triggerSegmentationDataModified(initializedData.segmentationId, segmentationVoxelManager.getArrayOfModifiedSlices(), segmentIndex);
|
|
38
|
+
return initializedData;
|
|
52
39
|
};
|
|
53
40
|
this.onInteractionStart = (enabledElement, operationData) => {
|
|
54
|
-
const { preview } = operationData;
|
|
55
|
-
if (preview?.isPreviewFromHover) {
|
|
56
|
-
preview.isPreviewFromHover = false;
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
41
|
const initializedData = this.initialize(enabledElement, operationData);
|
|
60
42
|
if (!initializedData) {
|
|
61
43
|
return;
|
|
@@ -67,7 +49,7 @@ export default class BrushStrategy {
|
|
|
67
49
|
if (!initializedData) {
|
|
68
50
|
return;
|
|
69
51
|
}
|
|
70
|
-
return initializedData
|
|
52
|
+
return initializedData;
|
|
71
53
|
};
|
|
72
54
|
this.configurationName = name;
|
|
73
55
|
this.compositions = initializers;
|
|
@@ -94,28 +76,24 @@ export default class BrushStrategy {
|
|
|
94
76
|
const { viewport } = enabledElement;
|
|
95
77
|
const data = getStrategyData({ operationData, viewport, strategy: this });
|
|
96
78
|
if (!data) {
|
|
97
|
-
|
|
98
|
-
return operationData.preview;
|
|
79
|
+
return null;
|
|
99
80
|
}
|
|
100
81
|
const { imageVoxelManager, segmentationVoxelManager, segmentationImageData, } = data;
|
|
101
|
-
const
|
|
102
|
-
VoxelManager.createRLEHistoryVoxelManager(segmentationVoxelManager);
|
|
103
|
-
const previewEnabled = !!operationData.previewColor;
|
|
104
|
-
const previewSegmentIndex = previewEnabled ? 255 : undefined;
|
|
82
|
+
const memo = operationData.createMemo(operationData.segmentationId, segmentationVoxelManager);
|
|
105
83
|
const initializedData = {
|
|
106
84
|
operationName,
|
|
107
|
-
previewSegmentIndex,
|
|
108
85
|
...operationData,
|
|
86
|
+
segmentIndex: operationData.segmentIndex,
|
|
109
87
|
enabledElement,
|
|
110
88
|
imageVoxelManager,
|
|
111
89
|
segmentationVoxelManager,
|
|
112
90
|
segmentationImageData,
|
|
113
|
-
previewVoxelManager,
|
|
114
91
|
viewport,
|
|
115
92
|
centerWorld: null,
|
|
116
93
|
isInObject: null,
|
|
117
94
|
isInObjectBoundsIJK: null,
|
|
118
95
|
brushStrategy: this,
|
|
96
|
+
memo,
|
|
119
97
|
};
|
|
120
98
|
this._initialize.forEach((func) => func(initializedData));
|
|
121
99
|
return initializedData;
|
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
|
|
2
2
|
export default {
|
|
3
|
-
[StrategyCallbacks.Initialize]: (operationData) => {
|
|
4
|
-
const { centerSegmentIndex } = operationData.configuration || {};
|
|
5
|
-
if (!centerSegmentIndex) {
|
|
6
|
-
return;
|
|
7
|
-
}
|
|
8
|
-
operationData.segmentIndex = centerSegmentIndex.segmentIndex;
|
|
9
|
-
},
|
|
10
3
|
[StrategyCallbacks.OnInteractionStart]: (operationData) => {
|
|
11
|
-
const { segmentIndex, previewSegmentIndex, segmentationVoxelManager, centerIJK, viewPlaneNormal, segmentationImageData,
|
|
4
|
+
const { segmentIndex, previewSegmentIndex, segmentationVoxelManager, centerIJK, viewPlaneNormal, segmentationImageData, configuration, } = operationData;
|
|
12
5
|
if (!configuration?.useCenterSegmentIndex) {
|
|
13
6
|
return;
|
|
14
7
|
}
|
|
15
|
-
delete configuration.centerSegmentIndex;
|
|
16
8
|
let hasSegmentIndex = false;
|
|
17
9
|
let hasPreviewIndex = false;
|
|
18
10
|
const nestedBounds = [
|
|
@@ -37,23 +29,12 @@ export default {
|
|
|
37
29
|
boundsIJK: nestedBounds,
|
|
38
30
|
});
|
|
39
31
|
if (!hasSegmentIndex && !hasPreviewIndex) {
|
|
32
|
+
operationData.centerSegmentIndexInfo.segmentIndex = null;
|
|
40
33
|
return;
|
|
41
34
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
else if (hasPreviewIndex) {
|
|
52
|
-
existingValue = null;
|
|
53
|
-
}
|
|
54
|
-
operationData.segmentIndex = existingValue;
|
|
55
|
-
configuration.centerSegmentIndex = {
|
|
56
|
-
segmentIndex: existingValue,
|
|
57
|
-
};
|
|
35
|
+
const existingValue = segmentationVoxelManager.getAtIJKPoint(centerIJK);
|
|
36
|
+
operationData.centerSegmentIndexInfo.segmentIndex = existingValue;
|
|
37
|
+
operationData.centerSegmentIndexInfo.hasSegmentIndex = hasSegmentIndex;
|
|
38
|
+
operationData.centerSegmentIndexInfo.hasPreviewIndex = hasPreviewIndex;
|
|
58
39
|
},
|
|
59
40
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
declare const _default: {
|
|
2
2
|
determineSegmentIndex: {
|
|
3
|
-
initialize: (operationData: import("../BrushStrategy").InitializedOperationData) => void;
|
|
4
3
|
onInteractionStart: (operationData: import("../BrushStrategy").InitializedOperationData) => void;
|
|
5
4
|
};
|
|
6
5
|
dynamicThreshold: {
|
|
@@ -3,13 +3,13 @@ import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
|
|
|
3
3
|
import IslandRemoval from '../../../../utilities/segmentation/islandRemoval';
|
|
4
4
|
export default {
|
|
5
5
|
[StrategyCallbacks.OnInteractionEnd]: (operationData) => {
|
|
6
|
-
const { previewSegmentIndex, segmentIndex, viewport,
|
|
6
|
+
const { previewSegmentIndex, segmentIndex, viewport, segmentationVoxelManager, activeStrategy, memo, } = operationData;
|
|
7
7
|
if (activeStrategy !== 'THRESHOLD_INSIDE_SPHERE_WITH_ISLAND_REMOVAL' ||
|
|
8
8
|
segmentIndex === null) {
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
11
|
const islandRemoval = new IslandRemoval();
|
|
12
|
-
const voxelManager =
|
|
12
|
+
const voxelManager = memo?.voxelManager || segmentationVoxelManager;
|
|
13
13
|
if (!islandRemoval.initialize(viewport, voxelManager, {
|
|
14
14
|
previewSegmentIndex,
|
|
15
15
|
segmentIndex,
|
|
@@ -1,38 +1,24 @@
|
|
|
1
|
+
import { utilities } from '@cornerstonejs/core';
|
|
1
2
|
import { triggerSegmentationDataModified } from '../../../../stateManagement/segmentation/events/triggerSegmentationDataModified';
|
|
2
3
|
import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
|
|
3
|
-
import {
|
|
4
|
+
import { setSegmentIndexColor } from '../../../../stateManagement/segmentation/config/segmentationColor';
|
|
4
5
|
import { getViewportIdsWithSegmentation } from '../../../../stateManagement/segmentation/getViewportIdsWithSegmentation';
|
|
5
6
|
export default {
|
|
6
7
|
[StrategyCallbacks.Preview]: function (operationData) {
|
|
7
|
-
const {
|
|
8
|
-
if (!
|
|
8
|
+
const { previewSegmentIndex, configuration, enabledElement } = operationData;
|
|
9
|
+
if (!previewSegmentIndex || !configuration) {
|
|
9
10
|
return;
|
|
10
11
|
}
|
|
11
|
-
if (operationData.preview) {
|
|
12
|
-
delete operationData.preview;
|
|
13
|
-
}
|
|
14
|
-
delete configuration.centerSegmentIndex;
|
|
15
12
|
this.onInteractionStart?.(enabledElement, operationData);
|
|
16
13
|
const preview = this.fill(enabledElement, operationData);
|
|
17
14
|
if (preview) {
|
|
18
|
-
preview.isPreviewFromHover = true;
|
|
19
|
-
operationData.preview = preview;
|
|
20
15
|
this.onInteractionEnd?.(enabledElement, operationData);
|
|
21
16
|
}
|
|
22
17
|
return preview;
|
|
23
18
|
},
|
|
24
19
|
[StrategyCallbacks.Initialize]: (operationData) => {
|
|
25
|
-
const { segmentIndex,
|
|
26
|
-
if (
|
|
27
|
-
operationData.memo = operationData.createMemo(segmentationId, segmentationVoxelManager);
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
if (preview) {
|
|
31
|
-
preview.previewVoxelManager.sourceVoxelManager =
|
|
32
|
-
operationData.segmentationVoxelManager;
|
|
33
|
-
operationData.previewVoxelManager = preview.previewVoxelManager;
|
|
34
|
-
}
|
|
35
|
-
if (segmentIndex === null) {
|
|
20
|
+
const { segmentIndex, previewColor, previewSegmentIndex } = operationData;
|
|
21
|
+
if (previewSegmentIndex == null || segmentIndex == null) {
|
|
36
22
|
return;
|
|
37
23
|
}
|
|
38
24
|
const viewportIds = getViewportIdsWithSegmentation(operationData.segmentationId);
|
|
@@ -41,38 +27,44 @@ export default {
|
|
|
41
27
|
});
|
|
42
28
|
},
|
|
43
29
|
[StrategyCallbacks.AcceptPreview]: (operationData) => {
|
|
44
|
-
const {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
const segmentIndex = preview?.segmentIndex ?? operationData.segmentIndex;
|
|
49
|
-
if (!previewVoxelManager || previewVoxelManager.modifiedSlices.size === 0) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
const memo = operationData.createMemo(segmentationId, segmentationVoxelManager);
|
|
53
|
-
operationData.memo = memo;
|
|
54
|
-
const { voxelManager } = memo;
|
|
55
|
-
const callback = ({ index, value }) => {
|
|
30
|
+
const { previewSegmentIndex, segmentationVoxelManager, memo, segmentIndex, centerSegmentIndexInfo, } = operationData || {};
|
|
31
|
+
const { changedIndices } = centerSegmentIndexInfo || {};
|
|
32
|
+
const labelmapMemo = memo;
|
|
33
|
+
const callback = ({ index }) => {
|
|
56
34
|
const oldValue = segmentationVoxelManager.getAtIndex(index);
|
|
57
|
-
if (
|
|
58
|
-
|
|
59
|
-
|
|
35
|
+
if (changedIndices?.length > 0) {
|
|
36
|
+
if (changedIndices.includes(index)) {
|
|
37
|
+
labelmapMemo.voxelManager.setAtIndex(index, 0);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
if (oldValue === previewSegmentIndex) {
|
|
42
|
+
labelmapMemo.voxelManager.setAtIndex(index, segmentIndex);
|
|
43
|
+
}
|
|
60
44
|
}
|
|
61
45
|
};
|
|
62
|
-
|
|
63
|
-
triggerSegmentationDataModified(operationData.segmentationId,
|
|
64
|
-
|
|
46
|
+
segmentationVoxelManager.forEach(callback);
|
|
47
|
+
triggerSegmentationDataModified(operationData.segmentationId, segmentationVoxelManager.getArrayOfModifiedSlices(), segmentIndex);
|
|
48
|
+
operationData.centerSegmentIndexInfo.changedIndices = [];
|
|
65
49
|
},
|
|
66
50
|
[StrategyCallbacks.RejectPreview]: (operationData) => {
|
|
67
|
-
|
|
68
|
-
if (previewVoxelManager.modifiedSlices.size === 0) {
|
|
51
|
+
if (!operationData) {
|
|
69
52
|
return;
|
|
70
53
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
54
|
+
utilities.HistoryMemo.DefaultHistoryMemo.undoIf((memo) => {
|
|
55
|
+
const labelmapMemo = memo;
|
|
56
|
+
if (!labelmapMemo?.voxelManager) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
const { segmentationVoxelManager } = labelmapMemo;
|
|
60
|
+
let hasPreviewSegmentIndex = false;
|
|
61
|
+
const callback = ({ value }) => {
|
|
62
|
+
if (value === operationData.previewSegmentIndex) {
|
|
63
|
+
hasPreviewSegmentIndex = true;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
segmentationVoxelManager.forEach(callback);
|
|
67
|
+
return hasPreviewSegmentIndex;
|
|
68
|
+
});
|
|
77
69
|
},
|
|
78
70
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
|
|
2
2
|
export default {
|
|
3
3
|
[StrategyCallbacks.Fill]: (operationData) => {
|
|
4
|
-
const { segmentsLocked, segmentationImageData, segmentationVoxelManager,
|
|
4
|
+
const { segmentsLocked, segmentationImageData, segmentationVoxelManager, brushStrategy, centerIJK, } = operationData;
|
|
5
5
|
const isWithinThreshold = brushStrategy.createIsInThreshold?.(operationData);
|
|
6
6
|
const { setValue } = brushStrategy;
|
|
7
7
|
const callback = isWithinThreshold
|
|
@@ -18,6 +18,6 @@ export default {
|
|
|
18
18
|
isInObject: operationData.isInObject,
|
|
19
19
|
boundsIJK: operationData.isInObjectBoundsIJK,
|
|
20
20
|
});
|
|
21
|
-
|
|
21
|
+
segmentationVoxelManager.addPoint(centerIJK);
|
|
22
22
|
},
|
|
23
23
|
};
|
|
@@ -1,29 +1,35 @@
|
|
|
1
1
|
import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
|
|
2
|
+
import { handleUseSegmentCenterIndex } from '../utils/handleUseSegmentCenterIndex';
|
|
2
3
|
export default {
|
|
3
4
|
[StrategyCallbacks.INTERNAL_setValue]: (operationData, { value, index }) => {
|
|
4
|
-
const { segmentsLocked,
|
|
5
|
-
const previewVoxelManager = memo?.voxelManager || operationData.previewVoxelManager;
|
|
5
|
+
const { segmentsLocked, previewSegmentIndex, memo, segmentationVoxelManager, centerSegmentIndexInfo, segmentIndex, } = operationData;
|
|
6
6
|
const existingValue = segmentationVoxelManager.getAtIndex(index);
|
|
7
|
-
|
|
8
|
-
if (segmentIndex === null) {
|
|
9
|
-
const oldValue = previewVoxelManager.getAtIndex(index);
|
|
10
|
-
if (oldValue !== undefined) {
|
|
11
|
-
changed = previewVoxelManager.setAtIndex(index, oldValue);
|
|
12
|
-
}
|
|
7
|
+
if (segmentsLocked.includes(value)) {
|
|
13
8
|
return;
|
|
14
9
|
}
|
|
15
|
-
if (existingValue === segmentIndex
|
|
10
|
+
if (!centerSegmentIndexInfo && existingValue === segmentIndex) {
|
|
16
11
|
return;
|
|
17
12
|
}
|
|
18
|
-
if (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
if (centerSegmentIndexInfo?.segmentIndex !== 0 &&
|
|
14
|
+
existingValue === segmentIndex) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (centerSegmentIndexInfo?.segmentIndex === null) {
|
|
18
|
+
memo.voxelManager.setAtIndex(index, previewSegmentIndex ?? segmentIndex);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (!previewSegmentIndex) {
|
|
22
|
+
let useSegmentIndex = segmentIndex;
|
|
23
|
+
if (centerSegmentIndexInfo) {
|
|
24
|
+
useSegmentIndex = centerSegmentIndexInfo.segmentIndex;
|
|
24
25
|
}
|
|
26
|
+
memo.voxelManager.setAtIndex(index, useSegmentIndex);
|
|
27
|
+
return;
|
|
25
28
|
}
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
handleUseSegmentCenterIndex({
|
|
30
|
+
operationData,
|
|
31
|
+
existingValue,
|
|
32
|
+
index,
|
|
33
|
+
});
|
|
28
34
|
},
|
|
29
35
|
};
|
|
@@ -97,6 +97,9 @@ function getStrategyDataForStackViewport({ operationData, viewport, strategy, })
|
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
99
|
function getStrategyData({ operationData, viewport, strategy, }) {
|
|
100
|
+
if (!operationData) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
100
103
|
if (('volumeId' in operationData && operationData.volumeId != null) ||
|
|
101
104
|
('referencedVolumeId' in operationData &&
|
|
102
105
|
operationData.referencedVolumeId != null)) {
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export function handleUseSegmentCenterIndex({ operationData, existingValue, index, }) {
|
|
2
|
+
const { previewSegmentIndex, memo, centerSegmentIndexInfo, previewOnHover, segmentIndex, } = operationData;
|
|
3
|
+
const { hasPreviewIndex, hasSegmentIndex, segmentIndex: centerSegmentIndex, } = centerSegmentIndexInfo;
|
|
4
|
+
if (centerSegmentIndex === 0 && hasSegmentIndex && hasPreviewIndex) {
|
|
5
|
+
if (existingValue === segmentIndex) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
if (previewOnHover) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (existingValue === previewSegmentIndex) {
|
|
12
|
+
memo.voxelManager.setAtIndex(index, 0);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (centerSegmentIndex === 0 && hasSegmentIndex && !hasPreviewIndex) {
|
|
18
|
+
if (existingValue === 0 || existingValue !== segmentIndex) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
memo.voxelManager.setAtIndex(index, previewSegmentIndex);
|
|
22
|
+
centerSegmentIndexInfo.changedIndices.push(index);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (centerSegmentIndex === 0 && !hasSegmentIndex && hasPreviewIndex) {
|
|
26
|
+
if (existingValue === segmentIndex) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (previewOnHover) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (existingValue === previewSegmentIndex) {
|
|
33
|
+
memo.voxelManager.setAtIndex(index, 0);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (centerSegmentIndex === 0 && !hasSegmentIndex && !hasPreviewIndex) {
|
|
39
|
+
if (existingValue === segmentIndex) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (existingValue === previewSegmentIndex) {
|
|
43
|
+
memo.voxelManager.setAtIndex(index, previewSegmentIndex);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (centerSegmentIndex === previewSegmentIndex &&
|
|
49
|
+
hasSegmentIndex &&
|
|
50
|
+
hasPreviewIndex) {
|
|
51
|
+
if (existingValue === segmentIndex) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
memo.voxelManager.setAtIndex(index, previewSegmentIndex);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (centerSegmentIndex === previewSegmentIndex &&
|
|
58
|
+
!hasSegmentIndex &&
|
|
59
|
+
hasPreviewIndex) {
|
|
60
|
+
if (existingValue === segmentIndex) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
memo.voxelManager.setAtIndex(index, previewSegmentIndex);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (centerSegmentIndex === segmentIndex &&
|
|
67
|
+
hasSegmentIndex &&
|
|
68
|
+
hasPreviewIndex) {
|
|
69
|
+
if (existingValue === segmentIndex) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
memo.voxelManager.setAtIndex(index, previewSegmentIndex);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (centerSegmentIndex === segmentIndex &&
|
|
76
|
+
hasSegmentIndex &&
|
|
77
|
+
!hasPreviewIndex) {
|
|
78
|
+
if (existingValue === segmentIndex) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
memo.voxelManager.setAtIndex(index, previewSegmentIndex);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -6,6 +6,7 @@ type LabelmapToolOperationData = {
|
|
|
6
6
|
segmentationId: string;
|
|
7
7
|
segmentIndex: number;
|
|
8
8
|
previewColor?: [number, number, number, number];
|
|
9
|
+
previewSegmentIndex?: number;
|
|
9
10
|
segmentsLocked: number[];
|
|
10
11
|
viewPlaneNormal: number[];
|
|
11
12
|
viewUp: number[];
|
|
@@ -16,7 +17,6 @@ type LabelmapToolOperationData = {
|
|
|
16
17
|
voxelManager: Types.IVoxelManager<number>;
|
|
17
18
|
imageData: vtkImageData;
|
|
18
19
|
};
|
|
19
|
-
preview: any;
|
|
20
20
|
toolGroupId: string;
|
|
21
21
|
createMemo: (segmentId: any, segmentVoxels: any, previewVoxels?: any, previewMemo?: any) => LabelmapMemo;
|
|
22
22
|
};
|
|
@@ -1,27 +1,21 @@
|
|
|
1
1
|
import { utilities } from '@cornerstonejs/core';
|
|
2
2
|
import type { Types } from '@cornerstonejs/core';
|
|
3
|
-
import type { InitializedOperationData } from '../../tools/segmentation/strategies/BrushStrategy';
|
|
4
3
|
export type LabelmapMemo = Types.Memo & {
|
|
5
4
|
segmentationVoxelManager: Types.IVoxelManager<number>;
|
|
6
5
|
voxelManager: Types.IVoxelManager<number>;
|
|
7
6
|
redoVoxelManager?: Types.IVoxelManager<number>;
|
|
8
7
|
undoVoxelManager?: Types.IVoxelManager<number>;
|
|
9
8
|
memo?: LabelmapMemo;
|
|
9
|
+
id: string;
|
|
10
10
|
};
|
|
11
|
-
export declare function createLabelmapMemo<T>(segmentationId: string, segmentationVoxelManager: Types.IVoxelManager<T
|
|
12
|
-
segmentationId: string;
|
|
13
|
-
restoreMemo: typeof restoreMemo;
|
|
14
|
-
commitMemo: typeof commitMemo;
|
|
15
|
-
segmentationVoxelManager: Types.IVoxelManager<number>;
|
|
16
|
-
voxelManager: Types.IVoxelManager<number>;
|
|
17
|
-
memo: LabelmapMemo;
|
|
18
|
-
preview: InitializedOperationData;
|
|
19
|
-
} | {
|
|
11
|
+
export declare function createLabelmapMemo<T>(segmentationId: string, segmentationVoxelManager: Types.IVoxelManager<T>): {
|
|
20
12
|
segmentationId: string;
|
|
21
13
|
restoreMemo: typeof restoreMemo;
|
|
22
14
|
commitMemo: typeof commitMemo;
|
|
23
15
|
segmentationVoxelManager: Types.IVoxelManager<T>;
|
|
24
16
|
voxelManager: utilities.VoxelManager<T>;
|
|
17
|
+
id: string;
|
|
18
|
+
operationType: string;
|
|
25
19
|
};
|
|
26
20
|
export declare function restoreMemo(isUndo?: boolean): void;
|
|
27
21
|
export declare function createRleMemo<T>(segmentationId: string, segmentationVoxelManager: Types.IVoxelManager<T>): {
|
|
@@ -30,15 +24,8 @@ export declare function createRleMemo<T>(segmentationId: string, segmentationVox
|
|
|
30
24
|
commitMemo: typeof commitMemo;
|
|
31
25
|
segmentationVoxelManager: Types.IVoxelManager<T>;
|
|
32
26
|
voxelManager: utilities.VoxelManager<T>;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
segmentationId: string;
|
|
36
|
-
restoreMemo: typeof restoreMemo;
|
|
37
|
-
commitMemo: typeof commitMemo;
|
|
38
|
-
segmentationVoxelManager: Types.IVoxelManager<number>;
|
|
39
|
-
voxelManager: Types.IVoxelManager<number>;
|
|
40
|
-
memo: LabelmapMemo;
|
|
41
|
-
preview: InitializedOperationData;
|
|
27
|
+
id: string;
|
|
28
|
+
operationType: string;
|
|
42
29
|
};
|
|
43
30
|
declare function commitMemo(): boolean;
|
|
44
31
|
export {};
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { utilities } from '@cornerstonejs/core';
|
|
1
|
+
import { utilities, eventTarget } from '@cornerstonejs/core';
|
|
2
2
|
import { triggerSegmentationDataModified } from '../../stateManagement/segmentation/triggerSegmentationEvents';
|
|
3
|
+
import Events from '../../enums/Events';
|
|
3
4
|
const { VoxelManager, RLEVoxelMap } = utilities;
|
|
4
|
-
export function createLabelmapMemo(segmentationId, segmentationVoxelManager
|
|
5
|
-
return
|
|
6
|
-
? createPreviewMemo(segmentationId, preview)
|
|
7
|
-
: createRleMemo(segmentationId, segmentationVoxelManager);
|
|
5
|
+
export function createLabelmapMemo(segmentationId, segmentationVoxelManager) {
|
|
6
|
+
return createRleMemo(segmentationId, segmentationVoxelManager);
|
|
8
7
|
}
|
|
9
8
|
export function restoreMemo(isUndo) {
|
|
10
9
|
const { segmentationVoxelManager, undoVoxelManager, redoVoxelManager } = this;
|
|
@@ -23,19 +22,8 @@ export function createRleMemo(segmentationId, segmentationVoxelManager) {
|
|
|
23
22
|
commitMemo,
|
|
24
23
|
segmentationVoxelManager,
|
|
25
24
|
voxelManager,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
export function createPreviewMemo(segmentationId, preview) {
|
|
30
|
-
const { memo: previewMemo, segmentationVoxelManager, previewVoxelManager, } = preview;
|
|
31
|
-
const state = {
|
|
32
|
-
segmentationId,
|
|
33
|
-
restoreMemo,
|
|
34
|
-
commitMemo,
|
|
35
|
-
segmentationVoxelManager,
|
|
36
|
-
voxelManager: previewVoxelManager,
|
|
37
|
-
memo: previewMemo,
|
|
38
|
-
preview,
|
|
25
|
+
id: utilities.uuidv4(),
|
|
26
|
+
operationType: 'labelmap',
|
|
39
27
|
};
|
|
40
28
|
return state;
|
|
41
29
|
}
|
|
@@ -28,11 +28,11 @@ export default class IslandRemoval {
|
|
|
28
28
|
? segmentationVoxels
|
|
29
29
|
: VoxelManager.createRLEHistoryVoxelManager(segmentationVoxelManager);
|
|
30
30
|
const { segmentIndex = 1, previewSegmentIndex = 1 } = options;
|
|
31
|
-
const clickedPoints = options.points ||
|
|
31
|
+
const clickedPoints = options.points || segmentationVoxelManager.getPoints();
|
|
32
32
|
if (!clickedPoints?.length) {
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
|
-
const boundsIJK =
|
|
35
|
+
const boundsIJK = segmentationVoxelManager
|
|
36
36
|
.getBoundsIJK()
|
|
37
37
|
.map((bound, i) => [
|
|
38
38
|
Math.min(bound[0], ...clickedPoints.map((point) => point[i])),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/tools",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.1",
|
|
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": "^3.1.0"
|
|
104
104
|
},
|
|
105
105
|
"peerDependencies": {
|
|
106
|
-
"@cornerstonejs/core": "^3.
|
|
106
|
+
"@cornerstonejs/core": "^3.8.1",
|
|
107
107
|
"@kitware/vtk.js": "32.12.1",
|
|
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": "1f45d352ecb6e239cb418f085cdabeca2a4520a9"
|
|
126
126
|
}
|