@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.
Files changed (59) hide show
  1. package/dist/esm/enums/ChangeTypes.d.ts +2 -1
  2. package/dist/esm/enums/ChangeTypes.js +1 -0
  3. package/dist/esm/store/filterToolsWithAnnotationsForElement.js +1 -1
  4. package/dist/esm/tools/AnnotationEraserTool.js +8 -4
  5. package/dist/esm/tools/CrosshairsTool.js +1 -1
  6. package/dist/esm/tools/PanTool.d.ts +0 -1
  7. package/dist/esm/tools/PanTool.js +0 -5
  8. package/dist/esm/tools/ZoomTool.js +0 -2
  9. package/dist/esm/tools/annotation/ArrowAnnotateTool.js +4 -1
  10. package/dist/esm/tools/annotation/BidirectionalTool.js +6 -5
  11. package/dist/esm/tools/annotation/CircleROITool.js +6 -3
  12. package/dist/esm/tools/annotation/CobbAngleTool.d.ts +2 -2
  13. package/dist/esm/tools/annotation/CobbAngleTool.js +19 -19
  14. package/dist/esm/tools/annotation/EllipticalROITool.js +6 -6
  15. package/dist/esm/tools/annotation/KeyImageTool.d.ts +1 -2
  16. package/dist/esm/tools/annotation/KeyImageTool.js +5 -1
  17. package/dist/esm/tools/annotation/LengthTool.js +4 -1
  18. package/dist/esm/tools/annotation/LivewireContourTool.js +9 -5
  19. package/dist/esm/tools/annotation/ProbeTool.js +6 -5
  20. package/dist/esm/tools/annotation/RectangleROITool.js +3 -2
  21. package/dist/esm/tools/annotation/SplineROITool.js +4 -4
  22. package/dist/esm/tools/annotation/VideoRedactionTool.d.ts +2 -2
  23. package/dist/esm/tools/annotation/VideoRedactionTool.js +27 -29
  24. package/dist/esm/tools/annotation/planarFreehandROITool/closedContourEditLoop.js +7 -3
  25. package/dist/esm/tools/annotation/planarFreehandROITool/drawLoop.js +6 -2
  26. package/dist/esm/tools/annotation/planarFreehandROITool/openContourEditLoop.js +6 -2
  27. package/dist/esm/tools/base/AnnotationDisplayTool.d.ts +1 -1
  28. package/dist/esm/tools/base/AnnotationDisplayTool.js +2 -2
  29. package/dist/esm/tools/base/AnnotationTool.d.ts +30 -0
  30. package/dist/esm/tools/base/AnnotationTool.js +85 -1
  31. package/dist/esm/tools/base/BaseTool.d.ts +1 -0
  32. package/dist/esm/tools/base/BaseTool.js +7 -1
  33. package/dist/esm/tools/base/ContourSegmentationBaseTool.js +0 -4
  34. package/dist/esm/tools/segmentation/BrushTool.js +1 -0
  35. package/dist/esm/tools/segmentation/CircleScissorsTool.d.ts +4 -2
  36. package/dist/esm/tools/segmentation/CircleScissorsTool.js +4 -1
  37. package/dist/esm/tools/segmentation/LabelmapBaseTool.d.ts +6 -1
  38. package/dist/esm/tools/segmentation/LabelmapBaseTool.js +6 -1
  39. package/dist/esm/tools/segmentation/PaintFillTool.js +1 -1
  40. package/dist/esm/tools/segmentation/RectangleScissorsTool.d.ts +2 -2
  41. package/dist/esm/tools/segmentation/RectangleScissorsTool.js +6 -2
  42. package/dist/esm/tools/segmentation/SphereScissorsTool.d.ts +2 -2
  43. package/dist/esm/tools/segmentation/SphereScissorsTool.js +5 -1
  44. package/dist/esm/tools/segmentation/strategies/BrushStrategy.d.ts +2 -0
  45. package/dist/esm/tools/segmentation/strategies/compositions/preview.js +15 -13
  46. package/dist/esm/tools/segmentation/strategies/compositions/setValue.js +2 -1
  47. package/dist/esm/tools/segmentation/strategies/fillRectangle.d.ts +6 -8
  48. package/dist/esm/tools/segmentation/strategies/fillRectangle.js +29 -30
  49. package/dist/esm/tools/segmentation/strategies/index.d.ts +2 -2
  50. package/dist/esm/tools/segmentation/strategies/index.js +2 -2
  51. package/dist/esm/types/ContourAnnotation.d.ts +2 -0
  52. package/dist/esm/types/LabelmapToolOperationData.d.ts +2 -0
  53. package/dist/esm/utilities/math/polyline/planarFreehandROIInternalTypes.d.ts +1 -0
  54. package/dist/esm/utilities/planar/filterAnnotationsWithinSlice.js +4 -0
  55. package/dist/esm/utilities/segmentation/createLabelmapMemo.d.ts +44 -0
  56. package/dist/esm/utilities/segmentation/createLabelmapMemo.js +68 -0
  57. package/dist/esm/utilities/segmentation/index.d.ts +2 -1
  58. package/dist/esm/utilities/segmentation/index.js +2 -1
  59. 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
- class SphereScissorsTool extends BaseTool {
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 === undefined ||
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
- const tracking = previewVoxelManager;
61
- if (!tracking || tracking.modifiedSlices.size === 0) {
59
+ if (!previewVoxelManager || previewVoxelManager.modifiedSlices.size === 0) {
62
60
  return;
63
61
  }
64
- const callback = ({ index }) => {
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, segmentIndex);
68
+ segmentationVoxelManager.setAtIndex(index, value);
69
+ voxelManager.setAtIndex(index, segmentIndex);
68
70
  }
69
71
  };
70
- tracking.forEach(callback, {});
71
- triggerSegmentationDataModified(operationData.segmentationId, tracking.getArrayOfModifiedSlices(), preview.segmentIndex);
72
- tracking.clear();
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, previewVoxelManager, previewSegmentIndex, segmentationVoxelManager, } = operationData;
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 type { Types } from '@cornerstonejs/core';
2
- import type { LabelmapToolOperationData } from '../../../types';
3
- type OperationData = LabelmapToolOperationData & {
4
- points: [Types.Point3, Types.Point3, Types.Point3, Types.Point3];
5
- };
6
- export declare function fillInsideRectangle(enabledElement: Types.IEnabledElement, operationData: OperationData): void;
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
- function fillRectangle(enabledElement, operationData) {
8
- const { points, segmentsLocked, segmentIndex, segmentationId } = operationData;
9
- const { viewport } = enabledElement;
10
- const strategyData = getStrategyData({
11
- operationData,
12
- viewport: enabledElement.viewport,
13
- });
14
- if (!strategyData) {
15
- console.warn('No data found for fillRectangle');
16
- return;
17
- }
18
- const { segmentationImageData, segmentationVoxelManager } = strategyData;
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
- const callback = ({ value, index }) => {
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, fillOutsideRectangle } from './fillRectangle';
1
+ import { fillInsideRectangle, thresholdInsideRectangle } from './fillRectangle';
2
2
  import { fillInsideCircle, fillOutsideCircle } from './fillCircle';
3
- export { fillInsideRectangle, fillOutsideRectangle, fillInsideCircle, fillOutsideCircle, };
3
+ export { fillInsideRectangle, thresholdInsideRectangle, fillInsideCircle, fillOutsideCircle, };
@@ -1,3 +1,3 @@
1
- import { fillInsideRectangle, fillOutsideRectangle } from './fillRectangle';
1
+ import { fillInsideRectangle, thresholdInsideRectangle } from './fillRectangle';
2
2
  import { fillInsideCircle, fillOutsideCircle } from './fillCircle';
3
- export { fillInsideRectangle, fillOutsideRectangle, fillInsideCircle, fillOutsideCircle, };
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;
@@ -12,6 +12,7 @@ type PlanarFreehandROIEditData = {
12
12
  startCrossingIndex?: Types.Point2;
13
13
  editIndex: number;
14
14
  snapIndex?: number;
15
+ newAnnotation?: boolean;
15
16
  };
16
17
  type PlanarFreehandROICommonData = {
17
18
  annotation: PlanarFreehandROIAnnotation;
@@ -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
- export { thresholdVolumeByRange, createMergedLabelmapForIndex, createLabelmapVolumeForViewport, rectangleROIThresholdVolumeByRange, triggerSegmentationRender, triggerSegmentationRenderBySegmentationId, floodFill, getBrushSizeForToolGroup, setBrushSizeForToolGroup, getBrushThresholdForToolGroup, setBrushThresholdForToolGroup, VolumetricCalculator, thresholdSegmentationByRange, contourAndFindLargestBidirectional, createBidirectionalToolData, segmentContourAction, invalidateBrushCursor, getUniqueSegmentIndices, getSegmentIndexAtWorldPoint, getSegmentIndexAtLabelmapBorder, getHoveredContourSegmentationAnnotation, getBrushToolInstances, growCut, };
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
- export { thresholdVolumeByRange, createMergedLabelmapForIndex, createLabelmapVolumeForViewport, rectangleROIThresholdVolumeByRange, triggerSegmentationRender, triggerSegmentationRenderBySegmentationId, floodFill, getBrushSizeForToolGroup, setBrushSizeForToolGroup, getBrushThresholdForToolGroup, setBrushThresholdForToolGroup, VolumetricCalculator, thresholdSegmentationByRange, contourAndFindLargestBidirectional, createBidirectionalToolData, segmentContourAction, invalidateBrushCursor, getUniqueSegmentIndices, getSegmentIndexAtWorldPoint, getSegmentIndexAtLabelmapBorder, getHoveredContourSegmentationAnnotation, getBrushToolInstances, growCut, };
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.7.4",
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.7.4",
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": "d386daf61a0fe0fb2f049e8456c3497839e7e4fa"
126
+ "gitHead": "64b1f664e114d73546cf88099bf427a4f563aabd"
127
127
  }