@cornerstonejs/tools 2.7.4 → 2.8.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/enums/ChangeTypes.d.ts +2 -1
- package/dist/esm/enums/ChangeTypes.js +1 -0
- package/dist/esm/store/filterToolsWithAnnotationsForElement.js +1 -1
- package/dist/esm/tools/AnnotationEraserTool.js +8 -4
- package/dist/esm/tools/CrosshairsTool.js +1 -1
- package/dist/esm/tools/PanTool.d.ts +0 -1
- package/dist/esm/tools/PanTool.js +0 -5
- package/dist/esm/tools/ZoomTool.js +0 -2
- package/dist/esm/tools/annotation/ArrowAnnotateTool.js +4 -1
- package/dist/esm/tools/annotation/BidirectionalTool.js +6 -5
- package/dist/esm/tools/annotation/CircleROITool.js +6 -3
- package/dist/esm/tools/annotation/CobbAngleTool.d.ts +2 -2
- package/dist/esm/tools/annotation/CobbAngleTool.js +19 -19
- package/dist/esm/tools/annotation/EllipticalROITool.js +6 -6
- package/dist/esm/tools/annotation/KeyImageTool.d.ts +1 -2
- package/dist/esm/tools/annotation/KeyImageTool.js +5 -1
- package/dist/esm/tools/annotation/LengthTool.js +4 -1
- package/dist/esm/tools/annotation/LivewireContourTool.js +9 -5
- package/dist/esm/tools/annotation/ProbeTool.js +6 -5
- package/dist/esm/tools/annotation/RectangleROITool.js +3 -2
- package/dist/esm/tools/annotation/SplineROITool.js +4 -4
- package/dist/esm/tools/annotation/VideoRedactionTool.d.ts +2 -2
- package/dist/esm/tools/annotation/VideoRedactionTool.js +27 -29
- package/dist/esm/tools/annotation/planarFreehandROITool/closedContourEditLoop.js +7 -3
- package/dist/esm/tools/annotation/planarFreehandROITool/drawLoop.js +6 -2
- package/dist/esm/tools/annotation/planarFreehandROITool/openContourEditLoop.js +6 -2
- package/dist/esm/tools/base/AnnotationDisplayTool.d.ts +1 -1
- package/dist/esm/tools/base/AnnotationDisplayTool.js +2 -2
- package/dist/esm/tools/base/AnnotationTool.d.ts +30 -0
- package/dist/esm/tools/base/AnnotationTool.js +85 -1
- package/dist/esm/tools/base/BaseTool.d.ts +1 -0
- package/dist/esm/tools/base/BaseTool.js +7 -1
- package/dist/esm/tools/base/ContourSegmentationBaseTool.js +0 -4
- package/dist/esm/tools/segmentation/BrushTool.js +1 -0
- package/dist/esm/tools/segmentation/CircleScissorsTool.d.ts +4 -2
- package/dist/esm/tools/segmentation/CircleScissorsTool.js +4 -1
- package/dist/esm/tools/segmentation/LabelmapBaseTool.d.ts +6 -1
- package/dist/esm/tools/segmentation/LabelmapBaseTool.js +6 -1
- package/dist/esm/tools/segmentation/PaintFillTool.js +1 -1
- package/dist/esm/tools/segmentation/RectangleScissorsTool.d.ts +2 -2
- package/dist/esm/tools/segmentation/RectangleScissorsTool.js +6 -2
- package/dist/esm/tools/segmentation/SphereScissorsTool.d.ts +2 -2
- package/dist/esm/tools/segmentation/SphereScissorsTool.js +5 -1
- package/dist/esm/tools/segmentation/strategies/BrushStrategy.d.ts +2 -0
- package/dist/esm/tools/segmentation/strategies/compositions/preview.js +15 -13
- package/dist/esm/tools/segmentation/strategies/compositions/setValue.js +2 -1
- package/dist/esm/tools/segmentation/strategies/fillRectangle.d.ts +6 -8
- package/dist/esm/tools/segmentation/strategies/fillRectangle.js +29 -30
- package/dist/esm/tools/segmentation/strategies/index.d.ts +2 -2
- package/dist/esm/tools/segmentation/strategies/index.js +2 -2
- package/dist/esm/types/ContourAnnotation.d.ts +2 -0
- package/dist/esm/types/LabelmapToolOperationData.d.ts +2 -0
- package/dist/esm/utilities/math/polyline/planarFreehandROIInternalTypes.d.ts +1 -0
- package/dist/esm/utilities/planar/filterAnnotationsWithinSlice.js +4 -0
- package/dist/esm/utilities/segmentation/createLabelmapMemo.d.ts +44 -0
- package/dist/esm/utilities/segmentation/createLabelmapMemo.js +68 -0
- package/dist/esm/utilities/segmentation/index.d.ts +2 -1
- package/dist/esm/utilities/segmentation/index.js +2 -1
- package/package.json +3 -3
|
@@ -8,7 +8,8 @@ import { resetElementCursor, hideElementCursor, } from '../../cursors/elementCur
|
|
|
8
8
|
import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds';
|
|
9
9
|
import { config as segmentationConfig, segmentLocking, segmentIndex as segmentIndexController, activeSegmentation, } from '../../stateManagement/segmentation';
|
|
10
10
|
import { getSegmentation } from '../../stateManagement/segmentation/segmentationState';
|
|
11
|
-
|
|
11
|
+
import LabelmapBaseTool from './LabelmapBaseTool';
|
|
12
|
+
class SphereScissorsTool extends LabelmapBaseTool {
|
|
12
13
|
constructor(toolProps = {}, defaultToolProps = {
|
|
13
14
|
supportedInteractionTypes: ['Mouse', 'Touch'],
|
|
14
15
|
configuration: {
|
|
@@ -25,6 +26,7 @@ class SphereScissorsTool extends BaseTool {
|
|
|
25
26
|
if (this.isDrawing === true) {
|
|
26
27
|
return;
|
|
27
28
|
}
|
|
29
|
+
this.doneEditMemo();
|
|
28
30
|
const eventDetail = evt.detail;
|
|
29
31
|
const { currentPoints, element } = eventDetail;
|
|
30
32
|
const worldPos = currentPoints.world;
|
|
@@ -165,10 +167,12 @@ class SphereScissorsTool extends BaseTool {
|
|
|
165
167
|
segmentsLocked,
|
|
166
168
|
viewPlaneNormal,
|
|
167
169
|
viewUp,
|
|
170
|
+
createMemo: this.createMemo.bind(this),
|
|
168
171
|
};
|
|
169
172
|
this.editData = null;
|
|
170
173
|
this.isDrawing = false;
|
|
171
174
|
this.applyActiveStrategy(enabledElement, operationData);
|
|
175
|
+
this.doneEditMemo();
|
|
172
176
|
};
|
|
173
177
|
this._activateDraw = (element) => {
|
|
174
178
|
element.addEventListener(Events.MOUSE_UP, this._endCallback);
|
|
@@ -2,6 +2,7 @@ import type { Types } from '@cornerstonejs/core';
|
|
|
2
2
|
import { StrategyCallbacks } from '../../../enums';
|
|
3
3
|
import type { LabelmapToolOperationDataAny } from '../../../types/LabelmapToolOperationData';
|
|
4
4
|
import type vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
|
|
5
|
+
import type { LabelmapMemo } from '../../../utilities/segmentation/createLabelmapMemo';
|
|
5
6
|
export type InitializedOperationData = LabelmapToolOperationDataAny & {
|
|
6
7
|
operationName?: string;
|
|
7
8
|
enabledElement: Types.IEnabledElement;
|
|
@@ -17,6 +18,7 @@ export type InitializedOperationData = LabelmapToolOperationDataAny & {
|
|
|
17
18
|
previewSegmentIndex?: number;
|
|
18
19
|
brushStrategy: BrushStrategy;
|
|
19
20
|
configuration?: Record<string, any>;
|
|
21
|
+
memo?: LabelmapMemo;
|
|
20
22
|
};
|
|
21
23
|
export type StrategyFunction = (operationData: InitializedOperationData, ...args: any[]) => unknown;
|
|
22
24
|
export type CompositionInstance = {
|
|
@@ -29,8 +29,9 @@ export default {
|
|
|
29
29
|
return preview;
|
|
30
30
|
},
|
|
31
31
|
[StrategyCallbacks.Initialize]: (operationData) => {
|
|
32
|
-
const { segmentIndex, previewSegmentIndex, previewColors, preview } = operationData;
|
|
33
|
-
if (previewColors === undefined) {
|
|
32
|
+
const { segmentIndex, previewSegmentIndex, previewColors, preview, segmentationId, segmentationVoxelManager, } = operationData;
|
|
33
|
+
if (previewColors === undefined || !previewSegmentIndex) {
|
|
34
|
+
operationData.memo = operationData.createMemo(segmentationId, segmentationVoxelManager);
|
|
34
35
|
return;
|
|
35
36
|
}
|
|
36
37
|
if (preview) {
|
|
@@ -38,9 +39,7 @@ export default {
|
|
|
38
39
|
operationData.segmentationVoxelManager;
|
|
39
40
|
operationData.previewVoxelManager = preview.previewVoxelManager;
|
|
40
41
|
}
|
|
41
|
-
if (segmentIndex ===
|
|
42
|
-
segmentIndex === null ||
|
|
43
|
-
!previewSegmentIndex) {
|
|
42
|
+
if (segmentIndex === null) {
|
|
44
43
|
return;
|
|
45
44
|
}
|
|
46
45
|
const configColor = previewColors?.[segmentIndex];
|
|
@@ -52,24 +51,27 @@ export default {
|
|
|
52
51
|
setSegmentIndexColor(operationData.viewport.id, operationData.segmentationId, previewSegmentIndex, previewColor);
|
|
53
52
|
},
|
|
54
53
|
[StrategyCallbacks.AcceptPreview]: (operationData) => {
|
|
55
|
-
const { segmentationVoxelManager, previewVoxelManager: previewVoxelManager, previewSegmentIndex, preview, } = operationData || {};
|
|
54
|
+
const { segmentationVoxelManager, previewVoxelManager: previewVoxelManager, previewSegmentIndex, segmentationId, preview, } = operationData || {};
|
|
56
55
|
if (previewSegmentIndex === undefined) {
|
|
57
56
|
return;
|
|
58
57
|
}
|
|
59
58
|
const segmentIndex = preview?.segmentIndex ?? operationData.segmentIndex;
|
|
60
|
-
|
|
61
|
-
if (!tracking || tracking.modifiedSlices.size === 0) {
|
|
59
|
+
if (!previewVoxelManager || previewVoxelManager.modifiedSlices.size === 0) {
|
|
62
60
|
return;
|
|
63
61
|
}
|
|
64
|
-
const
|
|
62
|
+
const memo = operationData.createMemo(segmentationId, segmentationVoxelManager);
|
|
63
|
+
operationData.memo = memo;
|
|
64
|
+
const { voxelManager } = memo;
|
|
65
|
+
const callback = ({ index, value }) => {
|
|
65
66
|
const oldValue = segmentationVoxelManager.getAtIndex(index);
|
|
66
67
|
if (oldValue === previewSegmentIndex) {
|
|
67
|
-
segmentationVoxelManager.setAtIndex(index,
|
|
68
|
+
segmentationVoxelManager.setAtIndex(index, value);
|
|
69
|
+
voxelManager.setAtIndex(index, segmentIndex);
|
|
68
70
|
}
|
|
69
71
|
};
|
|
70
|
-
|
|
71
|
-
triggerSegmentationDataModified(operationData.segmentationId,
|
|
72
|
-
|
|
72
|
+
previewVoxelManager.forEach(callback, {});
|
|
73
|
+
triggerSegmentationDataModified(operationData.segmentationId, previewVoxelManager.getArrayOfModifiedSlices(), preview.segmentIndex);
|
|
74
|
+
previewVoxelManager.clear();
|
|
73
75
|
},
|
|
74
76
|
[StrategyCallbacks.RejectPreview]: (operationData) => {
|
|
75
77
|
const { previewVoxelManager: previewVoxelManager, segmentationVoxelManager, } = operationData;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
|
|
2
2
|
export default {
|
|
3
3
|
[StrategyCallbacks.INTERNAL_setValue]: (operationData, { value, index }) => {
|
|
4
|
-
const { segmentsLocked, segmentIndex,
|
|
4
|
+
const { segmentsLocked, segmentIndex, previewSegmentIndex, segmentationVoxelManager, memo, } = operationData;
|
|
5
|
+
const previewVoxelManager = memo?.voxelManager || operationData.previewVoxelManager;
|
|
5
6
|
const existingValue = segmentationVoxelManager.getAtIndex(index);
|
|
6
7
|
let changed = false;
|
|
7
8
|
if (segmentIndex === null) {
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export
|
|
7
|
-
export declare function fillOutsideRectangle(enabledElement: Types.IEnabledElement, operationData: OperationData): void;
|
|
8
|
-
export {};
|
|
1
|
+
import BrushStrategy from './BrushStrategy';
|
|
2
|
+
declare const RECTANGLE_STRATEGY: BrushStrategy;
|
|
3
|
+
declare const RECTANGLE_THRESHOLD_STRATEGY: BrushStrategy;
|
|
4
|
+
declare const fillInsideRectangle: (enabledElement: any, operationData: any) => unknown;
|
|
5
|
+
declare const thresholdInsideRectangle: (enabledElement: any, operationData: any) => unknown;
|
|
6
|
+
export { RECTANGLE_STRATEGY, RECTANGLE_THRESHOLD_STRATEGY, fillInsideRectangle, thresholdInsideRectangle, };
|
|
@@ -1,21 +1,32 @@
|
|
|
1
|
+
import { vec3 } from 'gl-matrix';
|
|
1
2
|
import { utilities as csUtils, StackViewport } from '@cornerstonejs/core';
|
|
2
3
|
import { getBoundingBoxAroundShapeIJK, getBoundingBoxAroundShapeWorld, } from '../../../utilities/boundingBox';
|
|
3
4
|
import { triggerSegmentationDataModified } from '../../../stateManagement/segmentation/triggerSegmentationEvents';
|
|
4
5
|
import { getStrategyData } from './utils/getStrategyData';
|
|
5
6
|
import { isAxisAlignedRectangle } from '../../../utilities/rectangleROITool/isAxisAlignedRectangle';
|
|
7
|
+
import BrushStrategy from './BrushStrategy';
|
|
8
|
+
import { StrategyCallbacks } from '../../../enums';
|
|
9
|
+
import compositions from './compositions';
|
|
6
10
|
const { transformWorldToIndex } = csUtils;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
const initializeRectangle = {
|
|
12
|
+
[StrategyCallbacks.Initialize]: (operationData) => {
|
|
13
|
+
const { points, imageVoxelManager, viewport, segmentationImageData, segmentationVoxelManager, } = operationData;
|
|
14
|
+
if (!points) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const center = vec3.fromValues(0, 0, 0);
|
|
18
|
+
points.forEach((point) => {
|
|
19
|
+
vec3.add(center, center, point);
|
|
20
|
+
});
|
|
21
|
+
vec3.scale(center, center, 1 / points.length);
|
|
22
|
+
operationData.centerWorld = center;
|
|
23
|
+
operationData.centerIJK = transformWorldToIndex(segmentationImageData, center);
|
|
24
|
+
const { boundsIJK, pointInShapeFn } = createPointInRectangle(viewport, points, segmentationImageData);
|
|
25
|
+
operationData.isInObject = pointInShapeFn;
|
|
26
|
+
operationData.isInObjectBoundsIJK = boundsIJK;
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
function createPointInRectangle(viewport, points, segmentationImageData) {
|
|
19
30
|
let rectangleCornersIJK = points.map((world) => {
|
|
20
31
|
return transformWorldToIndex(segmentationImageData, world);
|
|
21
32
|
});
|
|
@@ -51,22 +62,10 @@ function fillRectangle(enabledElement, operationData) {
|
|
|
51
62
|
const zInside = z >= zMin && z <= zMax;
|
|
52
63
|
return xInside && yInside && zInside;
|
|
53
64
|
};
|
|
54
|
-
|
|
55
|
-
if (segmentsLocked.includes(value)) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
segmentationVoxelManager.setAtIndex(index, segmentIndex);
|
|
59
|
-
};
|
|
60
|
-
segmentationVoxelManager.forEach(callback, {
|
|
61
|
-
isInObject: pointInShapeFn,
|
|
62
|
-
boundsIJK,
|
|
63
|
-
imageData: segmentationImageData,
|
|
64
|
-
});
|
|
65
|
-
triggerSegmentationDataModified(segmentationId);
|
|
66
|
-
}
|
|
67
|
-
export function fillInsideRectangle(enabledElement, operationData) {
|
|
68
|
-
fillRectangle(enabledElement, operationData);
|
|
69
|
-
}
|
|
70
|
-
export function fillOutsideRectangle(enabledElement, operationData) {
|
|
71
|
-
fillRectangle(enabledElement, operationData);
|
|
65
|
+
return { boundsIJK, pointInShapeFn };
|
|
72
66
|
}
|
|
67
|
+
const RECTANGLE_STRATEGY = new BrushStrategy('Rectangle', compositions.regionFill, compositions.setValue, initializeRectangle, compositions.determineSegmentIndex, compositions.preview, compositions.labelmapStatistics);
|
|
68
|
+
const RECTANGLE_THRESHOLD_STRATEGY = new BrushStrategy('RectangleThreshold', compositions.regionFill, compositions.setValue, initializeRectangle, compositions.determineSegmentIndex, compositions.dynamicThreshold, compositions.threshold, compositions.preview, compositions.islandRemoval, compositions.labelmapStatistics);
|
|
69
|
+
const fillInsideRectangle = RECTANGLE_STRATEGY.strategyFunction;
|
|
70
|
+
const thresholdInsideRectangle = RECTANGLE_THRESHOLD_STRATEGY.strategyFunction;
|
|
71
|
+
export { RECTANGLE_STRATEGY, RECTANGLE_THRESHOLD_STRATEGY, fillInsideRectangle, thresholdInsideRectangle, };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { fillInsideRectangle,
|
|
1
|
+
import { fillInsideRectangle, thresholdInsideRectangle } from './fillRectangle';
|
|
2
2
|
import { fillInsideCircle, fillOutsideCircle } from './fillCircle';
|
|
3
|
-
export { fillInsideRectangle,
|
|
3
|
+
export { fillInsideRectangle, thresholdInsideRectangle, fillInsideCircle, fillOutsideCircle, };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { fillInsideRectangle,
|
|
1
|
+
import { fillInsideRectangle, thresholdInsideRectangle } from './fillRectangle';
|
|
2
2
|
import { fillInsideCircle, fillOutsideCircle } from './fillCircle';
|
|
3
|
-
export { fillInsideRectangle,
|
|
3
|
+
export { fillInsideRectangle, thresholdInsideRectangle, fillInsideCircle, fillOutsideCircle, };
|
|
@@ -7,10 +7,12 @@ export declare enum ContourWindingDirection {
|
|
|
7
7
|
}
|
|
8
8
|
export type ContourAnnotationData = {
|
|
9
9
|
data: {
|
|
10
|
+
cachedStats?: Record<string, unknown>;
|
|
10
11
|
contour: {
|
|
11
12
|
polyline: Types.Point3[];
|
|
12
13
|
closed: boolean;
|
|
13
14
|
windingDirection?: ContourWindingDirection;
|
|
15
|
+
pointsManager?: Types.IPointsManager<Types.Point3>;
|
|
14
16
|
};
|
|
15
17
|
};
|
|
16
18
|
onInterpolationComplete?: () => void;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Types } from '@cornerstonejs/core';
|
|
2
2
|
import type { LabelmapSegmentationDataStack, LabelmapSegmentationDataVolume } from './LabelmapTypes';
|
|
3
3
|
import type vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
|
|
4
|
+
import type { LabelmapMemo } from '../utilities/segmentation/createLabelmapMemo';
|
|
4
5
|
type LabelmapToolOperationData = {
|
|
5
6
|
segmentationId: string;
|
|
6
7
|
segmentIndex: number;
|
|
@@ -17,6 +18,7 @@ type LabelmapToolOperationData = {
|
|
|
17
18
|
};
|
|
18
19
|
preview: any;
|
|
19
20
|
toolGroupId: string;
|
|
21
|
+
createMemo: (segmentId: any, segmentVoxels: any, previewVoxels?: any, previewMemo?: any) => LabelmapMemo;
|
|
20
22
|
};
|
|
21
23
|
type LabelmapToolOperationDataStack = LabelmapToolOperationData & LabelmapSegmentationDataStack;
|
|
22
24
|
type LabelmapToolOperationDataVolume = LabelmapToolOperationData & LabelmapSegmentationDataVolume;
|
|
@@ -32,6 +32,10 @@ export default function filterAnnotationsWithinSlice(annotations, camera, spacin
|
|
|
32
32
|
continue;
|
|
33
33
|
}
|
|
34
34
|
const dir = vec3.create();
|
|
35
|
+
if (!point) {
|
|
36
|
+
annotationsWithinSlice.push(annotation);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
35
39
|
vec3.sub(dir, focalPoint, point);
|
|
36
40
|
const dot = vec3.dot(dir, viewPlaneNormal);
|
|
37
41
|
if (Math.abs(dot) < halfSpacingInNormalDirection) {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { utilities } from '@cornerstonejs/core';
|
|
2
|
+
import type { Types } from '@cornerstonejs/core';
|
|
3
|
+
import type { InitializedOperationData } from '../../tools/segmentation/strategies/BrushStrategy';
|
|
4
|
+
export type LabelmapMemo = Types.Memo & {
|
|
5
|
+
segmentationVoxelManager: Types.IVoxelManager<number>;
|
|
6
|
+
voxelManager: Types.IVoxelManager<number>;
|
|
7
|
+
redoVoxelManager?: Types.IVoxelManager<number>;
|
|
8
|
+
undoVoxelManager?: Types.IVoxelManager<number>;
|
|
9
|
+
memo?: LabelmapMemo;
|
|
10
|
+
};
|
|
11
|
+
export declare function createLabelmapMemo<T>(segmentationId: string, segmentationVoxelManager: Types.IVoxelManager<T>, preview?: InitializedOperationData): {
|
|
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
|
+
} | {
|
|
20
|
+
segmentationId: string;
|
|
21
|
+
restoreMemo: typeof restoreMemo;
|
|
22
|
+
commitMemo: typeof commitMemo;
|
|
23
|
+
segmentationVoxelManager: Types.IVoxelManager<T>;
|
|
24
|
+
voxelManager: utilities.VoxelManager<T>;
|
|
25
|
+
};
|
|
26
|
+
export declare function restoreMemo(isUndo?: boolean): void;
|
|
27
|
+
export declare function createRleMemo<T>(segmentationId: string, segmentationVoxelManager: Types.IVoxelManager<T>): {
|
|
28
|
+
segmentationId: string;
|
|
29
|
+
restoreMemo: typeof restoreMemo;
|
|
30
|
+
commitMemo: typeof commitMemo;
|
|
31
|
+
segmentationVoxelManager: Types.IVoxelManager<T>;
|
|
32
|
+
voxelManager: utilities.VoxelManager<T>;
|
|
33
|
+
};
|
|
34
|
+
export declare function createPreviewMemo(segmentationId: string, preview: InitializedOperationData): {
|
|
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;
|
|
42
|
+
};
|
|
43
|
+
declare function commitMemo(): boolean;
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { utilities } from '@cornerstonejs/core';
|
|
2
|
+
import { triggerSegmentationDataModified } from '../../stateManagement/segmentation/triggerSegmentationEvents';
|
|
3
|
+
const { VoxelManager, RLEVoxelMap } = utilities;
|
|
4
|
+
export function createLabelmapMemo(segmentationId, segmentationVoxelManager, preview) {
|
|
5
|
+
return preview
|
|
6
|
+
? createPreviewMemo(segmentationId, preview)
|
|
7
|
+
: createRleMemo(segmentationId, segmentationVoxelManager);
|
|
8
|
+
}
|
|
9
|
+
export function restoreMemo(isUndo) {
|
|
10
|
+
const { segmentationVoxelManager, undoVoxelManager, redoVoxelManager } = this;
|
|
11
|
+
const useVoxelManager = isUndo === false ? redoVoxelManager : undoVoxelManager;
|
|
12
|
+
useVoxelManager.forEach(({ value, pointIJK }) => {
|
|
13
|
+
segmentationVoxelManager.setAtIJKPoint(pointIJK, value);
|
|
14
|
+
});
|
|
15
|
+
const slices = useVoxelManager.getArrayOfModifiedSlices();
|
|
16
|
+
triggerSegmentationDataModified(this.segmentationId, slices);
|
|
17
|
+
}
|
|
18
|
+
export function createRleMemo(segmentationId, segmentationVoxelManager) {
|
|
19
|
+
const voxelManager = VoxelManager.createRLEHistoryVoxelManager(segmentationVoxelManager);
|
|
20
|
+
const state = {
|
|
21
|
+
segmentationId,
|
|
22
|
+
restoreMemo,
|
|
23
|
+
commitMemo,
|
|
24
|
+
segmentationVoxelManager,
|
|
25
|
+
voxelManager,
|
|
26
|
+
};
|
|
27
|
+
return state;
|
|
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,
|
|
39
|
+
};
|
|
40
|
+
return state;
|
|
41
|
+
}
|
|
42
|
+
function commitMemo() {
|
|
43
|
+
if (this.redoVoxelManager) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
if (!this.voxelManager.modifiedSlices.size) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
const { segmentationVoxelManager } = this;
|
|
50
|
+
const undoVoxelManager = VoxelManager.createRLEHistoryVoxelManager(segmentationVoxelManager);
|
|
51
|
+
RLEVoxelMap.copyMap(undoVoxelManager.map, this.voxelManager.map);
|
|
52
|
+
for (const key of this.voxelManager.modifiedSlices.keys()) {
|
|
53
|
+
undoVoxelManager.modifiedSlices.add(key);
|
|
54
|
+
}
|
|
55
|
+
this.undoVoxelManager = undoVoxelManager;
|
|
56
|
+
const redoVoxelManager = VoxelManager.createRLEVolumeVoxelManager({
|
|
57
|
+
dimensions: this.segmentationVoxelManager.dimensions,
|
|
58
|
+
});
|
|
59
|
+
this.redoVoxelManager = redoVoxelManager;
|
|
60
|
+
undoVoxelManager.forEach(({ index, pointIJK, value }) => {
|
|
61
|
+
const currentValue = segmentationVoxelManager.getAtIJKPoint(pointIJK);
|
|
62
|
+
if (currentValue === value) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
redoVoxelManager.setAtIndex(index, currentValue);
|
|
66
|
+
});
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
@@ -18,4 +18,5 @@ import { getSegmentIndexAtLabelmapBorder } from './getSegmentIndexAtLabelmapBord
|
|
|
18
18
|
import { getHoveredContourSegmentationAnnotation } from './getHoveredContourSegmentationAnnotation';
|
|
19
19
|
import { getBrushToolInstances } from './getBrushToolInstances';
|
|
20
20
|
import * as growCut from './growCut';
|
|
21
|
-
|
|
21
|
+
import * as LabelmapMemo from './createLabelmapMemo';
|
|
22
|
+
export { thresholdVolumeByRange, createMergedLabelmapForIndex, createLabelmapVolumeForViewport, rectangleROIThresholdVolumeByRange, triggerSegmentationRender, triggerSegmentationRenderBySegmentationId, floodFill, getBrushSizeForToolGroup, setBrushSizeForToolGroup, getBrushThresholdForToolGroup, setBrushThresholdForToolGroup, VolumetricCalculator, thresholdSegmentationByRange, contourAndFindLargestBidirectional, createBidirectionalToolData, segmentContourAction, invalidateBrushCursor, getUniqueSegmentIndices, getSegmentIndexAtWorldPoint, getSegmentIndexAtLabelmapBorder, getHoveredContourSegmentationAnnotation, getBrushToolInstances, growCut, LabelmapMemo, };
|
|
@@ -18,4 +18,5 @@ import { getSegmentIndexAtLabelmapBorder } from './getSegmentIndexAtLabelmapBord
|
|
|
18
18
|
import { getHoveredContourSegmentationAnnotation } from './getHoveredContourSegmentationAnnotation';
|
|
19
19
|
import { getBrushToolInstances } from './getBrushToolInstances';
|
|
20
20
|
import * as growCut from './growCut';
|
|
21
|
-
|
|
21
|
+
import * as LabelmapMemo from './createLabelmapMemo';
|
|
22
|
+
export { thresholdVolumeByRange, createMergedLabelmapForIndex, createLabelmapVolumeForViewport, rectangleROIThresholdVolumeByRange, triggerSegmentationRender, triggerSegmentationRenderBySegmentationId, floodFill, getBrushSizeForToolGroup, setBrushSizeForToolGroup, getBrushThresholdForToolGroup, setBrushThresholdForToolGroup, VolumetricCalculator, thresholdSegmentationByRange, contourAndFindLargestBidirectional, createBidirectionalToolData, segmentContourAction, invalidateBrushCursor, getUniqueSegmentIndices, getSegmentIndexAtWorldPoint, getSegmentIndexAtLabelmapBorder, getHoveredContourSegmentationAnnotation, getBrushToolInstances, growCut, LabelmapMemo, };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/tools",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "Cornerstone3D Tools",
|
|
5
5
|
"types": "./dist/esm/index.d.ts",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
"canvas": "^2.11.2"
|
|
105
105
|
},
|
|
106
106
|
"peerDependencies": {
|
|
107
|
-
"@cornerstonejs/core": "^2.
|
|
107
|
+
"@cornerstonejs/core": "^2.8.0",
|
|
108
108
|
"@kitware/vtk.js": "32.1.1",
|
|
109
109
|
"@types/d3-array": "^3.0.4",
|
|
110
110
|
"@types/d3-interpolate": "^3.0.1",
|
|
@@ -123,5 +123,5 @@
|
|
|
123
123
|
"type": "individual",
|
|
124
124
|
"url": "https://ohif.org/donate"
|
|
125
125
|
},
|
|
126
|
-
"gitHead": "
|
|
126
|
+
"gitHead": "64b1f664e114d73546cf88099bf427a4f563aabd"
|
|
127
127
|
}
|