@cornerstonejs/tools 2.6.5 → 2.7.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.
Files changed (36) hide show
  1. package/dist/esm/index.d.ts +2 -2
  2. package/dist/esm/index.js +2 -2
  3. package/dist/esm/stateManagement/segmentation/polySeg/Labelmap/labelmapComputationStrategies.js +2 -1
  4. package/dist/esm/tools/annotation/LengthTool.js +6 -3
  5. package/dist/esm/tools/annotation/RegionSegmentPlusTool.d.ts +15 -0
  6. package/dist/esm/tools/annotation/RegionSegmentPlusTool.js +40 -0
  7. package/dist/esm/tools/annotation/RegionSegmentTool.d.ts +21 -0
  8. package/dist/esm/tools/annotation/RegionSegmentTool.js +103 -0
  9. package/dist/esm/tools/annotation/WholeBodySegmentTool.d.ts +28 -0
  10. package/dist/esm/tools/annotation/WholeBodySegmentTool.js +188 -0
  11. package/dist/esm/tools/base/ContourSegmentationBaseTool.js +5 -46
  12. package/dist/esm/tools/base/GrowCutBaseTool.d.ts +49 -0
  13. package/dist/esm/tools/base/GrowCutBaseTool.js +106 -0
  14. package/dist/esm/tools/index.d.ts +4 -1
  15. package/dist/esm/tools/index.js +4 -1
  16. package/dist/esm/tools/segmentation/strategies/fillSphere.js +2 -2
  17. package/dist/esm/utilities/getSphereBoundsInfo.d.ts +5 -2
  18. package/dist/esm/utilities/getSphereBoundsInfo.js +36 -13
  19. package/dist/esm/utilities/segmentation/createLabelmapVolumeForViewport.js +1 -1
  20. package/dist/esm/utilities/segmentation/getSVGStyleForSegment.d.ts +17 -0
  21. package/dist/esm/utilities/segmentation/getSVGStyleForSegment.js +68 -0
  22. package/dist/esm/utilities/segmentation/growCut/growCutShader.d.ts +2 -0
  23. package/dist/esm/utilities/segmentation/growCut/growCutShader.js +106 -0
  24. package/dist/esm/utilities/segmentation/growCut/index.d.ts +7 -0
  25. package/dist/esm/utilities/segmentation/growCut/index.js +4 -0
  26. package/dist/esm/utilities/segmentation/growCut/runGrowCut.d.ts +16 -0
  27. package/dist/esm/utilities/segmentation/growCut/runGrowCut.js +269 -0
  28. package/dist/esm/utilities/segmentation/growCut/runGrowCutForBoundingBox.d.ts +17 -0
  29. package/dist/esm/utilities/segmentation/growCut/runGrowCutForBoundingBox.js +111 -0
  30. package/dist/esm/utilities/segmentation/growCut/runGrowCutForSphere.d.ts +9 -0
  31. package/dist/esm/utilities/segmentation/growCut/runGrowCutForSphere.js +164 -0
  32. package/dist/esm/utilities/segmentation/growCut/runOneClickGrowCut.d.ts +13 -0
  33. package/dist/esm/utilities/segmentation/growCut/runOneClickGrowCut.js +176 -0
  34. package/dist/esm/utilities/segmentation/index.d.ts +2 -1
  35. package/dist/esm/utilities/segmentation/index.js +2 -1
  36. package/package.json +3 -3
@@ -9,7 +9,7 @@ import * as cursors from './cursors';
9
9
  import * as Types from './types';
10
10
  import * as annotation from './stateManagement/annotation';
11
11
  import * as segmentation from './stateManagement/segmentation';
12
- import { BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, ZoomTool, StackScrollTool, PlanarRotateTool, MIPJumpToClickTool, LengthTool, HeightTool, ProbeTool, RectangleROITool, EllipticalROITool, CircleROITool, ETDRSGridTool, SplineROITool, SplineContourSegmentationTool, BidirectionalTool, PlanarFreehandROITool, PlanarFreehandContourSegmentationTool, LivewireContourTool, LivewireContourSegmentationTool, ArrowAnnotateTool, KeyImageTool, CrosshairsTool, ReferenceLinesTool, RectangleScissorsTool, CircleScissorsTool, SphereScissorsTool, RectangleROIThresholdTool, RectangleROIStartEndThresholdTool, CircleROIStartEndThresholdTool, BrushTool, AngleTool, CobbAngleTool, UltrasoundDirectionalTool, MagnifyTool, AdvancedMagnifyTool, ReferenceCursors, PaintFillTool, ScaleOverlayTool, OrientationMarkerTool, OverlayGridTool, SegmentationIntersectionTool, EraserTool, SculptorTool, SegmentSelectTool, WindowLevelRegionTool, VolumeRotateTool } from './tools';
12
+ import { BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, ZoomTool, StackScrollTool, PlanarRotateTool, MIPJumpToClickTool, LengthTool, HeightTool, ProbeTool, RectangleROITool, EllipticalROITool, CircleROITool, ETDRSGridTool, SplineROITool, SplineContourSegmentationTool, BidirectionalTool, PlanarFreehandROITool, PlanarFreehandContourSegmentationTool, LivewireContourTool, LivewireContourSegmentationTool, ArrowAnnotateTool, KeyImageTool, CrosshairsTool, ReferenceLinesTool, RectangleScissorsTool, CircleScissorsTool, SphereScissorsTool, RectangleROIThresholdTool, RectangleROIStartEndThresholdTool, CircleROIStartEndThresholdTool, BrushTool, AngleTool, CobbAngleTool, UltrasoundDirectionalTool, MagnifyTool, AdvancedMagnifyTool, ReferenceCursors, PaintFillTool, ScaleOverlayTool, OrientationMarkerTool, OverlayGridTool, SegmentationIntersectionTool, EraserTool, SculptorTool, SegmentSelectTool, WindowLevelRegionTool, VolumeRotateTool, RegionSegmentPlusTool, RegionSegmentTool, WholeBodySegmentTool } from './tools';
13
13
  import VideoRedactionTool from './tools/annotation/VideoRedactionTool';
14
14
  import * as Enums from './enums';
15
- export { VideoRedactionTool, init, destroy, addTool, removeTool, cancelActiveManipulations, BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, WindowLevelRegionTool, ZoomTool, StackScrollTool, PlanarRotateTool, MIPJumpToClickTool, LengthTool, HeightTool, CrosshairsTool, ReferenceLinesTool, OverlayGridTool, SegmentationIntersectionTool, ProbeTool, RectangleROITool, EllipticalROITool, CircleROITool, ETDRSGridTool, SplineROITool, SplineContourSegmentationTool, BidirectionalTool, PlanarFreehandROITool, PlanarFreehandContourSegmentationTool, LivewireContourTool, LivewireContourSegmentationTool, ArrowAnnotateTool, AngleTool, CobbAngleTool, UltrasoundDirectionalTool, KeyImageTool, MagnifyTool, AdvancedMagnifyTool, ReferenceCursors, ScaleOverlayTool, SculptorTool, EraserTool, RectangleScissorsTool, CircleScissorsTool, SphereScissorsTool, RectangleROIThresholdTool, RectangleROIStartEndThresholdTool, CircleROIStartEndThresholdTool, BrushTool, OrientationMarkerTool, SegmentSelectTool, synchronizers, Synchronizer, SynchronizerManager, PaintFillTool, Types, state, ToolGroupManager, Enums, CONSTANTS, drawing, annotation, segmentation, utilities, cursors, VolumeRotateTool, };
15
+ export { VideoRedactionTool, init, destroy, addTool, removeTool, cancelActiveManipulations, BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, WindowLevelRegionTool, ZoomTool, StackScrollTool, PlanarRotateTool, MIPJumpToClickTool, LengthTool, HeightTool, CrosshairsTool, ReferenceLinesTool, OverlayGridTool, SegmentationIntersectionTool, ProbeTool, RectangleROITool, EllipticalROITool, CircleROITool, ETDRSGridTool, SplineROITool, SplineContourSegmentationTool, BidirectionalTool, PlanarFreehandROITool, PlanarFreehandContourSegmentationTool, LivewireContourTool, LivewireContourSegmentationTool, ArrowAnnotateTool, AngleTool, CobbAngleTool, UltrasoundDirectionalTool, KeyImageTool, MagnifyTool, AdvancedMagnifyTool, ReferenceCursors, ScaleOverlayTool, SculptorTool, EraserTool, RectangleScissorsTool, CircleScissorsTool, SphereScissorsTool, RectangleROIThresholdTool, RectangleROIStartEndThresholdTool, CircleROIStartEndThresholdTool, BrushTool, OrientationMarkerTool, SegmentSelectTool, synchronizers, Synchronizer, SynchronizerManager, PaintFillTool, Types, state, ToolGroupManager, Enums, CONSTANTS, drawing, annotation, segmentation, utilities, cursors, VolumeRotateTool, RegionSegmentPlusTool, RegionSegmentTool, WholeBodySegmentTool, };
package/dist/esm/index.js CHANGED
@@ -9,7 +9,7 @@ import * as cursors from './cursors';
9
9
  import * as Types from './types';
10
10
  import * as annotation from './stateManagement/annotation';
11
11
  import * as segmentation from './stateManagement/segmentation';
12
- import { BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, ZoomTool, StackScrollTool, PlanarRotateTool, MIPJumpToClickTool, LengthTool, HeightTool, ProbeTool, RectangleROITool, EllipticalROITool, CircleROITool, ETDRSGridTool, SplineROITool, SplineContourSegmentationTool, BidirectionalTool, PlanarFreehandROITool, PlanarFreehandContourSegmentationTool, LivewireContourTool, LivewireContourSegmentationTool, ArrowAnnotateTool, KeyImageTool, CrosshairsTool, ReferenceLinesTool, RectangleScissorsTool, CircleScissorsTool, SphereScissorsTool, RectangleROIThresholdTool, RectangleROIStartEndThresholdTool, CircleROIStartEndThresholdTool, BrushTool, AngleTool, CobbAngleTool, UltrasoundDirectionalTool, MagnifyTool, AdvancedMagnifyTool, ReferenceCursors, PaintFillTool, ScaleOverlayTool, OrientationMarkerTool, OverlayGridTool, SegmentationIntersectionTool, EraserTool, SculptorTool, SegmentSelectTool, WindowLevelRegionTool, VolumeRotateTool, } from './tools';
12
+ import { BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, ZoomTool, StackScrollTool, PlanarRotateTool, MIPJumpToClickTool, LengthTool, HeightTool, ProbeTool, RectangleROITool, EllipticalROITool, CircleROITool, ETDRSGridTool, SplineROITool, SplineContourSegmentationTool, BidirectionalTool, PlanarFreehandROITool, PlanarFreehandContourSegmentationTool, LivewireContourTool, LivewireContourSegmentationTool, ArrowAnnotateTool, KeyImageTool, CrosshairsTool, ReferenceLinesTool, RectangleScissorsTool, CircleScissorsTool, SphereScissorsTool, RectangleROIThresholdTool, RectangleROIStartEndThresholdTool, CircleROIStartEndThresholdTool, BrushTool, AngleTool, CobbAngleTool, UltrasoundDirectionalTool, MagnifyTool, AdvancedMagnifyTool, ReferenceCursors, PaintFillTool, ScaleOverlayTool, OrientationMarkerTool, OverlayGridTool, SegmentationIntersectionTool, EraserTool, SculptorTool, SegmentSelectTool, WindowLevelRegionTool, VolumeRotateTool, RegionSegmentPlusTool, RegionSegmentTool, WholeBodySegmentTool, } from './tools';
13
13
  import VideoRedactionTool from './tools/annotation/VideoRedactionTool';
14
14
  import * as Enums from './enums';
15
- export { VideoRedactionTool, init, destroy, addTool, removeTool, cancelActiveManipulations, BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, WindowLevelRegionTool, ZoomTool, StackScrollTool, PlanarRotateTool, MIPJumpToClickTool, LengthTool, HeightTool, CrosshairsTool, ReferenceLinesTool, OverlayGridTool, SegmentationIntersectionTool, ProbeTool, RectangleROITool, EllipticalROITool, CircleROITool, ETDRSGridTool, SplineROITool, SplineContourSegmentationTool, BidirectionalTool, PlanarFreehandROITool, PlanarFreehandContourSegmentationTool, LivewireContourTool, LivewireContourSegmentationTool, ArrowAnnotateTool, AngleTool, CobbAngleTool, UltrasoundDirectionalTool, KeyImageTool, MagnifyTool, AdvancedMagnifyTool, ReferenceCursors, ScaleOverlayTool, SculptorTool, EraserTool, RectangleScissorsTool, CircleScissorsTool, SphereScissorsTool, RectangleROIThresholdTool, RectangleROIStartEndThresholdTool, CircleROIStartEndThresholdTool, BrushTool, OrientationMarkerTool, SegmentSelectTool, synchronizers, Synchronizer, SynchronizerManager, PaintFillTool, Types, state, ToolGroupManager, Enums, CONSTANTS, drawing, annotation, segmentation, utilities, cursors, VolumeRotateTool, };
15
+ export { VideoRedactionTool, init, destroy, addTool, removeTool, cancelActiveManipulations, BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, WindowLevelRegionTool, ZoomTool, StackScrollTool, PlanarRotateTool, MIPJumpToClickTool, LengthTool, HeightTool, CrosshairsTool, ReferenceLinesTool, OverlayGridTool, SegmentationIntersectionTool, ProbeTool, RectangleROITool, EllipticalROITool, CircleROITool, ETDRSGridTool, SplineROITool, SplineContourSegmentationTool, BidirectionalTool, PlanarFreehandROITool, PlanarFreehandContourSegmentationTool, LivewireContourTool, LivewireContourSegmentationTool, ArrowAnnotateTool, AngleTool, CobbAngleTool, UltrasoundDirectionalTool, KeyImageTool, MagnifyTool, AdvancedMagnifyTool, ReferenceCursors, ScaleOverlayTool, SculptorTool, EraserTool, RectangleScissorsTool, CircleScissorsTool, SphereScissorsTool, RectangleROIThresholdTool, RectangleROIStartEndThresholdTool, CircleROIStartEndThresholdTool, BrushTool, OrientationMarkerTool, SegmentSelectTool, synchronizers, Synchronizer, SynchronizerManager, PaintFillTool, Types, state, ToolGroupManager, Enums, CONSTANTS, drawing, annotation, segmentation, utilities, cursors, VolumeRotateTool, RegionSegmentPlusTool, RegionSegmentTool, WholeBodySegmentTool, };
@@ -73,7 +73,8 @@ async function computeLabelmapFromSurfaceSegmentation(segmentationId, options =
73
73
  let segmentationVolume;
74
74
  if (isVolume) {
75
75
  const volumeId = viewport.getVolumeId();
76
- segmentationVolume = await volumeLoader.createAndCacheDerivedLabelmapVolume(volumeId);
76
+ segmentationVolume =
77
+ volumeLoader.createAndCacheDerivedLabelmapVolume(volumeId);
77
78
  }
78
79
  else {
79
80
  const imageIds = options.viewport.getImageIds();
@@ -432,9 +432,12 @@ class LengthTool extends AnnotationTool {
432
432
  const handles = [index1, index2];
433
433
  const { scale, unit } = getCalibratedLengthUnitsAndScale(image, handles);
434
434
  const length = this._calculateLength(worldPos1, worldPos2) / scale;
435
- this._isInsideVolume(index1, index2, dimensions)
436
- ? (this.isHandleOutsideImage = false)
437
- : (this.isHandleOutsideImage = true);
435
+ if (this._isInsideVolume(index1, index2, dimensions)) {
436
+ this.isHandleOutsideImage = false;
437
+ }
438
+ else {
439
+ this.isHandleOutsideImage = true;
440
+ }
438
441
  cachedStats[targetId] = {
439
442
  length,
440
443
  unit,
@@ -0,0 +1,15 @@
1
+ import type { Types } from '@cornerstonejs/core';
2
+ import type { EventTypes, PublicToolProps, ToolProps } from '../../types';
3
+ import GrowCutBaseTool from '../base/GrowCutBaseTool';
4
+ import type { GrowCutToolData } from '../base/GrowCutBaseTool';
5
+ type RegionSegmentPlusToolData = GrowCutToolData & {
6
+ worldPoint: Types.Point3;
7
+ };
8
+ declare class RegionSegmentPlusTool extends GrowCutBaseTool {
9
+ static toolName: any;
10
+ protected growCutData: RegionSegmentPlusToolData | null;
11
+ constructor(toolProps?: PublicToolProps, defaultToolProps?: ToolProps);
12
+ preMouseDownCallback(evt: EventTypes.MouseDownActivateEventType): Promise<boolean>;
13
+ protected getGrowCutLabelmap(): Promise<Types.IImageVolume>;
14
+ }
15
+ export default RegionSegmentPlusTool;
@@ -0,0 +1,40 @@
1
+ import { getRenderingEngine } from '@cornerstonejs/core';
2
+ import { growCut } from '../../utilities/segmentation';
3
+ import GrowCutBaseTool from '../base/GrowCutBaseTool';
4
+ class RegionSegmentPlusTool extends GrowCutBaseTool {
5
+ constructor(toolProps = {}, defaultToolProps = {
6
+ supportedInteractionTypes: ['Mouse', 'Touch'],
7
+ configuration: {
8
+ positiveSeedVariance: 0.4,
9
+ negativeSeedVariance: 0.9,
10
+ subVolumePaddingPercentage: 0.1,
11
+ },
12
+ }) {
13
+ super(toolProps, defaultToolProps);
14
+ }
15
+ async preMouseDownCallback(evt) {
16
+ const eventData = evt.detail;
17
+ const { currentPoints } = eventData;
18
+ const { world: worldPoint } = currentPoints;
19
+ super.preMouseDownCallback(evt);
20
+ this.growCutData.worldPoint = worldPoint;
21
+ this.runGrowCut();
22
+ return true;
23
+ }
24
+ async getGrowCutLabelmap() {
25
+ const { segmentation: { segmentIndex, referencedVolumeId }, renderingEngineId, viewportId, worldPoint, } = this.growCutData;
26
+ const renderingEngine = getRenderingEngine(renderingEngineId);
27
+ const viewport = renderingEngine.getViewport(viewportId);
28
+ const { positiveSeedVariance, negativeSeedVariance, subVolumePaddingPercentage, } = this.configuration;
29
+ const options = {
30
+ positiveSeedValue: segmentIndex,
31
+ negativeSeedValue: 255,
32
+ positiveSeedVariance: positiveSeedVariance,
33
+ negativeSeedVariance: negativeSeedVariance,
34
+ subVolumePaddingPercentage: subVolumePaddingPercentage,
35
+ };
36
+ return await growCut.runOneClickGrowCut(referencedVolumeId, worldPoint, viewport, options);
37
+ }
38
+ }
39
+ RegionSegmentPlusTool.toolName = 'RegionSegmentPlus';
40
+ export default RegionSegmentPlusTool;
@@ -0,0 +1,21 @@
1
+ import type { Types } from '@cornerstonejs/core';
2
+ import type { EventTypes, PublicToolProps, ToolProps, SVGDrawingHelper } from '../../types';
3
+ import type { GrowCutToolData } from '../base/GrowCutBaseTool';
4
+ import GrowCutBaseTool from '../base/GrowCutBaseTool';
5
+ type RegionSegmentToolData = GrowCutToolData & {
6
+ circleCenterPoint: Types.Point3;
7
+ circleBorderPoint: Types.Point3;
8
+ };
9
+ declare class RegionSegmentTool extends GrowCutBaseTool {
10
+ static toolName: any;
11
+ protected growCutData: RegionSegmentToolData | null;
12
+ constructor(toolProps?: PublicToolProps, defaultToolProps?: ToolProps);
13
+ preMouseDownCallback(evt: EventTypes.MouseDownActivateEventType): Promise<boolean>;
14
+ private _dragCallback;
15
+ private _endCallback;
16
+ protected getGrowCutLabelmap(): Promise<Types.IImageVolume>;
17
+ private _activateDraw;
18
+ private _deactivateDraw;
19
+ renderAnnotation(enabledElement: Types.IEnabledElement, svgDrawingHelper: SVGDrawingHelper): void;
20
+ }
21
+ export default RegionSegmentTool;
@@ -0,0 +1,103 @@
1
+ import { vec2, vec3 } from 'gl-matrix';
2
+ import { getEnabledElement, utilities as csUtils, getRenderingEngine, } from '@cornerstonejs/core';
3
+ import { drawCircle as drawCircleSvg } from '../../drawingSvg';
4
+ import { resetElementCursor, hideElementCursor, } from '../../cursors/elementCursor';
5
+ import { Events } from '../../enums';
6
+ import triggerAnnotationRenderForViewportUIDs from '../../utilities/triggerAnnotationRenderForViewportIds';
7
+ import { growCut } from '../../utilities/segmentation';
8
+ import GrowCutBaseTool from '../base/GrowCutBaseTool';
9
+ class RegionSegmentTool extends GrowCutBaseTool {
10
+ constructor(toolProps = {}, defaultToolProps = {
11
+ supportedInteractionTypes: ['Mouse', 'Touch'],
12
+ configuration: {},
13
+ }) {
14
+ super(toolProps, defaultToolProps);
15
+ this._dragCallback = (evt) => {
16
+ const eventData = evt.detail;
17
+ const { element, currentPoints } = eventData;
18
+ const { world: currentWorldPoint } = currentPoints;
19
+ const enabledElement = getEnabledElement(element);
20
+ const { viewport } = enabledElement;
21
+ this.growCutData.circleBorderPoint = currentWorldPoint;
22
+ triggerAnnotationRenderForViewportUIDs([viewport.id]);
23
+ };
24
+ this._endCallback = async (evt) => {
25
+ const eventData = evt.detail;
26
+ const { element } = eventData;
27
+ const enabledElement = getEnabledElement(element);
28
+ const { viewport } = enabledElement;
29
+ this.runGrowCut();
30
+ this._deactivateDraw(element);
31
+ this.growCutData = null;
32
+ resetElementCursor(element);
33
+ triggerAnnotationRenderForViewportUIDs([viewport.id]);
34
+ };
35
+ this._deactivateDraw = (element) => {
36
+ element.removeEventListener(Events.MOUSE_UP, this._endCallback);
37
+ element.removeEventListener(Events.MOUSE_DRAG, this._dragCallback);
38
+ element.removeEventListener(Events.MOUSE_CLICK, this._endCallback);
39
+ };
40
+ }
41
+ async preMouseDownCallback(evt) {
42
+ const eventData = evt.detail;
43
+ const { element, currentPoints } = eventData;
44
+ const { world: worldPoint } = currentPoints;
45
+ const enabledElement = getEnabledElement(element);
46
+ const { viewport, renderingEngine } = enabledElement;
47
+ super.preMouseDownCallback(evt);
48
+ Object.assign(this.growCutData, {
49
+ circleCenterPoint: worldPoint,
50
+ circleBorderPoint: worldPoint,
51
+ });
52
+ this._activateDraw(element);
53
+ hideElementCursor(element);
54
+ triggerAnnotationRenderForViewportUIDs([viewport.id]);
55
+ return true;
56
+ }
57
+ async getGrowCutLabelmap() {
58
+ const { segmentation: { segmentIndex, referencedVolumeId }, renderingEngineId, viewportId, circleCenterPoint, circleBorderPoint, } = this.growCutData;
59
+ const renderingEngine = getRenderingEngine(renderingEngineId);
60
+ const viewport = renderingEngine.getViewport(viewportId);
61
+ const worldCircleRadius = vec3.len(vec3.sub(vec3.create(), circleCenterPoint, circleBorderPoint));
62
+ const sphereInfo = {
63
+ center: circleCenterPoint,
64
+ radius: worldCircleRadius,
65
+ };
66
+ const options = {
67
+ positiveSeedValue: segmentIndex,
68
+ negativeSeedValue: 255,
69
+ };
70
+ return growCut.runGrowCutForSphere(referencedVolumeId, sphereInfo, viewport, options);
71
+ }
72
+ _activateDraw(element) {
73
+ element.addEventListener(Events.MOUSE_UP, this._endCallback);
74
+ element.addEventListener(Events.MOUSE_DRAG, this._dragCallback);
75
+ element.addEventListener(Events.MOUSE_CLICK, this._endCallback);
76
+ }
77
+ renderAnnotation(enabledElement, svgDrawingHelper) {
78
+ if (!this.growCutData) {
79
+ return;
80
+ }
81
+ const { viewport } = enabledElement;
82
+ const { segmentation: segmentationData, circleCenterPoint, circleBorderPoint, } = this.growCutData;
83
+ const canvasCenterPoint = viewport.worldToCanvas(circleCenterPoint);
84
+ const canvasBorderPoint = viewport.worldToCanvas(circleBorderPoint);
85
+ const vecCenterToBorder = vec2.sub(vec2.create(), canvasBorderPoint, canvasCenterPoint);
86
+ const circleRadius = vec2.len(vecCenterToBorder);
87
+ if (csUtils.isEqual(circleRadius, 0)) {
88
+ return;
89
+ }
90
+ const annotationUID = 'growcut';
91
+ const circleUID = '0';
92
+ const { color } = this.getSegmentStyle({
93
+ segmentationId: segmentationData.segmentationId,
94
+ segmentIndex: segmentationData.segmentIndex,
95
+ viewportId: viewport.id,
96
+ });
97
+ drawCircleSvg(svgDrawingHelper, annotationUID, circleUID, canvasCenterPoint, circleRadius, {
98
+ color,
99
+ });
100
+ }
101
+ }
102
+ RegionSegmentTool.toolName = 'RegionSegment';
103
+ export default RegionSegmentTool;
@@ -0,0 +1,28 @@
1
+ import type { Types } from '@cornerstonejs/core';
2
+ import type { EventTypes, PublicToolProps, ToolProps, SVGDrawingHelper } from '../../types';
3
+ import type { GrowCutToolData } from '../base/GrowCutBaseTool';
4
+ import GrowCutBaseTool from '../base/GrowCutBaseTool';
5
+ type HorizontalLine = [Types.Point3, Types.Point3];
6
+ type WholeBodySegmentToolData = GrowCutToolData & {
7
+ horizontalLines: [HorizontalLine, HorizontalLine];
8
+ };
9
+ declare class WholeBodySegmentTool extends GrowCutBaseTool {
10
+ static toolName: any;
11
+ protected growCutData: WholeBodySegmentToolData | null;
12
+ constructor(toolProps?: PublicToolProps, defaultToolProps?: ToolProps);
13
+ preMouseDownCallback(evt: EventTypes.MouseDownActivateEventType): Promise<boolean>;
14
+ private _dragCallback;
15
+ private _endCallback;
16
+ renderAnnotation(enabledElement: Types.IEnabledElement, svgDrawingHelper: SVGDrawingHelper): void;
17
+ protected getGrowCutLabelmap(): Promise<Types.IImageVolume>;
18
+ private _activateDraw;
19
+ private _deactivateDraw;
20
+ private _projectWorldPointAcrossSlices;
21
+ private _getCuboidIJKEdgePointsFromProjectedWorldPoint;
22
+ private _getWorldCuboidCornerPoints;
23
+ private _getWorldBoundingBoxFromProjectedSquare;
24
+ private _getViewportVolume;
25
+ private _getHorizontalLineIJKPoints;
26
+ private _getHorizontalLineWorldPoints;
27
+ }
28
+ export default WholeBodySegmentTool;
@@ -0,0 +1,188 @@
1
+ import { vec3 } from 'gl-matrix';
2
+ import { getEnabledElement, utilities as csUtils, cache, getRenderingEngine, BaseVolumeViewport, } from '@cornerstonejs/core';
3
+ import { drawPolyline as drawPolylineSvg } from '../../drawingSvg';
4
+ import { resetElementCursor, hideElementCursor, } from '../../cursors/elementCursor';
5
+ import { Events } from '../../enums';
6
+ import triggerAnnotationRenderForViewportUIDs from '../../utilities/triggerAnnotationRenderForViewportIds';
7
+ import { growCut } from '../../utilities/segmentation';
8
+ import GrowCutBaseTool from '../base/GrowCutBaseTool';
9
+ const { transformWorldToIndex, transformIndexToWorld } = csUtils;
10
+ class WholeBodySegmentTool extends GrowCutBaseTool {
11
+ constructor(toolProps = {}, defaultToolProps = {
12
+ supportedInteractionTypes: ['Mouse', 'Touch'],
13
+ configuration: {},
14
+ }) {
15
+ super(toolProps, defaultToolProps);
16
+ this._dragCallback = (evt) => {
17
+ const eventData = evt.detail;
18
+ const { element, currentPoints } = eventData;
19
+ const { world: currentWorldPoint } = currentPoints;
20
+ const enabledElement = getEnabledElement(element);
21
+ const { renderingEngine, viewport } = enabledElement;
22
+ const linePoints = this._getHorizontalLineWorldPoints(enabledElement, currentWorldPoint);
23
+ this.growCutData.horizontalLines[1] = linePoints;
24
+ triggerAnnotationRenderForViewportUIDs([viewport.id]);
25
+ };
26
+ this._endCallback = (evt) => {
27
+ const eventData = evt.detail;
28
+ const { element } = eventData;
29
+ const enabledElement = getEnabledElement(element);
30
+ const { renderingEngine, viewport } = enabledElement;
31
+ this.runGrowCut();
32
+ this._deactivateDraw(element);
33
+ this.growCutData = null;
34
+ resetElementCursor(element);
35
+ triggerAnnotationRenderForViewportUIDs([viewport.id]);
36
+ };
37
+ this._deactivateDraw = (element) => {
38
+ element.removeEventListener(Events.MOUSE_UP, this._endCallback);
39
+ element.removeEventListener(Events.MOUSE_DRAG, this._dragCallback);
40
+ element.removeEventListener(Events.MOUSE_CLICK, this._endCallback);
41
+ };
42
+ }
43
+ async preMouseDownCallback(evt) {
44
+ const eventData = evt.detail;
45
+ const { element, currentPoints } = eventData;
46
+ const { world: worldPoint } = currentPoints;
47
+ const enabledElement = getEnabledElement(element);
48
+ const { viewport, renderingEngine } = enabledElement;
49
+ const linePoints = this._getHorizontalLineWorldPoints(enabledElement, worldPoint);
50
+ super.preMouseDownCallback(evt);
51
+ this.growCutData.horizontalLines = [linePoints, linePoints];
52
+ this._activateDraw(element);
53
+ hideElementCursor(element);
54
+ triggerAnnotationRenderForViewportUIDs([viewport.id]);
55
+ return true;
56
+ }
57
+ renderAnnotation(enabledElement, svgDrawingHelper) {
58
+ if (!this.growCutData) {
59
+ return;
60
+ }
61
+ const { segmentation: segmentationData, horizontalLines } = this.growCutData;
62
+ if (horizontalLines.length !== 2) {
63
+ return;
64
+ }
65
+ const { viewport } = enabledElement;
66
+ const { segmentationId, segmentIndex } = segmentationData;
67
+ const [line1, line2] = horizontalLines;
68
+ const [worldLine1P1, worldLine1P2] = line1;
69
+ const [worldLine2P1, worldLine2P2] = line2;
70
+ const canvasPoints = [
71
+ worldLine1P1,
72
+ worldLine1P2,
73
+ worldLine2P2,
74
+ worldLine2P1,
75
+ ].map((worldPoint) => viewport.worldToCanvas(worldPoint));
76
+ const annotationUID = 'growCutRect';
77
+ const squareGroupUID = '0';
78
+ const { color, fillColor, lineWidth, fillOpacity, lineDash } = this.getSegmentStyle({
79
+ segmentationId,
80
+ segmentIndex,
81
+ viewportId: viewport.id,
82
+ });
83
+ drawPolylineSvg(svgDrawingHelper, annotationUID, squareGroupUID, canvasPoints, {
84
+ color,
85
+ fillColor,
86
+ fillOpacity,
87
+ lineWidth,
88
+ lineDash,
89
+ closePath: true,
90
+ });
91
+ }
92
+ async getGrowCutLabelmap() {
93
+ const { segmentation: { segmentIndex, referencedVolumeId }, renderingEngineId, viewportId, horizontalLines, } = this.growCutData;
94
+ const renderingEngine = getRenderingEngine(renderingEngineId);
95
+ const viewport = renderingEngine.getViewport(viewportId);
96
+ const [line1, line2] = horizontalLines;
97
+ const worldSquarePoints = [line1[0], line1[1], line2[1], line2[0]];
98
+ const referencedVolume = cache.getVolume(referencedVolumeId);
99
+ const { topLeft: worldTopLeft, bottomRight: worldBottomRight } = this._getWorldBoundingBoxFromProjectedSquare(viewport, worldSquarePoints);
100
+ const ijkTopLeft = transformWorldToIndex(referencedVolume.imageData, worldTopLeft);
101
+ const ijkBottomRight = transformWorldToIndex(referencedVolume.imageData, worldBottomRight);
102
+ const boundingBoxInfo = {
103
+ boundingBox: {
104
+ ijkTopLeft,
105
+ ijkBottomRight,
106
+ },
107
+ };
108
+ const options = {
109
+ positiveSeedValue: segmentIndex,
110
+ negativeSeedValue: 255,
111
+ };
112
+ return growCut.runGrowCutForBoundingBox(referencedVolumeId, boundingBoxInfo, options);
113
+ }
114
+ _activateDraw(element) {
115
+ element.addEventListener(Events.MOUSE_UP, this._endCallback);
116
+ element.addEventListener(Events.MOUSE_DRAG, this._dragCallback);
117
+ element.addEventListener(Events.MOUSE_CLICK, this._endCallback);
118
+ }
119
+ _projectWorldPointAcrossSlices(viewport, worldEdgePoint, vecDirection) {
120
+ const volume = this._getViewportVolume(viewport);
121
+ const { dimensions } = volume;
122
+ const ijkPoint = transformWorldToIndex(volume.imageData, worldEdgePoint);
123
+ const axis = vecDirection.findIndex((n) => csUtils.isEqual(Math.abs(n), 1));
124
+ if (axis === -1) {
125
+ throw new Error('Non-orthogonal direction vector');
126
+ }
127
+ const ijkLineP1 = [...ijkPoint];
128
+ const ijkLineP2 = [...ijkPoint];
129
+ ijkLineP1[axis] = 0;
130
+ ijkLineP2[axis] = dimensions[axis] - 1;
131
+ return [ijkLineP1, ijkLineP2];
132
+ }
133
+ _getCuboidIJKEdgePointsFromProjectedWorldPoint(viewport, worldEdgePoint) {
134
+ const { viewPlaneNormal } = viewport.getCamera();
135
+ return this._projectWorldPointAcrossSlices(viewport, worldEdgePoint, viewPlaneNormal);
136
+ }
137
+ _getWorldCuboidCornerPoints(viewport, worldSquarePoints) {
138
+ const cuboidPoints = [];
139
+ const volume = this._getViewportVolume(viewport);
140
+ worldSquarePoints.forEach((worldSquarePoint) => {
141
+ const ijkEdgePoints = this._getCuboidIJKEdgePointsFromProjectedWorldPoint(viewport, worldSquarePoint);
142
+ const worldEdgePoints = ijkEdgePoints.map((ijkPoint) => transformIndexToWorld(volume.imageData, ijkPoint));
143
+ cuboidPoints.push(...worldEdgePoints);
144
+ });
145
+ return cuboidPoints;
146
+ }
147
+ _getWorldBoundingBoxFromProjectedSquare(viewport, worldSquarePoints) {
148
+ const worldCuboidPoints = this._getWorldCuboidCornerPoints(viewport, worldSquarePoints);
149
+ const topLeft = [...worldCuboidPoints[0]];
150
+ const bottomRight = [...worldCuboidPoints[0]];
151
+ worldCuboidPoints.forEach((worldPoint) => {
152
+ vec3.min(topLeft, topLeft, worldPoint);
153
+ vec3.max(bottomRight, bottomRight, worldPoint);
154
+ });
155
+ return { topLeft, bottomRight };
156
+ }
157
+ _getViewportVolume(viewport) {
158
+ if (!(viewport instanceof BaseVolumeViewport)) {
159
+ throw new Error('Viewport is not a BaseVolumeViewport');
160
+ }
161
+ const volumeId = viewport.getAllVolumeIds()[0];
162
+ return cache.getVolume(volumeId);
163
+ }
164
+ _getHorizontalLineIJKPoints(enabledElement, worldPoint) {
165
+ const { viewport } = enabledElement;
166
+ const volume = this._getViewportVolume(viewport);
167
+ const { dimensions } = volume;
168
+ const ijkPoint = transformWorldToIndex(volume.imageData, worldPoint);
169
+ const { viewUp, viewPlaneNormal } = viewport.getCamera();
170
+ const vecRow = vec3.cross(vec3.create(), viewUp, viewPlaneNormal);
171
+ const axis = vecRow.findIndex((n) => csUtils.isEqual(Math.abs(n), 1));
172
+ const ijkLineP1 = [...ijkPoint];
173
+ const ijkLineP2 = [...ijkPoint];
174
+ ijkLineP1[axis] = 0;
175
+ ijkLineP2[axis] = dimensions[axis] - 1;
176
+ return [ijkLineP1, ijkLineP2];
177
+ }
178
+ _getHorizontalLineWorldPoints(enabledElement, worldPoint) {
179
+ const { viewport } = enabledElement;
180
+ const volume = this._getViewportVolume(viewport);
181
+ const [ijkPoint1, ijkPoint2] = this._getHorizontalLineIJKPoints(enabledElement, worldPoint);
182
+ const worldPoint1 = transformIndexToWorld(volume.imageData, ijkPoint1);
183
+ const worldPoint2 = transformIndexToWorld(volume.imageData, ijkPoint2);
184
+ return [worldPoint1, worldPoint2];
185
+ }
186
+ }
187
+ WholeBodySegmentTool.toolName = 'WholeBodySegmentTool';
188
+ export default WholeBodySegmentTool;
@@ -15,6 +15,7 @@ import { getActiveSegmentIndex } from '../../stateManagement/segmentation/getAct
15
15
  import { getLockedSegmentIndices } from '../../stateManagement/segmentation/segmentLocking';
16
16
  import { segmentationStyle } from '../../stateManagement/segmentation/SegmentationStyle';
17
17
  import { internalGetHiddenSegmentIndices } from '../../stateManagement/segmentation/helpers/internalGetHiddenSegmentIndices';
18
+ import { getSVGStyleForSegment } from '../../utilities/segmentation/getSVGStyleForSegment';
18
19
  class ContourSegmentationBaseTool extends ContourBaseTool {
19
20
  constructor(toolProps, defaultToolProps) {
20
21
  super(toolProps, defaultToolProps);
@@ -112,54 +113,12 @@ class ContourSegmentationBaseTool extends ContourBaseTool {
112
113
  const { autoGenerated } = annotation;
113
114
  const segmentsLocked = getLockedSegmentIndices(segmentationId);
114
115
  const annotationLocked = segmentsLocked.includes(segmentIndex);
115
- const segmentColor = getSegmentIndexColor(context.styleSpecifier.viewportId, segmentationId, segmentIndex);
116
- const segmentationVisible = getSegmentationRepresentationVisibility(viewportId, {
116
+ const { color, fillColor, lineWidth, fillOpacity, lineDash, visibility } = getSVGStyleForSegment({
117
117
  segmentationId,
118
- type: SegmentationRepresentations.Contour,
119
- });
120
- const activeSegmentation = getActiveSegmentation(viewportId);
121
- const isActive = activeSegmentation?.segmentationId === segmentationId;
122
- const style = segmentationStyle.getStyle({
123
- viewportId,
124
- segmentationId,
125
- type: SegmentationRepresentations.Contour,
126
118
  segmentIndex,
119
+ viewportId,
120
+ autoGenerated,
127
121
  });
128
- const mergedConfig = style;
129
- let lineWidth = 1;
130
- let lineDash = undefined;
131
- let lineOpacity = 1;
132
- let fillOpacity = 0;
133
- if (autoGenerated) {
134
- lineWidth = mergedConfig.outlineWidthAutoGenerated ?? lineWidth;
135
- lineDash = mergedConfig.outlineDashAutoGenerated ?? lineDash;
136
- lineOpacity = mergedConfig.outlineOpacity ?? lineOpacity;
137
- fillOpacity = mergedConfig.fillAlphaAutoGenerated ?? fillOpacity;
138
- }
139
- else if (isActive) {
140
- lineWidth = mergedConfig.outlineWidth ?? lineWidth;
141
- lineDash = mergedConfig.outlineDash ?? lineDash;
142
- lineOpacity = mergedConfig.outlineOpacity ?? lineOpacity;
143
- fillOpacity = mergedConfig.fillAlpha ?? fillOpacity;
144
- }
145
- else {
146
- lineWidth = mergedConfig.outlineWidthInactive ?? lineWidth;
147
- lineDash = mergedConfig.outlineDashInactive ?? lineDash;
148
- lineOpacity = mergedConfig.outlineOpacityInactive ?? lineOpacity;
149
- fillOpacity = mergedConfig.fillAlphaInactive ?? fillOpacity;
150
- }
151
- if (getActiveSegmentIndex(segmentationId) === segmentIndex) {
152
- lineWidth += mergedConfig.activeSegmentOutlineWidthDelta;
153
- }
154
- lineWidth = mergedConfig.renderOutline ? lineWidth : 0;
155
- fillOpacity = mergedConfig.renderFill ? fillOpacity : 0;
156
- const color = `rgba(${segmentColor[0]}, ${segmentColor[1]}, ${segmentColor[2]}, ${lineOpacity})`;
157
- const fillColor = `rgb(${segmentColor[0]}, ${segmentColor[1]}, ${segmentColor[2]})`;
158
- const hiddenSegments = internalGetHiddenSegmentIndices(viewportId, {
159
- segmentationId,
160
- type: SegmentationRepresentations.Contour,
161
- });
162
- const isVisible = !hiddenSegments.has(segmentIndex);
163
122
  return {
164
123
  color,
165
124
  fillColor,
@@ -169,7 +128,7 @@ class ContourSegmentationBaseTool extends ContourBaseTool {
169
128
  textbox: {
170
129
  color,
171
130
  },
172
- visibility: segmentationVisible && isVisible,
131
+ visibility,
173
132
  locked: annotationLocked,
174
133
  };
175
134
  }
@@ -0,0 +1,49 @@
1
+ import type { Types } from '@cornerstonejs/core';
2
+ import { BaseTool } from '../base';
3
+ import type { EventTypes, PublicToolProps, ToolProps } from '../../types';
4
+ type GrowCutToolData = {
5
+ metadata: Types.ViewReference & {
6
+ viewUp?: Types.Point3;
7
+ };
8
+ segmentation: {
9
+ segmentationId: string;
10
+ segmentIndex: number;
11
+ labelmapVolumeId: string;
12
+ referencedVolumeId: string;
13
+ };
14
+ viewportId: string;
15
+ renderingEngineId: string;
16
+ };
17
+ declare class GrowCutBaseTool extends BaseTool {
18
+ static toolName: any;
19
+ protected growCutData: GrowCutToolData | null;
20
+ constructor(toolProps: PublicToolProps, defaultToolProps: ToolProps);
21
+ preMouseDownCallback(evt: EventTypes.MouseDownActivateEventType): Promise<boolean>;
22
+ protected getGrowCutLabelmap(): Promise<Types.IImageVolume>;
23
+ protected runGrowCut(): Promise<void>;
24
+ protected applyGrowCutLabelmap(segmentationId: string, segmentIndex: number, targetLabelmap: Types.IImageVolume, sourceLabelmap: Types.IImageVolume): void;
25
+ protected getSegmentStyle({ segmentationId, viewportId, segmentIndex }: {
26
+ segmentationId: any;
27
+ viewportId: any;
28
+ segmentIndex: any;
29
+ }): {
30
+ color: string;
31
+ fillColor: string;
32
+ lineWidth: number;
33
+ fillOpacity: number;
34
+ lineDash: any;
35
+ textbox: {
36
+ color: string;
37
+ };
38
+ visibility: boolean;
39
+ };
40
+ protected getLabelmapSegmentationData(viewport: Types.IViewport): {
41
+ segmentationId: string;
42
+ segmentIndex: number;
43
+ labelmapVolumeId: string;
44
+ referencedVolumeId: string;
45
+ };
46
+ protected _isOrthogonalView(viewport: Types.IViewport, referencedVolumeId: string): boolean;
47
+ }
48
+ export default GrowCutBaseTool;
49
+ export type { GrowCutToolData };