@cornerstonejs/tools 3.5.3 → 3.6.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 (45) hide show
  1. package/dist/esm/config.d.ts +7 -0
  2. package/dist/esm/enums/WorkerTypes.d.ts +2 -1
  3. package/dist/esm/enums/WorkerTypes.js +1 -0
  4. package/dist/esm/index.d.ts +2 -2
  5. package/dist/esm/index.js +2 -2
  6. package/dist/esm/tools/annotation/BidirectionalTool.d.ts +3 -0
  7. package/dist/esm/tools/annotation/BidirectionalTool.js +39 -1
  8. package/dist/esm/tools/index.d.ts +2 -1
  9. package/dist/esm/tools/index.js +2 -1
  10. package/dist/esm/tools/segmentation/SegmentBidirectionalTool.d.ts +27 -0
  11. package/dist/esm/tools/segmentation/SegmentBidirectionalTool.js +253 -0
  12. package/dist/esm/tools/segmentation/strategies/compositions/ensureImageVolume.js +5 -8
  13. package/dist/esm/tools/segmentation/strategies/utils/getStrategyData.js +5 -10
  14. package/dist/esm/types/CalculatorTypes.d.ts +21 -3
  15. package/dist/esm/types/ToolSpecificAnnotationTypes.d.ts +34 -0
  16. package/dist/esm/utilities/contours/generateContourSetsFromLabelmap.js +1 -0
  17. package/dist/esm/utilities/math/basic/BasicStatsCalculator.js +88 -13
  18. package/dist/esm/utilities/registerComputeWorker.js +4 -1
  19. package/dist/esm/utilities/segmentation/VolumetricCalculator.js +12 -2
  20. package/dist/esm/utilities/segmentation/computeMetabolicStats.d.ts +8 -0
  21. package/dist/esm/utilities/segmentation/computeMetabolicStats.js +58 -0
  22. package/dist/esm/utilities/segmentation/contourAndFindLargestBidirectional.js +7 -5
  23. package/dist/esm/utilities/segmentation/createMergedLabelmapForIndex.js +10 -2
  24. package/dist/esm/utilities/segmentation/findLargestBidirectional.d.ts +5 -0
  25. package/dist/esm/utilities/segmentation/findLargestBidirectional.js +1 -1
  26. package/dist/esm/utilities/segmentation/getOrCreateImageVolume.d.ts +3 -0
  27. package/dist/esm/utilities/segmentation/getOrCreateImageVolume.js +18 -0
  28. package/dist/esm/utilities/segmentation/getOrCreateSegmentationVolume.d.ts +2 -1
  29. package/dist/esm/utilities/segmentation/getOrCreateSegmentationVolume.js +5 -1
  30. package/dist/esm/utilities/segmentation/getReferenceVolumeForSegmentation.d.ts +1 -0
  31. package/dist/esm/utilities/segmentation/getReferenceVolumeForSegmentation.js +34 -0
  32. package/dist/esm/utilities/segmentation/getReferenceVolumeForSegmentationVolume.d.ts +1 -0
  33. package/dist/esm/utilities/segmentation/getReferenceVolumeForSegmentationVolume.js +20 -0
  34. package/dist/esm/utilities/segmentation/getSegmentLargestBidirectional.d.ts +5 -0
  35. package/dist/esm/utilities/segmentation/getSegmentLargestBidirectional.js +54 -0
  36. package/dist/esm/utilities/segmentation/getStatistics.js +50 -108
  37. package/dist/esm/utilities/segmentation/index.d.ts +5 -1
  38. package/dist/esm/utilities/segmentation/index.js +5 -1
  39. package/dist/esm/utilities/segmentation/isLineInSegment.d.ts +13 -1
  40. package/dist/esm/utilities/segmentation/isLineInSegment.js +20 -12
  41. package/dist/esm/utilities/segmentation/segmentContourAction.js +1 -0
  42. package/dist/esm/utilities/segmentation/utilsForWorker.d.ts +38 -0
  43. package/dist/esm/utilities/segmentation/utilsForWorker.js +125 -0
  44. package/dist/esm/workers/computeWorker.js +336 -38
  45. package/package.json +4 -4
@@ -20,8 +20,15 @@ type PolySegAddOn = {
20
20
  type AddOns = {
21
21
  polySeg: PolySegAddOn;
22
22
  };
23
+ type ComputeWorkerConfig = {
24
+ autoTerminateOnIdle?: {
25
+ enabled: boolean;
26
+ idleTimeThreshold?: number;
27
+ };
28
+ };
23
29
  export type Config = {
24
30
  addons: AddOns;
31
+ computeWorker?: ComputeWorkerConfig;
25
32
  };
26
33
  export declare function getConfig(): Config;
27
34
  export declare function setConfig(newConfig: Config): void;
@@ -5,6 +5,7 @@ declare enum ChangeTypes {
5
5
  POLYSEG_LABELMAP_TO_SURFACE = "Converting Labelmap to Surface",
6
6
  SURFACE_CLIPPING = "Clipping Surfaces",
7
7
  COMPUTE_STATISTICS = "Computing Statistics",
8
- INTERPOLATE_LABELMAP = "Interpolating Labelmap"
8
+ INTERPOLATE_LABELMAP = "Interpolating Labelmap",
9
+ COMPUTE_LARGEST_BIDIRECTIONAL = "Computing Largest Bidirectional"
9
10
  }
10
11
  export default ChangeTypes;
@@ -7,5 +7,6 @@ var ChangeTypes;
7
7
  ChangeTypes["SURFACE_CLIPPING"] = "Clipping Surfaces";
8
8
  ChangeTypes["COMPUTE_STATISTICS"] = "Computing Statistics";
9
9
  ChangeTypes["INTERPOLATE_LABELMAP"] = "Interpolating Labelmap";
10
+ ChangeTypes["COMPUTE_LARGEST_BIDIRECTIONAL"] = "Computing Largest Bidirectional";
10
11
  })(ChangeTypes || (ChangeTypes = {}));
11
12
  export default ChangeTypes;
@@ -11,7 +11,7 @@ import * as Types from './types';
11
11
  import * as annotation from './stateManagement/annotation';
12
12
  import * as segmentation from './stateManagement/segmentation';
13
13
  import * as splines from './tools/annotation/splines';
14
- import { BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, ZoomTool, StackScrollTool, PlanarRotateTool, MIPJumpToClickTool, LabelTool, 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, LabelmapBaseTool } from './tools';
14
+ import { BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, ZoomTool, StackScrollTool, SegmentBidirectionalTool, PlanarRotateTool, MIPJumpToClickTool, LabelTool, 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, LabelmapBaseTool } from './tools';
15
15
  import VideoRedactionTool from './tools/annotation/VideoRedactionTool';
16
16
  import * as Enums from './enums';
17
- export { VideoRedactionTool, init, destroy, addTool, removeTool, cancelActiveManipulations, BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, WindowLevelRegionTool, ZoomTool, StackScrollTool, PlanarRotateTool, MIPJumpToClickTool, LabelTool, 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, store, Enums, CONSTANTS, drawing, annotation, segmentation, utilities, cursors, VolumeRotateTool, RegionSegmentPlusTool, RegionSegmentTool, WholeBodySegmentTool, LabelmapBaseTool, splines, };
17
+ export { VideoRedactionTool, init, destroy, addTool, removeTool, cancelActiveManipulations, BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, SegmentBidirectionalTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, WindowLevelRegionTool, ZoomTool, StackScrollTool, PlanarRotateTool, MIPJumpToClickTool, LabelTool, 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, store, Enums, CONSTANTS, drawing, annotation, segmentation, utilities, cursors, VolumeRotateTool, RegionSegmentPlusTool, RegionSegmentTool, WholeBodySegmentTool, LabelmapBaseTool, splines, };
package/dist/esm/index.js CHANGED
@@ -11,7 +11,7 @@ import * as Types from './types';
11
11
  import * as annotation from './stateManagement/annotation';
12
12
  import * as segmentation from './stateManagement/segmentation';
13
13
  import * as splines from './tools/annotation/splines';
14
- import { BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, ZoomTool, StackScrollTool, PlanarRotateTool, MIPJumpToClickTool, LabelTool, 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, LabelmapBaseTool, } from './tools';
14
+ import { BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, ZoomTool, StackScrollTool, SegmentBidirectionalTool, PlanarRotateTool, MIPJumpToClickTool, LabelTool, 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, LabelmapBaseTool, } from './tools';
15
15
  import VideoRedactionTool from './tools/annotation/VideoRedactionTool';
16
16
  import * as Enums from './enums';
17
- export { VideoRedactionTool, init, destroy, addTool, removeTool, cancelActiveManipulations, BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, WindowLevelRegionTool, ZoomTool, StackScrollTool, PlanarRotateTool, MIPJumpToClickTool, LabelTool, 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, store, Enums, CONSTANTS, drawing, annotation, segmentation, utilities, cursors, VolumeRotateTool, RegionSegmentPlusTool, RegionSegmentTool, WholeBodySegmentTool, LabelmapBaseTool, splines, };
17
+ export { VideoRedactionTool, init, destroy, addTool, removeTool, cancelActiveManipulations, BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, SegmentBidirectionalTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, WindowLevelRegionTool, ZoomTool, StackScrollTool, PlanarRotateTool, MIPJumpToClickTool, LabelTool, 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, store, Enums, CONSTANTS, drawing, annotation, segmentation, utilities, cursors, VolumeRotateTool, RegionSegmentPlusTool, RegionSegmentTool, WholeBodySegmentTool, LabelmapBaseTool, splines, };
@@ -18,6 +18,9 @@ declare class BidirectionalTool extends AnnotationTool {
18
18
  preventHandleOutsideImage: boolean;
19
19
  constructor(toolProps?: PublicToolProps, defaultToolProps?: ToolProps);
20
20
  addNewAnnotation(evt: EventTypes.InteractionEventType): BidirectionalAnnotation;
21
+ static hydrate: (viewportId: string, axis: [[Types.Point3, Types.Point3], [Types.Point3, Types.Point3]], options?: {
22
+ annotationUID?: string;
23
+ }) => BidirectionalAnnotation;
21
24
  isPointNearTool: (element: HTMLDivElement, annotation: BidirectionalAnnotation, canvasCoords: Types.Point2, proximity: number) => boolean;
22
25
  toolSelectedCallback: (evt: EventTypes.InteractionEventType, annotation: BidirectionalAnnotation) => void;
23
26
  handleSelectedCallback: (evt: EventTypes.InteractionEventType, annotation: BidirectionalAnnotation, handle: ToolHandle) => void;
@@ -1,5 +1,5 @@
1
1
  import { vec2, vec3 } from 'gl-matrix';
2
- import { getEnabledElement, utilities as csUtils } from '@cornerstonejs/core';
2
+ import { getEnabledElement, utilities as csUtils, getEnabledElementByViewportId, utilities, } from '@cornerstonejs/core';
3
3
  import { getCalibratedLengthUnitsAndScale } from '../../utilities/getCalibratedUnits';
4
4
  import { AnnotationTool } from '../base';
5
5
  import throttle from '../../utilities/throttle';
@@ -709,6 +709,44 @@ class BidirectionalTool extends AnnotationTool {
709
709
  triggerAnnotationRenderForViewportIds(viewportIdsToRender);
710
710
  return annotation;
711
711
  }
712
+ static { this.hydrate = (viewportId, axis, options) => {
713
+ const enabledElement = getEnabledElementByViewportId(viewportId);
714
+ if (!enabledElement) {
715
+ return;
716
+ }
717
+ const { viewport } = enabledElement;
718
+ const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
719
+ const { viewPlaneNormal, viewUp } = viewport.getCamera();
720
+ const instance = new this();
721
+ const [majorAxis, minorAxis] = axis;
722
+ const [major0, major1] = majorAxis;
723
+ const [minor0, minor1] = minorAxis;
724
+ const points = [major0, major1, minor0, minor1];
725
+ const referencedImageId = instance.getReferencedImageId(viewport, points[0], viewPlaneNormal, viewUp);
726
+ const annotation = {
727
+ annotationUID: options?.annotationUID || utilities.uuidv4(),
728
+ data: {
729
+ handles: {
730
+ points,
731
+ activeHandleIndex: null,
732
+ },
733
+ },
734
+ highlighted: false,
735
+ autoGenerated: false,
736
+ invalidated: false,
737
+ isLocked: false,
738
+ isVisible: true,
739
+ metadata: {
740
+ toolName: instance.getToolName(),
741
+ viewPlaneNormal,
742
+ FrameOfReferenceUID,
743
+ referencedImageId,
744
+ ...options,
745
+ },
746
+ };
747
+ addAnnotation(annotation, viewport.element);
748
+ triggerAnnotationRenderForViewportIds([viewport.id]);
749
+ }; }
712
750
  _calculateLength(pos1, pos2) {
713
751
  const dx = pos1[0] - pos2[0];
714
752
  const dy = pos1[1] - pos2[1];
@@ -53,5 +53,6 @@ import BrushTool from './segmentation/BrushTool';
53
53
  import PaintFillTool from './segmentation/PaintFillTool';
54
54
  import OrientationMarkerTool from './OrientationMarkerTool';
55
55
  import SegmentSelectTool from './segmentation/SegmentSelectTool';
56
+ import SegmentBidirectionalTool from './segmentation/SegmentBidirectionalTool';
56
57
  import * as strategies from './segmentation/strategies';
57
- export { BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, WindowLevelRegionTool, StackScrollTool, PlanarRotateTool, ZoomTool, MIPJumpToClickTool, ReferenceCursors, CrosshairsTool, ReferenceLinesTool, OverlayGridTool, SegmentationIntersectionTool, BidirectionalTool, LabelTool, LengthTool, HeightTool, ProbeTool, RectangleROITool, EllipticalROITool, CircleROITool, ETDRSGridTool, SplineROITool, PlanarFreehandROITool, PlanarFreehandContourSegmentationTool, LivewireContourTool, LivewireContourSegmentationTool, ArrowAnnotateTool, AngleTool, CobbAngleTool, UltrasoundDirectionalTool, KeyImageTool, AnnotationEraserTool as EraserTool, RectangleScissorsTool, CircleScissorsTool, SphereScissorsTool, RectangleROIThresholdTool, RectangleROIStartEndThresholdTool, CircleROIStartEndThresholdTool, SplineContourSegmentationTool, BrushTool, MagnifyTool, AdvancedMagnifyTool, PaintFillTool, ScaleOverlayTool, OrientationMarkerTool, SculptorTool, SegmentSelectTool, VolumeRotateTool, RegionSegmentTool, RegionSegmentPlusTool, WholeBodySegmentTool, LabelmapBaseTool, strategies, };
58
+ export { BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, WindowLevelRegionTool, StackScrollTool, PlanarRotateTool, ZoomTool, MIPJumpToClickTool, ReferenceCursors, CrosshairsTool, ReferenceLinesTool, OverlayGridTool, SegmentationIntersectionTool, BidirectionalTool, LabelTool, LengthTool, HeightTool, ProbeTool, RectangleROITool, EllipticalROITool, CircleROITool, ETDRSGridTool, SplineROITool, PlanarFreehandROITool, PlanarFreehandContourSegmentationTool, LivewireContourTool, LivewireContourSegmentationTool, ArrowAnnotateTool, AngleTool, CobbAngleTool, UltrasoundDirectionalTool, KeyImageTool, AnnotationEraserTool as EraserTool, RectangleScissorsTool, CircleScissorsTool, SphereScissorsTool, RectangleROIThresholdTool, RectangleROIStartEndThresholdTool, CircleROIStartEndThresholdTool, SplineContourSegmentationTool, BrushTool, MagnifyTool, AdvancedMagnifyTool, PaintFillTool, ScaleOverlayTool, OrientationMarkerTool, SculptorTool, SegmentSelectTool, VolumeRotateTool, RegionSegmentTool, RegionSegmentPlusTool, WholeBodySegmentTool, LabelmapBaseTool, SegmentBidirectionalTool, strategies, };
@@ -53,5 +53,6 @@ import BrushTool from './segmentation/BrushTool';
53
53
  import PaintFillTool from './segmentation/PaintFillTool';
54
54
  import OrientationMarkerTool from './OrientationMarkerTool';
55
55
  import SegmentSelectTool from './segmentation/SegmentSelectTool';
56
+ import SegmentBidirectionalTool from './segmentation/SegmentBidirectionalTool';
56
57
  import * as strategies from './segmentation/strategies';
57
- export { BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, WindowLevelRegionTool, StackScrollTool, PlanarRotateTool, ZoomTool, MIPJumpToClickTool, ReferenceCursors, CrosshairsTool, ReferenceLinesTool, OverlayGridTool, SegmentationIntersectionTool, BidirectionalTool, LabelTool, LengthTool, HeightTool, ProbeTool, RectangleROITool, EllipticalROITool, CircleROITool, ETDRSGridTool, SplineROITool, PlanarFreehandROITool, PlanarFreehandContourSegmentationTool, LivewireContourTool, LivewireContourSegmentationTool, ArrowAnnotateTool, AngleTool, CobbAngleTool, UltrasoundDirectionalTool, KeyImageTool, AnnotationEraserTool as EraserTool, RectangleScissorsTool, CircleScissorsTool, SphereScissorsTool, RectangleROIThresholdTool, RectangleROIStartEndThresholdTool, CircleROIStartEndThresholdTool, SplineContourSegmentationTool, BrushTool, MagnifyTool, AdvancedMagnifyTool, PaintFillTool, ScaleOverlayTool, OrientationMarkerTool, SculptorTool, SegmentSelectTool, VolumeRotateTool, RegionSegmentTool, RegionSegmentPlusTool, WholeBodySegmentTool, LabelmapBaseTool, strategies, };
58
+ export { BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, DragProbeTool, WindowLevelTool, WindowLevelRegionTool, StackScrollTool, PlanarRotateTool, ZoomTool, MIPJumpToClickTool, ReferenceCursors, CrosshairsTool, ReferenceLinesTool, OverlayGridTool, SegmentationIntersectionTool, BidirectionalTool, LabelTool, LengthTool, HeightTool, ProbeTool, RectangleROITool, EllipticalROITool, CircleROITool, ETDRSGridTool, SplineROITool, PlanarFreehandROITool, PlanarFreehandContourSegmentationTool, LivewireContourTool, LivewireContourSegmentationTool, ArrowAnnotateTool, AngleTool, CobbAngleTool, UltrasoundDirectionalTool, KeyImageTool, AnnotationEraserTool as EraserTool, RectangleScissorsTool, CircleScissorsTool, SphereScissorsTool, RectangleROIThresholdTool, RectangleROIStartEndThresholdTool, CircleROIStartEndThresholdTool, SplineContourSegmentationTool, BrushTool, MagnifyTool, AdvancedMagnifyTool, PaintFillTool, ScaleOverlayTool, OrientationMarkerTool, SculptorTool, SegmentSelectTool, VolumeRotateTool, RegionSegmentTool, RegionSegmentPlusTool, WholeBodySegmentTool, LabelmapBaseTool, SegmentBidirectionalTool, strategies, };
@@ -0,0 +1,27 @@
1
+ import type { Types } from '@cornerstonejs/core';
2
+ import type { EventTypes, PublicToolProps, SVGDrawingHelper, Annotation } from '../../types';
3
+ import type { BidirectionalAnnotation, SegmentBidirectionalAnnotation } from '../../types/ToolSpecificAnnotationTypes';
4
+ import BidirectionalTool from '../annotation/BidirectionalTool';
5
+ declare class SegmentBidirectionalTool extends BidirectionalTool {
6
+ static toolName: string;
7
+ editData: {
8
+ annotation: Annotation;
9
+ viewportIdsToRender: string[];
10
+ handleIndex?: number;
11
+ movingTextBox: boolean;
12
+ newAnnotation?: boolean;
13
+ hasMoved?: boolean;
14
+ } | null;
15
+ isDrawing: boolean;
16
+ isHandleOutsideImage: boolean;
17
+ preventHandleOutsideImage: boolean;
18
+ constructor(toolProps?: PublicToolProps);
19
+ addNewAnnotation(evt: EventTypes.InteractionEventType): BidirectionalAnnotation;
20
+ static hydrate: (viewportId: string, axis: [[Types.Point3, Types.Point3], [Types.Point3, Types.Point3]], options?: {
21
+ segmentIndex?: number;
22
+ segmentationId?: string;
23
+ annotationUID?: string;
24
+ }) => SegmentBidirectionalAnnotation;
25
+ renderAnnotation: (enabledElement: Types.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean;
26
+ }
27
+ export default SegmentBidirectionalTool;
@@ -0,0 +1,253 @@
1
+ import { getEnabledElement, utilities as csUtils, getEnabledElementByViewportId, utilities, } from '@cornerstonejs/core';
2
+ import { addAnnotation, getAllAnnotations, getAnnotations, removeAnnotation, } from '../../stateManagement/annotation/annotationState';
3
+ import { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking';
4
+ import { isAnnotationVisible } from '../../stateManagement/annotation/annotationVisibility';
5
+ import { drawLine as drawLineSvg, drawHandles as drawHandlesSvg, drawLinkedTextBox as drawLinkedTextBoxSvg, } from '../../drawingSvg';
6
+ import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
7
+ import { getTextBoxCoordsCanvas } from '../../utilities/drawing';
8
+ import { hideElementCursor } from '../../cursors/elementCursor';
9
+ import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds';
10
+ import BidirectionalTool from '../annotation/BidirectionalTool';
11
+ import { getSegmentIndexColor } from '../../stateManagement/segmentation/config/segmentationColor';
12
+ class SegmentBidirectionalTool extends BidirectionalTool {
13
+ static { this.toolName = 'SegmentBidirectional'; }
14
+ constructor(toolProps = {}) {
15
+ super(toolProps);
16
+ this.renderAnnotation = (enabledElement, svgDrawingHelper) => {
17
+ let renderStatus = true;
18
+ const { viewport } = enabledElement;
19
+ const { element } = viewport;
20
+ const viewportId = viewport.id;
21
+ let annotations = getAnnotations(this.getToolName(), element);
22
+ if (!annotations?.length) {
23
+ return renderStatus;
24
+ }
25
+ annotations = this.filterInteractableAnnotationsForElement(element, annotations);
26
+ if (!annotations?.length) {
27
+ return renderStatus;
28
+ }
29
+ const targetId = this.getTargetId(viewport);
30
+ const renderingEngine = viewport.getRenderingEngine();
31
+ const styleSpecifier = {
32
+ toolGroupId: this.toolGroupId,
33
+ toolName: this.getToolName(),
34
+ viewportId: enabledElement.viewport.id,
35
+ };
36
+ for (let i = 0; i < annotations.length; i++) {
37
+ const annotation = annotations[i];
38
+ const { annotationUID, data } = annotation;
39
+ const { points, activeHandleIndex } = data.handles;
40
+ const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p));
41
+ styleSpecifier.annotationUID = annotationUID;
42
+ const { segmentIndex, segmentationId } = annotation.metadata;
43
+ const { lineWidth, lineDash, shadow } = this.getAnnotationStyle({
44
+ annotation,
45
+ styleSpecifier,
46
+ });
47
+ const colorArray = getSegmentIndexColor(viewportId, segmentationId, segmentIndex);
48
+ const color = `rgb(${colorArray.slice(0, 3).join(',')})`;
49
+ if (!data.cachedStats[targetId] ||
50
+ data.cachedStats[targetId].unit == null) {
51
+ data.cachedStats[targetId] = {
52
+ length: null,
53
+ width: null,
54
+ unit: null,
55
+ };
56
+ this._calculateCachedStats(annotation, renderingEngine, enabledElement);
57
+ }
58
+ else if (annotation.invalidated) {
59
+ this._throttledCalculateCachedStats(annotation, renderingEngine, enabledElement);
60
+ }
61
+ if (!viewport.getRenderingEngine()) {
62
+ console.warn('Rendering Engine has been destroyed');
63
+ return renderStatus;
64
+ }
65
+ let activeHandleCanvasCoords;
66
+ if (!isAnnotationVisible(annotationUID)) {
67
+ continue;
68
+ }
69
+ if (!isAnnotationLocked(annotationUID) &&
70
+ !this.editData &&
71
+ activeHandleIndex !== null) {
72
+ activeHandleCanvasCoords = [canvasCoordinates[activeHandleIndex]];
73
+ }
74
+ if (activeHandleCanvasCoords) {
75
+ const handleGroupUID = '0';
76
+ drawHandlesSvg(svgDrawingHelper, annotationUID, handleGroupUID, activeHandleCanvasCoords, {
77
+ color,
78
+ });
79
+ }
80
+ const dataId1 = `${annotationUID}-line-1`;
81
+ const dataId2 = `${annotationUID}-line-2`;
82
+ const lineUID = '0';
83
+ drawLineSvg(svgDrawingHelper, annotationUID, lineUID, canvasCoordinates[0], canvasCoordinates[1], {
84
+ color,
85
+ lineWidth,
86
+ lineDash,
87
+ shadow,
88
+ }, dataId1);
89
+ const secondLineUID = '1';
90
+ drawLineSvg(svgDrawingHelper, annotationUID, secondLineUID, canvasCoordinates[2], canvasCoordinates[3], {
91
+ color,
92
+ lineWidth,
93
+ lineDash,
94
+ shadow,
95
+ }, dataId2);
96
+ renderStatus = true;
97
+ const options = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
98
+ if (!options.visibility) {
99
+ data.handles.textBox = {
100
+ hasMoved: false,
101
+ worldPosition: [0, 0, 0],
102
+ worldBoundingBox: {
103
+ topLeft: [0, 0, 0],
104
+ topRight: [0, 0, 0],
105
+ bottomLeft: [0, 0, 0],
106
+ bottomRight: [0, 0, 0],
107
+ },
108
+ };
109
+ continue;
110
+ }
111
+ options.color = color;
112
+ const textLines = this.configuration.getTextLines(data, targetId);
113
+ if (!textLines || textLines.length === 0) {
114
+ continue;
115
+ }
116
+ let canvasTextBoxCoords;
117
+ if (!data.handles.textBox.hasMoved) {
118
+ canvasTextBoxCoords = getTextBoxCoordsCanvas(canvasCoordinates);
119
+ data.handles.textBox.worldPosition =
120
+ viewport.canvasToWorld(canvasTextBoxCoords);
121
+ }
122
+ const textBoxPosition = viewport.worldToCanvas(data.handles.textBox.worldPosition);
123
+ const textBoxUID = '1';
124
+ const boundingBox = drawLinkedTextBoxSvg(svgDrawingHelper, annotationUID, textBoxUID, textLines, textBoxPosition, canvasCoordinates, {}, options);
125
+ const { x: left, y: top, width, height } = boundingBox;
126
+ data.handles.textBox.worldBoundingBox = {
127
+ topLeft: viewport.canvasToWorld([left, top]),
128
+ topRight: viewport.canvasToWorld([left + width, top]),
129
+ bottomLeft: viewport.canvasToWorld([left, top + height]),
130
+ bottomRight: viewport.canvasToWorld([left + width, top + height]),
131
+ };
132
+ }
133
+ return renderStatus;
134
+ };
135
+ }
136
+ addNewAnnotation(evt) {
137
+ const eventDetail = evt.detail;
138
+ const { currentPoints, element } = eventDetail;
139
+ const worldPos = currentPoints.world;
140
+ const enabledElement = getEnabledElement(element);
141
+ const { viewport } = enabledElement;
142
+ this.isDrawing = true;
143
+ const camera = viewport.getCamera();
144
+ const { viewPlaneNormal, viewUp } = camera;
145
+ const referencedImageId = this.getReferencedImageId(viewport, worldPos, viewPlaneNormal, viewUp);
146
+ const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
147
+ const annotation = {
148
+ highlighted: true,
149
+ invalidated: true,
150
+ metadata: {
151
+ toolName: this.getToolName(),
152
+ viewPlaneNormal: [...viewPlaneNormal],
153
+ viewUp: [...viewUp],
154
+ FrameOfReferenceUID,
155
+ referencedImageId,
156
+ ...viewport.getViewReference({ points: [worldPos] }),
157
+ },
158
+ data: {
159
+ handles: {
160
+ points: [
161
+ [...worldPos],
162
+ [...worldPos],
163
+ [...worldPos],
164
+ [...worldPos],
165
+ ],
166
+ textBox: {
167
+ hasMoved: false,
168
+ worldPosition: [0, 0, 0],
169
+ worldBoundingBox: {
170
+ topLeft: [0, 0, 0],
171
+ topRight: [0, 0, 0],
172
+ bottomLeft: [0, 0, 0],
173
+ bottomRight: [0, 0, 0],
174
+ },
175
+ },
176
+ activeHandleIndex: null,
177
+ },
178
+ label: '',
179
+ cachedStats: {},
180
+ },
181
+ };
182
+ addAnnotation(annotation, element);
183
+ const viewportIdsToRender = getViewportIdsWithToolToRender(element, this.getToolName());
184
+ this.editData = {
185
+ annotation,
186
+ viewportIdsToRender,
187
+ handleIndex: 1,
188
+ movingTextBox: false,
189
+ newAnnotation: true,
190
+ hasMoved: false,
191
+ };
192
+ this._activateDraw(element);
193
+ hideElementCursor(element);
194
+ evt.preventDefault();
195
+ triggerAnnotationRenderForViewportIds(viewportIdsToRender);
196
+ return annotation;
197
+ }
198
+ static { this.hydrate = (viewportId, axis, options) => {
199
+ const enabledElement = getEnabledElementByViewportId(viewportId);
200
+ if (!enabledElement) {
201
+ return;
202
+ }
203
+ const { viewport } = enabledElement;
204
+ const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
205
+ const { viewPlaneNormal, viewUp } = viewport.getCamera();
206
+ const existingAnnotations = getAllAnnotations();
207
+ const toolAnnotations = existingAnnotations.filter((annotation) => annotation.metadata.toolName === 'SegmentBidirectional');
208
+ const existingAnnotation = toolAnnotations.find((annotation) => {
209
+ const { metadata } = annotation;
210
+ if (metadata.segmentIndex === options?.segmentIndex &&
211
+ metadata.segmentationId === options?.segmentationId) {
212
+ return true;
213
+ }
214
+ return false;
215
+ });
216
+ if (existingAnnotation) {
217
+ removeAnnotation(existingAnnotation.annotationUID);
218
+ }
219
+ const instance = new this();
220
+ const [majorAxis, minorAxis] = axis;
221
+ const [major0, major1] = majorAxis;
222
+ const [minor0, minor1] = minorAxis;
223
+ const points = [major0, major1, minor0, minor1];
224
+ const referencedImageId = instance.getReferencedImageId(viewport, points[0], viewPlaneNormal, viewUp);
225
+ const annotation = {
226
+ annotationUID: options?.annotationUID || utilities.uuidv4(),
227
+ data: {
228
+ handles: {
229
+ points,
230
+ activeHandleIndex: null,
231
+ },
232
+ },
233
+ highlighted: false,
234
+ autoGenerated: false,
235
+ invalidated: false,
236
+ isLocked: false,
237
+ isVisible: true,
238
+ metadata: {
239
+ segmentIndex: options?.segmentIndex,
240
+ segmentationId: options?.segmentationId,
241
+ toolName: instance.getToolName(),
242
+ viewPlaneNormal,
243
+ FrameOfReferenceUID,
244
+ referencedImageId,
245
+ ...options,
246
+ },
247
+ };
248
+ addAnnotation(annotation, viewport.element);
249
+ triggerAnnotationRenderForViewportIds([viewport.id]);
250
+ return annotation;
251
+ }; }
252
+ }
253
+ export default SegmentBidirectionalTool;
@@ -1,6 +1,7 @@
1
- import { cache, utilities as csUtils, volumeLoader } from '@cornerstonejs/core';
1
+ import { cache, utilities as csUtils } from '@cornerstonejs/core';
2
2
  import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
3
3
  import { getSegmentation } from '../../../../stateManagement/segmentation/getSegmentation';
4
+ import getOrCreateImageVolume from '../../../../utilities/segmentation/getOrCreateImageVolume';
4
5
  export default {
5
6
  [StrategyCallbacks.EnsureImageVolumeFor3DManipulation]: (data) => {
6
7
  const { operationData, viewport } = data;
@@ -21,14 +22,10 @@ export default {
21
22
  return image.referencedImageId;
22
23
  });
23
24
  }
24
- const volumeId = cache.generateVolumeId(referencedImageIds);
25
- let imageVolume = cache.getVolume(volumeId);
26
- if (imageVolume) {
27
- operationData.imageVoxelManager = imageVolume.voxelManager;
28
- operationData.imageData = imageVolume.imageData;
29
- return;
25
+ const imageVolume = getOrCreateImageVolume(referencedImageIds);
26
+ if (!imageVolume) {
27
+ throw new Error('Failed to create or get image volume');
30
28
  }
31
- imageVolume = volumeLoader.createAndCacheVolumeFromImagesSync(volumeId, referencedImageIds);
32
29
  operationData.imageVoxelManager = imageVolume.voxelManager;
33
30
  operationData.imageData = imageVolume.imageData;
34
31
  },
@@ -1,6 +1,7 @@
1
1
  import { BaseVolumeViewport, cache, Enums, eventTarget, } from '@cornerstonejs/core';
2
2
  import { getCurrentLabelmapImageIdForViewport } from '../../../../stateManagement/segmentation/segmentationState';
3
3
  import { getLabelmapActorEntry } from '../../../../stateManagement/segmentation/helpers';
4
+ import { getReferenceVolumeForSegmentationVolume } from '../../../../utilities/segmentation/getReferenceVolumeForSegmentationVolume';
4
5
  function getStrategyDataForVolumeViewport({ operationData }) {
5
6
  const { volumeId } = operationData;
6
7
  if (!volumeId) {
@@ -15,19 +16,13 @@ function getStrategyDataForVolumeViewport({ operationData }) {
15
16
  return null;
16
17
  }
17
18
  const segmentationVolume = cache.getVolume(volumeId);
18
- if (!segmentationVolume) {
19
+ const imageVolume = getReferenceVolumeForSegmentationVolume(volumeId);
20
+ if (!segmentationVolume || !imageVolume) {
19
21
  return null;
20
22
  }
21
- const referencedVolumeId = segmentationVolume.referencedVolumeId;
22
- const segmentationVoxelManager = segmentationVolume.voxelManager;
23
- let imageVoxelManager;
24
- let imageData;
25
- if (referencedVolumeId) {
26
- const imageVolume = cache.getVolume(referencedVolumeId);
27
- imageVoxelManager = imageVolume.voxelManager;
28
- imageData = imageVolume.imageData;
29
- }
30
23
  const { imageData: segmentationImageData } = segmentationVolume;
24
+ const { voxelManager: segmentationVoxelManager } = segmentationVolume;
25
+ const { voxelManager: imageVoxelManager, imageData } = imageVolume;
31
26
  return {
32
27
  segmentationImageData,
33
28
  segmentationVoxelManager,
@@ -29,10 +29,28 @@ type NamedStatistics = {
29
29
  volume?: Statistics & {
30
30
  name: 'volume';
31
31
  };
32
- circumference?: Statistics & {
33
- name: 'circumference';
34
- };
35
32
  pointsInShape?: Types.IPointsManager<Types.Point3>;
33
+ median?: Statistics & {
34
+ name: 'median';
35
+ };
36
+ skewness?: Statistics & {
37
+ name: 'skewness';
38
+ };
39
+ kurtosis?: Statistics & {
40
+ name: 'kurtosis';
41
+ };
42
+ voxelCount?: Statistics & {
43
+ name: 'count';
44
+ };
45
+ lesionGlycolysis?: Statistics & {
46
+ name: 'lesionGlycolysis';
47
+ };
48
+ maxLPS?: Statistics & {
49
+ name: 'maxLPS';
50
+ };
51
+ minLPS?: Statistics & {
52
+ name: 'minLPS';
53
+ };
36
54
  maxIJKs?: Array<{
37
55
  value: number;
38
56
  pointIJK: Types.Point3;
@@ -455,6 +455,40 @@ export interface ScaleOverlayAnnotation extends Annotation {
455
455
  viewportId: string;
456
456
  };
457
457
  }
458
+ export interface SegmentBidirectionalAnnotation extends Annotation {
459
+ data: {
460
+ cachedStats: {
461
+ [targetId: string]: {
462
+ length: number;
463
+ width: number;
464
+ unit: string;
465
+ };
466
+ };
467
+ handles: {
468
+ points: Types.Point3[];
469
+ activeHandleIndex: number | null;
470
+ textBox: {
471
+ hasMoved: boolean;
472
+ worldPosition: Types.Point3;
473
+ worldBoundingBox: {
474
+ topLeft: Types.Point3;
475
+ topRight: Types.Point3;
476
+ bottomLeft: Types.Point3;
477
+ bottomRight: Types.Point3;
478
+ };
479
+ };
480
+ };
481
+ };
482
+ metadata: {
483
+ toolName: string;
484
+ viewPlaneNormal?: Types.Point3;
485
+ viewUp?: Types.Point3;
486
+ FrameOfReferenceUID: string;
487
+ referencedImageId?: string;
488
+ segmentIndex: number;
489
+ segmentationId: string;
490
+ };
491
+ }
458
492
  export interface VideoRedactionAnnotation extends Annotation {
459
493
  metadata: {
460
494
  viewPlaneNormal: Types.Point3;
@@ -7,6 +7,7 @@ import { findContoursFromReducedSet } from './contourFinder';
7
7
  import SegmentationRepresentations from '../../enums/SegmentationRepresentations';
8
8
  const { Labelmap } = SegmentationRepresentations;
9
9
  function generateContourSetsFromLabelmap({ segmentations }) {
10
+ console.warn('Deprecation Alert: This function will be removed in a future version of Cornerstone Tools. Please use the worker version of this function in computeWorker.');
10
11
  const { representationData, segments = [0, 1] } = segmentations;
11
12
  const { volumeId: segVolumeId } = representationData[Labelmap];
12
13
  const vol = cornerstoneCache.getVolume(segVolumeId);