@cornerstonejs/tools 4.18.3 → 4.18.5

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 (49) hide show
  1. package/dist/esm/index.d.ts +2 -2
  2. package/dist/esm/index.js +2 -2
  3. package/dist/esm/tools/OrientationControllerTool.d.ts +38 -0
  4. package/dist/esm/tools/OrientationControllerTool.js +415 -0
  5. package/dist/esm/tools/VolumeCroppingControlTool.d.ts +10 -35
  6. package/dist/esm/tools/VolumeCroppingControlTool.js +179 -699
  7. package/dist/esm/tools/VolumeCroppingTool.d.ts +32 -32
  8. package/dist/esm/tools/VolumeCroppingTool.js +775 -525
  9. package/dist/esm/tools/index.d.ts +2 -1
  10. package/dist/esm/tools/index.js +2 -1
  11. package/dist/esm/utilities/draw3D/addLine3DBetweenPoints.d.ts +7 -0
  12. package/dist/esm/utilities/draw3D/addLine3DBetweenPoints.js +34 -0
  13. package/dist/esm/utilities/draw3D/calculateAdaptiveSphereRadius.d.ts +6 -0
  14. package/dist/esm/utilities/draw3D/calculateAdaptiveSphereRadius.js +7 -0
  15. package/dist/esm/utilities/draw3D/index.d.ts +2 -0
  16. package/dist/esm/utilities/draw3D/index.js +2 -0
  17. package/dist/esm/utilities/index.d.ts +2 -1
  18. package/dist/esm/utilities/index.js +2 -1
  19. package/dist/esm/utilities/volumeCropping/computePlanePlaneIntersection.d.ts +6 -0
  20. package/dist/esm/utilities/volumeCropping/computePlanePlaneIntersection.js +37 -0
  21. package/dist/esm/utilities/volumeCropping/constants.d.ts +31 -0
  22. package/dist/esm/utilities/volumeCropping/constants.js +31 -0
  23. package/dist/esm/utilities/volumeCropping/copyClippingPlanes.d.ts +2 -0
  24. package/dist/esm/utilities/volumeCropping/copyClippingPlanes.js +6 -0
  25. package/dist/esm/utilities/volumeCropping/extractVolumeDirectionVectors.d.ts +9 -0
  26. package/dist/esm/utilities/volumeCropping/extractVolumeDirectionVectors.js +9 -0
  27. package/dist/esm/utilities/volumeCropping/findLineBoundsIntersection.d.ts +5 -0
  28. package/dist/esm/utilities/volumeCropping/findLineBoundsIntersection.js +50 -0
  29. package/dist/esm/utilities/volumeCropping/getColorKeyForPlaneIndex.d.ts +1 -0
  30. package/dist/esm/utilities/volumeCropping/getColorKeyForPlaneIndex.js +13 -0
  31. package/dist/esm/utilities/volumeCropping/getOrientationFromNormal.d.ts +2 -0
  32. package/dist/esm/utilities/volumeCropping/getOrientationFromNormal.js +19 -0
  33. package/dist/esm/utilities/volumeCropping/index.d.ts +9 -0
  34. package/dist/esm/utilities/volumeCropping/index.js +9 -0
  35. package/dist/esm/utilities/volumeCropping/parseCornerKey.d.ts +8 -0
  36. package/dist/esm/utilities/volumeCropping/parseCornerKey.js +11 -0
  37. package/dist/esm/utilities/volumeCropping/types.d.ts +5 -0
  38. package/dist/esm/utilities/volumeCropping/types.js +0 -0
  39. package/dist/esm/utilities/vtkjs/AnnotatedRhombicuboctahedronActor/index.d.ts +31 -0
  40. package/dist/esm/utilities/vtkjs/AnnotatedRhombicuboctahedronActor/index.js +391 -0
  41. package/dist/esm/utilities/vtkjs/OrientationControllerWidget/index.d.ts +59 -0
  42. package/dist/esm/utilities/vtkjs/OrientationControllerWidget/index.js +486 -0
  43. package/dist/esm/utilities/vtkjs/RhombicuboctahedronSource/index.d.ts +7 -0
  44. package/dist/esm/utilities/vtkjs/RhombicuboctahedronSource/index.js +144 -0
  45. package/dist/esm/utilities/vtkjs/index.d.ts +3 -0
  46. package/dist/esm/utilities/vtkjs/index.js +3 -0
  47. package/dist/esm/version.d.ts +1 -1
  48. package/dist/esm/version.js +1 -1
  49. package/package.json +3 -3
@@ -12,7 +12,7 @@ import * as Types from './types';
12
12
  import * as annotation from './stateManagement/annotation';
13
13
  import * as segmentation from './stateManagement/segmentation';
14
14
  import * as splines from './tools/annotation/splines';
15
- import { BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, VolumeCroppingTool, VolumeCroppingControlTool, 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, UltrasoundPleuraBLineTool, MagnifyTool, AdvancedMagnifyTool, ReferenceCursors, PaintFillTool, ScaleOverlayTool, OrientationMarkerTool, OverlayGridTool, SegmentationIntersectionTool, EraserTool, SculptorTool, SegmentSelectTool, WindowLevelRegionTool, VolumeRotateTool, RegionSegmentPlusTool, RegionSegmentTool, WholeBodySegmentTool, LabelmapBaseTool, SegmentLabelTool, LabelMapEditWithContourTool } from './tools';
15
+ import { BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, VolumeCroppingTool, VolumeCroppingControlTool, 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, UltrasoundPleuraBLineTool, MagnifyTool, AdvancedMagnifyTool, ReferenceCursors, PaintFillTool, ScaleOverlayTool, OrientationMarkerTool, OrientationControllerTool, OverlayGridTool, SegmentationIntersectionTool, EraserTool, SculptorTool, SegmentSelectTool, WindowLevelRegionTool, VolumeRotateTool, RegionSegmentPlusTool, RegionSegmentTool, WholeBodySegmentTool, LabelmapBaseTool, SegmentLabelTool, LabelMapEditWithContourTool } from './tools';
16
16
  import VideoRedactionTool from './tools/annotation/VideoRedactionTool';
17
17
  import * as Enums from './enums';
18
- export { VideoRedactionTool, init, destroy, addTool, removeTool, cancelActiveManipulations, BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, SegmentBidirectionalTool, TrackballRotateTool, VolumeCroppingTool, VolumeCroppingControlTool, 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, UltrasoundPleuraBLineTool, KeyImageTool, MagnifyTool, AdvancedMagnifyTool, ReferenceCursors, ScaleOverlayTool, SculptorTool, EraserTool, RectangleScissorsTool, CircleScissorsTool, SphereScissorsTool, RectangleROIThresholdTool, RectangleROIStartEndThresholdTool, CircleROIStartEndThresholdTool, BrushTool, OrientationMarkerTool, SegmentSelectTool, SegmentLabelTool, synchronizers, Synchronizer, SynchronizerManager, PaintFillTool, Types, state, ToolGroupManager, store, Enums, CONSTANTS, drawing, annotation, segmentation, utilities, cursors, VolumeRotateTool, RegionSegmentPlusTool, RegionSegmentTool, WholeBodySegmentTool, LabelmapBaseTool, LabelMapEditWithContourTool, splines, version, };
18
+ export { VideoRedactionTool, init, destroy, addTool, removeTool, cancelActiveManipulations, BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, SegmentBidirectionalTool, TrackballRotateTool, VolumeCroppingTool, VolumeCroppingControlTool, 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, UltrasoundPleuraBLineTool, KeyImageTool, MagnifyTool, AdvancedMagnifyTool, ReferenceCursors, ScaleOverlayTool, SculptorTool, EraserTool, RectangleScissorsTool, CircleScissorsTool, SphereScissorsTool, RectangleROIThresholdTool, RectangleROIStartEndThresholdTool, CircleROIStartEndThresholdTool, BrushTool, OrientationMarkerTool, OrientationControllerTool, SegmentSelectTool, SegmentLabelTool, synchronizers, Synchronizer, SynchronizerManager, PaintFillTool, Types, state, ToolGroupManager, store, Enums, CONSTANTS, drawing, annotation, segmentation, utilities, cursors, VolumeRotateTool, RegionSegmentPlusTool, RegionSegmentTool, WholeBodySegmentTool, LabelmapBaseTool, LabelMapEditWithContourTool, splines, version, };
package/dist/esm/index.js CHANGED
@@ -12,7 +12,7 @@ import * as Types from './types';
12
12
  import * as annotation from './stateManagement/annotation';
13
13
  import * as segmentation from './stateManagement/segmentation';
14
14
  import * as splines from './tools/annotation/splines';
15
- import { BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, VolumeCroppingTool, VolumeCroppingControlTool, 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, UltrasoundPleuraBLineTool, MagnifyTool, AdvancedMagnifyTool, ReferenceCursors, PaintFillTool, ScaleOverlayTool, OrientationMarkerTool, OverlayGridTool, SegmentationIntersectionTool, EraserTool, SculptorTool, SegmentSelectTool, WindowLevelRegionTool, VolumeRotateTool, RegionSegmentPlusTool, RegionSegmentTool, WholeBodySegmentTool, LabelmapBaseTool, SegmentLabelTool, LabelMapEditWithContourTool, } from './tools';
15
+ import { BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, TrackballRotateTool, VolumeCroppingTool, VolumeCroppingControlTool, 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, UltrasoundPleuraBLineTool, MagnifyTool, AdvancedMagnifyTool, ReferenceCursors, PaintFillTool, ScaleOverlayTool, OrientationMarkerTool, OrientationControllerTool, OverlayGridTool, SegmentationIntersectionTool, EraserTool, SculptorTool, SegmentSelectTool, WindowLevelRegionTool, VolumeRotateTool, RegionSegmentPlusTool, RegionSegmentTool, WholeBodySegmentTool, LabelmapBaseTool, SegmentLabelTool, LabelMapEditWithContourTool, } from './tools';
16
16
  import VideoRedactionTool from './tools/annotation/VideoRedactionTool';
17
17
  import * as Enums from './enums';
18
- export { VideoRedactionTool, init, destroy, addTool, removeTool, cancelActiveManipulations, BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, SegmentBidirectionalTool, TrackballRotateTool, VolumeCroppingTool, VolumeCroppingControlTool, 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, UltrasoundPleuraBLineTool, KeyImageTool, MagnifyTool, AdvancedMagnifyTool, ReferenceCursors, ScaleOverlayTool, SculptorTool, EraserTool, RectangleScissorsTool, CircleScissorsTool, SphereScissorsTool, RectangleROIThresholdTool, RectangleROIStartEndThresholdTool, CircleROIStartEndThresholdTool, BrushTool, OrientationMarkerTool, SegmentSelectTool, SegmentLabelTool, synchronizers, Synchronizer, SynchronizerManager, PaintFillTool, Types, state, ToolGroupManager, store, Enums, CONSTANTS, drawing, annotation, segmentation, utilities, cursors, VolumeRotateTool, RegionSegmentPlusTool, RegionSegmentTool, WholeBodySegmentTool, LabelmapBaseTool, LabelMapEditWithContourTool, splines, version, };
18
+ export { VideoRedactionTool, init, destroy, addTool, removeTool, cancelActiveManipulations, BaseTool, AnnotationTool, AnnotationDisplayTool, PanTool, SegmentBidirectionalTool, TrackballRotateTool, VolumeCroppingTool, VolumeCroppingControlTool, 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, UltrasoundPleuraBLineTool, KeyImageTool, MagnifyTool, AdvancedMagnifyTool, ReferenceCursors, ScaleOverlayTool, SculptorTool, EraserTool, RectangleScissorsTool, CircleScissorsTool, SphereScissorsTool, RectangleROIThresholdTool, RectangleROIStartEndThresholdTool, CircleROIStartEndThresholdTool, BrushTool, OrientationMarkerTool, OrientationControllerTool, SegmentSelectTool, SegmentLabelTool, synchronizers, Synchronizer, SynchronizerManager, PaintFillTool, Types, state, ToolGroupManager, store, Enums, CONSTANTS, drawing, annotation, segmentation, utilities, cursors, VolumeRotateTool, RegionSegmentPlusTool, RegionSegmentTool, WholeBodySegmentTool, LabelmapBaseTool, LabelMapEditWithContourTool, splines, version, };
@@ -0,0 +1,38 @@
1
+ import { BaseTool } from './base';
2
+ declare class OrientationControllerTool extends BaseTool {
3
+ static toolName: string;
4
+ private widget;
5
+ private resizeObservers;
6
+ private cameraHandlers;
7
+ constructor(toolProps?: {}, defaultToolProps?: {
8
+ supportedInteractionTypes: string[];
9
+ configuration: {
10
+ enabled: boolean;
11
+ opacity: number;
12
+ size: number;
13
+ position: string;
14
+ colorScheme: string;
15
+ letterColorScheme: string;
16
+ showEdgeFaces: boolean;
17
+ showCornerFaces: boolean;
18
+ keepOrientationUp: boolean;
19
+ };
20
+ });
21
+ private _getViewportsInfo;
22
+ private getPositionConfig;
23
+ private getFaceColors;
24
+ private getLetterColors;
25
+ onSetToolEnabled(): void;
26
+ onSetToolDisabled(): void;
27
+ onSetToolConfiguration: () => void;
28
+ private onViewportAdded;
29
+ private onViewportRemoved;
30
+ private removeMarkers;
31
+ private addMarkers;
32
+ private createAnnotatedRhombActor;
33
+ private addMarkerToViewport;
34
+ private onCameraModified;
35
+ private updateMarkerPosition;
36
+ private animateCameraToOrientation;
37
+ }
38
+ export default OrientationControllerTool;
@@ -0,0 +1,415 @@
1
+ import { BaseTool } from './base';
2
+ import { getEnabledElementByIds, Enums, eventTarget, } from '@cornerstonejs/core';
3
+ import { getToolGroup } from '../store/ToolGroupManager';
4
+ import * as ToolsEnums from '../enums';
5
+ import { vec3, mat4, quat } from 'gl-matrix';
6
+ import { vtkOrientationControllerWidget } from '../utilities/vtkjs/OrientationControllerWidget';
7
+ const ADD_MARKER_DELAY_MS = 500;
8
+ const POSITION_RETRY_DELAY_MS = 1000;
9
+ const FACE_COLOR_SCHEMES = {
10
+ marker: {
11
+ topBottom: [0, 0, 255],
12
+ frontBack: [0, 255, 255],
13
+ leftRight: [255, 255, 0],
14
+ },
15
+ gray: {
16
+ topBottom: [180, 180, 180],
17
+ frontBack: [180, 180, 180],
18
+ leftRight: [180, 180, 180],
19
+ },
20
+ rgy: {
21
+ topBottom: [255, 0, 0],
22
+ frontBack: [0, 255, 0],
23
+ leftRight: [255, 255, 0],
24
+ },
25
+ };
26
+ const LETTER_COLOR_SCHEMES = {
27
+ mixed: {
28
+ zMinus: [255, 255, 255],
29
+ zPlus: [255, 255, 255],
30
+ yMinus: [255, 255, 255],
31
+ yPlus: [255, 255, 255],
32
+ xMinus: [0, 0, 0],
33
+ xPlus: [0, 0, 0],
34
+ },
35
+ rgy: {
36
+ zMinus: [255, 255, 255],
37
+ zPlus: [255, 255, 255],
38
+ yMinus: [255, 255, 255],
39
+ yPlus: [255, 255, 255],
40
+ xMinus: [0, 0, 0],
41
+ xPlus: [0, 0, 0],
42
+ },
43
+ white: {
44
+ zMinus: [255, 255, 255],
45
+ zPlus: [255, 255, 255],
46
+ yMinus: [255, 255, 255],
47
+ yPlus: [255, 255, 255],
48
+ xMinus: [255, 255, 255],
49
+ xPlus: [255, 255, 255],
50
+ },
51
+ black: {
52
+ zMinus: [0, 0, 0],
53
+ zPlus: [0, 0, 0],
54
+ yMinus: [0, 0, 0],
55
+ yPlus: [0, 0, 0],
56
+ xMinus: [0, 0, 0],
57
+ xPlus: [0, 0, 0],
58
+ },
59
+ };
60
+ const DEFAULT_FACE_COLOR_SCHEME = 'rgy';
61
+ const DEFAULT_LETTER_COLOR_SCHEME = 'mixed';
62
+ const ANIMATE_RESET_CAMERA_OPTIONS = {
63
+ resetZoom: false,
64
+ resetPan: true,
65
+ resetToCenter: true,
66
+ };
67
+ class OrientationControllerTool extends BaseTool {
68
+ static { this.toolName = 'OrientationControllerTool'; }
69
+ constructor(toolProps = {}, defaultToolProps = {
70
+ supportedInteractionTypes: ['Mouse'],
71
+ configuration: {
72
+ enabled: true,
73
+ opacity: 1.0,
74
+ size: 0.04,
75
+ position: 'bottom-right',
76
+ colorScheme: 'rgy',
77
+ letterColorScheme: 'mixed',
78
+ showEdgeFaces: true,
79
+ showCornerFaces: true,
80
+ keepOrientationUp: true,
81
+ },
82
+ }) {
83
+ super(toolProps, defaultToolProps);
84
+ this.widget = new vtkOrientationControllerWidget();
85
+ this.resizeObservers = new Map();
86
+ this.cameraHandlers = new Map();
87
+ this._getViewportsInfo = () => {
88
+ const viewports = getToolGroup(this.toolGroupId)?.viewportsInfo;
89
+ return viewports || [];
90
+ };
91
+ this.onSetToolConfiguration = () => {
92
+ const viewportsInfo = this._getViewportsInfo();
93
+ const hasActiveMarkers = viewportsInfo.some(({ viewportId }) => {
94
+ return this.widget.getActors(viewportId) !== null;
95
+ });
96
+ if (hasActiveMarkers) {
97
+ this.removeMarkers();
98
+ this.addMarkers();
99
+ }
100
+ };
101
+ this.onViewportAdded = (evt) => {
102
+ const { viewportId, renderingEngineId, toolGroupId } = evt.detail;
103
+ if (toolGroupId !== this.toolGroupId) {
104
+ return;
105
+ }
106
+ if (this.widget.getActors(viewportId)) {
107
+ return;
108
+ }
109
+ setTimeout(() => {
110
+ this.addMarkerToViewport(viewportId, renderingEngineId);
111
+ }, ADD_MARKER_DELAY_MS);
112
+ };
113
+ this.onViewportRemoved = (evt) => {
114
+ const { viewportId, renderingEngineId, toolGroupId } = evt.detail;
115
+ if (toolGroupId !== this.toolGroupId) {
116
+ return;
117
+ }
118
+ const enabledElement = getEnabledElementByIds(viewportId, renderingEngineId);
119
+ if (enabledElement) {
120
+ const { viewport } = enabledElement;
121
+ if (viewport.isOrientationChangeable()) {
122
+ this.widget.removeActorsFromViewport(viewportId, viewport);
123
+ }
124
+ const cameraHandler = this.cameraHandlers.get(viewportId);
125
+ if (cameraHandler) {
126
+ viewport.element.removeEventListener(Enums.Events.CAMERA_MODIFIED, cameraHandler);
127
+ this.cameraHandlers.delete(viewportId);
128
+ }
129
+ }
130
+ this.widget.cleanup(viewportId);
131
+ const resizeObserver = this.resizeObservers.get(viewportId);
132
+ if (resizeObserver) {
133
+ resizeObserver.disconnect();
134
+ this.resizeObservers.delete(viewportId);
135
+ }
136
+ };
137
+ this.addMarkers = () => {
138
+ const viewportsInfo = this._getViewportsInfo();
139
+ viewportsInfo.forEach(({ viewportId, renderingEngineId }) => {
140
+ const enabledElement = getEnabledElementByIds(viewportId, renderingEngineId);
141
+ if (!enabledElement) {
142
+ return;
143
+ }
144
+ const { viewport } = enabledElement;
145
+ if (!viewport.isOrientationChangeable()) {
146
+ return;
147
+ }
148
+ if (this.widget.getActors(viewportId)) {
149
+ return;
150
+ }
151
+ setTimeout(() => {
152
+ this.addMarkerToViewport(viewportId, renderingEngineId);
153
+ }, ADD_MARKER_DELAY_MS);
154
+ });
155
+ };
156
+ this.onCameraModified = (evt) => {
157
+ const { viewportId } = evt.detail;
158
+ if (!viewportId) {
159
+ return;
160
+ }
161
+ const actors = this.widget.getActors(viewportId);
162
+ if (!actors) {
163
+ return;
164
+ }
165
+ const viewportsInfo = this._getViewportsInfo();
166
+ const viewportInfo = viewportsInfo.find((vp) => vp.viewportId === viewportId);
167
+ if (!viewportInfo) {
168
+ return;
169
+ }
170
+ const enabledElement = getEnabledElementByIds(viewportId, viewportInfo.renderingEngineId);
171
+ if (!enabledElement) {
172
+ return;
173
+ }
174
+ const { viewport } = enabledElement;
175
+ if (!viewport.isOrientationChangeable()) {
176
+ return;
177
+ }
178
+ const volumeViewport = viewport;
179
+ this.widget.positionActors(volumeViewport, actors, this.getPositionConfig());
180
+ viewport.render();
181
+ };
182
+ }
183
+ getPositionConfig() {
184
+ return {
185
+ position: this.configuration.position || 'bottom-right',
186
+ size: this.configuration.size || 0.04,
187
+ };
188
+ }
189
+ getFaceColors() {
190
+ const colorScheme = this.configuration.colorScheme || 'rgy';
191
+ if (this.configuration.faceColors) {
192
+ const provided = this.configuration.faceColors;
193
+ if (provided.topBottom && provided.frontBack && provided.leftRight) {
194
+ return {
195
+ topBottom: provided.topBottom,
196
+ frontBack: provided.frontBack,
197
+ leftRight: provided.leftRight,
198
+ };
199
+ }
200
+ }
201
+ return (FACE_COLOR_SCHEMES[colorScheme] ??
202
+ FACE_COLOR_SCHEMES[DEFAULT_FACE_COLOR_SCHEME]);
203
+ }
204
+ getLetterColors() {
205
+ const letterColorScheme = this.configuration.letterColorScheme || 'mixed';
206
+ return (LETTER_COLOR_SCHEMES[letterColorScheme] ??
207
+ LETTER_COLOR_SCHEMES[DEFAULT_LETTER_COLOR_SCHEME]);
208
+ }
209
+ onSetToolEnabled() {
210
+ this.removeMarkers();
211
+ this.addMarkers();
212
+ eventTarget.addEventListener(ToolsEnums.Events.TOOLGROUP_VIEWPORT_ADDED, this.onViewportAdded);
213
+ eventTarget.addEventListener(ToolsEnums.Events.TOOLGROUP_VIEWPORT_REMOVED, this.onViewportRemoved);
214
+ }
215
+ onSetToolDisabled() {
216
+ this.removeMarkers();
217
+ eventTarget.removeEventListener(ToolsEnums.Events.TOOLGROUP_VIEWPORT_ADDED, this.onViewportAdded);
218
+ eventTarget.removeEventListener(ToolsEnums.Events.TOOLGROUP_VIEWPORT_REMOVED, this.onViewportRemoved);
219
+ }
220
+ removeMarkers() {
221
+ const viewportsInfo = this._getViewportsInfo();
222
+ viewportsInfo.forEach(({ viewportId, renderingEngineId }) => {
223
+ const enabledElement = getEnabledElementByIds(viewportId, renderingEngineId);
224
+ if (enabledElement) {
225
+ const { viewport } = enabledElement;
226
+ if (viewport.isOrientationChangeable()) {
227
+ this.widget.removeActorsFromViewport(viewportId, viewport);
228
+ }
229
+ const cameraHandler = this.cameraHandlers.get(viewportId);
230
+ if (cameraHandler) {
231
+ viewport.element.removeEventListener(Enums.Events.CAMERA_MODIFIED, cameraHandler);
232
+ this.cameraHandlers.delete(viewportId);
233
+ }
234
+ }
235
+ const resizeObserver = this.resizeObservers.get(viewportId);
236
+ if (resizeObserver) {
237
+ resizeObserver.disconnect();
238
+ this.resizeObservers.delete(viewportId);
239
+ }
240
+ });
241
+ this.widget.cleanup();
242
+ this.resizeObservers.forEach((observer) => observer.disconnect());
243
+ this.resizeObservers.clear();
244
+ this.cameraHandlers.clear();
245
+ }
246
+ createAnnotatedRhombActor() {
247
+ const faceColors = this.getFaceColors();
248
+ const letterColors = this.getLetterColors();
249
+ return this.widget.createActors({
250
+ faceColors,
251
+ letterColors,
252
+ opacity: this.configuration.opacity ?? 1.0,
253
+ showEdgeFaces: this.configuration.showEdgeFaces !== false,
254
+ showCornerFaces: this.configuration.showCornerFaces !== false,
255
+ });
256
+ }
257
+ addMarkerToViewport(viewportId, renderingEngineId) {
258
+ const enabledElement = getEnabledElementByIds(viewportId, renderingEngineId);
259
+ if (!enabledElement) {
260
+ console.warn('OrientationControllerTool: No enabled element found');
261
+ return;
262
+ }
263
+ const { viewport } = enabledElement;
264
+ if (!viewport.isOrientationChangeable()) {
265
+ console.warn('OrientationControllerTool: Viewport does not support orientation changes');
266
+ return;
267
+ }
268
+ const element = viewport.element;
269
+ const volumeViewport = viewport;
270
+ const actors = this.createAnnotatedRhombActor();
271
+ this.widget.addActorsToViewport(viewportId, volumeViewport, actors);
272
+ const positioned = this.widget.positionActors(volumeViewport, actors, this.getPositionConfig());
273
+ if (!positioned) {
274
+ console.warn('OrientationControllerTool: Initial positioning failed, retrying...');
275
+ setTimeout(() => {
276
+ const repositioned = this.widget.positionActors(volumeViewport, actors, this.getPositionConfig());
277
+ if (repositioned) {
278
+ viewport.render();
279
+ }
280
+ else {
281
+ console.error('OrientationControllerTool: Retry positioning also failed');
282
+ }
283
+ }, POSITION_RETRY_DELAY_MS);
284
+ }
285
+ else {
286
+ viewport.render();
287
+ }
288
+ this.widget.syncOverlayViewport(viewportId, volumeViewport);
289
+ this.widget.setupPicker(viewportId, actors);
290
+ this.widget.setupMouseHandlers(viewportId, element, volumeViewport, actors, {
291
+ onFacePicked: (result) => {
292
+ const orientation = this.widget.getOrientationForFace(result.cellId);
293
+ if (orientation) {
294
+ this.animateCameraToOrientation(volumeViewport, orientation.viewPlaneNormal, orientation.viewUp);
295
+ }
296
+ },
297
+ onFaceHover: (result) => {
298
+ if (result && result.actorIndex !== 0) {
299
+ this.widget.highlightFace(result.pickedActor, result.cellId, volumeViewport, false);
300
+ }
301
+ else {
302
+ this.widget.clearHighlight();
303
+ }
304
+ },
305
+ });
306
+ const resizeObserver = new ResizeObserver(() => {
307
+ this.updateMarkerPosition(viewportId, renderingEngineId);
308
+ });
309
+ resizeObserver.observe(element);
310
+ this.resizeObservers.set(viewportId, resizeObserver);
311
+ const cameraHandler = (evt) => {
312
+ const detail = evt.detail;
313
+ if (detail.viewportId === viewportId) {
314
+ this.onCameraModified(evt);
315
+ }
316
+ };
317
+ element.addEventListener(Enums.Events.CAMERA_MODIFIED, cameraHandler);
318
+ this.cameraHandlers.set(viewportId, cameraHandler);
319
+ }
320
+ updateMarkerPosition(viewportId, renderingEngineId) {
321
+ const enabledElement = getEnabledElementByIds(viewportId, renderingEngineId);
322
+ if (!enabledElement) {
323
+ return;
324
+ }
325
+ const actors = this.widget.getActors(viewportId);
326
+ if (!actors) {
327
+ return;
328
+ }
329
+ const { viewport } = enabledElement;
330
+ if (!viewport.isOrientationChangeable()) {
331
+ return;
332
+ }
333
+ this.widget.positionActors(viewport, actors, this.getPositionConfig());
334
+ this.widget.syncOverlayViewport(viewportId, viewport);
335
+ viewport.render();
336
+ }
337
+ animateCameraToOrientation(viewport, targetViewPlaneNormal, targetViewUp) {
338
+ const keepOrientationUp = this.configuration.keepOrientationUp !== false;
339
+ const renderer = viewport.getRenderer();
340
+ const camera = renderer.getActiveCamera();
341
+ const directionOfProjection = camera.getDirectionOfProjection();
342
+ const startViewUpArray = camera.getViewUp();
343
+ const startForward = vec3.fromValues(-directionOfProjection[0], -directionOfProjection[1], -directionOfProjection[2]);
344
+ const startUp = vec3.fromValues(startViewUpArray[0], startViewUpArray[1], startViewUpArray[2]);
345
+ const startRight = vec3.create();
346
+ vec3.cross(startRight, startUp, startForward);
347
+ vec3.normalize(startRight, startRight);
348
+ const startMatrix = mat4.fromValues(startRight[0], startRight[1], startRight[2], 0, startUp[0], startUp[1], startUp[2], 0, startForward[0], startForward[1], startForward[2], 0, 0, 0, 0, 1);
349
+ let targetUp;
350
+ if (keepOrientationUp) {
351
+ targetUp = vec3.fromValues(targetViewUp[0], targetViewUp[1], targetViewUp[2]);
352
+ }
353
+ else {
354
+ const currentUp = vec3.normalize(vec3.create(), startUp);
355
+ const normalizedForward = vec3.create();
356
+ vec3.normalize(normalizedForward, targetViewPlaneNormal);
357
+ const dot = vec3.dot(currentUp, normalizedForward);
358
+ targetUp = vec3.create();
359
+ vec3.scaleAndAdd(targetUp, currentUp, normalizedForward, -dot);
360
+ vec3.normalize(targetUp, targetUp);
361
+ if (vec3.length(targetUp) < 0.001) {
362
+ if (Math.abs(normalizedForward[2]) < 0.9) {
363
+ targetUp = vec3.fromValues(0, 0, 1);
364
+ }
365
+ else {
366
+ targetUp = vec3.fromValues(0, 1, 0);
367
+ }
368
+ const dot2 = vec3.dot(targetUp, normalizedForward);
369
+ vec3.scaleAndAdd(targetUp, targetUp, normalizedForward, -dot2);
370
+ vec3.normalize(targetUp, targetUp);
371
+ }
372
+ }
373
+ const targetRight = vec3.create();
374
+ vec3.cross(targetRight, targetUp, targetViewPlaneNormal);
375
+ vec3.normalize(targetRight, targetRight);
376
+ const targetMatrix = mat4.fromValues(targetRight[0], targetRight[1], targetRight[2], 0, targetUp[0], targetUp[1], targetUp[2], 0, targetViewPlaneNormal[0], targetViewPlaneNormal[1], targetViewPlaneNormal[2], 0, 0, 0, 0, 1);
377
+ const startQuat = mat4.getRotation(quat.create(), startMatrix);
378
+ const targetQuat = mat4.getRotation(quat.create(), targetMatrix);
379
+ let dotProduct = quat.dot(startQuat, targetQuat);
380
+ if (dotProduct < 0) {
381
+ quat.scale(targetQuat, targetQuat, -1);
382
+ dotProduct = -dotProduct;
383
+ }
384
+ const threshold = 0.99996;
385
+ if (dotProduct > threshold) {
386
+ return;
387
+ }
388
+ const steps = 10;
389
+ const duration = 150;
390
+ const stepDuration = duration / steps;
391
+ let currentStep = 0;
392
+ const animate = () => {
393
+ currentStep++;
394
+ const t = currentStep / steps;
395
+ const easedT = t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
396
+ const interpolatedQuat = quat.create();
397
+ quat.slerp(interpolatedQuat, startQuat, targetQuat, easedT);
398
+ const interpolatedMatrix = mat4.create();
399
+ mat4.fromQuat(interpolatedMatrix, interpolatedQuat);
400
+ const interpolatedForward = interpolatedMatrix.slice(8, 11);
401
+ const interpolatedUp = interpolatedMatrix.slice(4, 7);
402
+ viewport.setCamera({
403
+ viewPlaneNormal: interpolatedForward,
404
+ viewUp: interpolatedUp,
405
+ });
406
+ viewport.resetCamera(ANIMATE_RESET_CAMERA_OPTIONS);
407
+ viewport.render();
408
+ if (currentStep < steps) {
409
+ setTimeout(animate, stepDuration);
410
+ }
411
+ };
412
+ animate();
413
+ }
414
+ }
415
+ export default OrientationControllerTool;
@@ -1,7 +1,7 @@
1
- import type vtkPlane from '@kitware/vtk.js/Common/DataModel/Plane';
2
1
  import { AnnotationTool } from './base';
3
2
  import type { Types } from '@cornerstonejs/core';
4
3
  import type { Annotation, Annotations, EventTypes, ToolHandle, PublicToolProps, ToolProps, InteractionTypes, SVGDrawingHelper } from '../types';
4
+ import { type ClippingPlane } from '../utilities/volumeCropping';
5
5
  type ReferenceLine = [
6
6
  viewport: {
7
7
  id: string;
@@ -10,60 +10,39 @@ type ReferenceLine = [
10
10
  },
11
11
  startPoint: Types.Point2,
12
12
  endPoint: Types.Point2,
13
- type: 'min' | 'max'
13
+ type: 'min' | 'max',
14
+ planeIndex?: number
14
15
  ];
15
16
  interface VolumeCroppingAnnotation extends Annotation {
16
17
  data: {
17
18
  handles: {
18
19
  activeOperation: number | null;
19
- toolCenter: Types.Point3;
20
- toolCenterMin: Types.Point3;
21
- toolCenterMax: Types.Point3;
20
+ activeType?: 'min' | 'max';
21
+ activePlaneIndex?: number;
22
+ clippingPlanes: ClippingPlane[];
22
23
  };
23
24
  activeViewportIds: string[];
24
25
  viewportId: string;
25
26
  referenceLines: ReferenceLine[];
26
- clippingPlanes?: vtkPlane[];
27
- clippingPlaneReferenceLines?: ReferenceLine[];
28
27
  orientation?: string;
29
28
  };
30
- isVirtual?: boolean;
31
- virtualNormal?: Types.Point3;
32
29
  }
33
30
  declare class VolumeCroppingControlTool extends AnnotationTool {
34
- _virtualAnnotations: VolumeCroppingAnnotation[];
35
31
  static toolName: any;
36
32
  seriesInstanceUID?: string;
37
- sphereStates: {
38
- point: Types.Point3;
39
- axis: string;
40
- uid: string;
41
- sphereSource: any;
42
- sphereActor: any;
43
- }[];
44
- draggingSphereIndex: number | null;
45
- toolCenter: Types.Point3;
46
- toolCenterMin: Types.Point3;
47
- toolCenterMax: Types.Point3;
33
+ clippingPlanes: ClippingPlane[];
48
34
  _getReferenceLineColor?: (viewportId: string) => string;
49
35
  _getReferenceLineControllable?: (viewportId: string) => boolean;
50
36
  constructor(toolProps?: PublicToolProps, defaultToolProps?: ToolProps);
51
- _updateToolCentersFromViewport(viewport: any): void;
52
- initializeViewport: ({ renderingEngineId, viewportId, }: Types.IViewportId) => {
53
- normal: Types.Point3;
54
- point: Types.Point3;
55
- };
37
+ initializeViewport: ({ renderingEngineId, viewportId, }: Types.IViewportId) => void;
56
38
  _getViewportsInfo: () => any[];
57
39
  onSetToolInactive(): void;
58
40
  onSetToolActive(): void;
59
41
  onSetToolEnabled(): void;
60
42
  onSetToolDisabled(): void;
61
43
  resetCroppingSpheres: () => void;
62
- computeToolCenter: () => void;
63
- _computeToolCenter: (viewportsInfo: any) => void;
64
- _getOrientationFromNormal(normal: Types.Point3): string | null;
65
- _syncWithVolumeCroppingTool(originalClippingPlanes: any): void;
66
- setToolCenter(toolCenter: Types.Point3, handleType: any): void;
44
+ _initializeViewports: (viewportsInfo: Types.IViewportId[]) => void;
45
+ _syncWithVolumeCroppingTool(originalClippingPlanes: ClippingPlane[]): void;
67
46
  addNewAnnotation(evt: EventTypes.InteractionEventType): VolumeCroppingAnnotation;
68
47
  cancel: () => void;
69
48
  isPointNearTool: (element: HTMLDivElement, annotation: VolumeCroppingAnnotation, canvasCoords: Types.Point2, proximity: number) => boolean;
@@ -78,14 +57,10 @@ declare class VolumeCroppingControlTool extends AnnotationTool {
78
57
  _onNewVolume: () => void;
79
58
  _unsubscribeToViewportNewVolumeSet(viewportsInfo: any): void;
80
59
  _subscribeToViewportNewVolumeSet(viewports: any): void;
81
- _getAnnotationsForViewportsWithDifferentCameras: (enabledElement: any, annotations: any) => any;
82
- _filterViewportWithSameOrientation: (enabledElement: any, referenceAnnotation: any, annotations: any) => any;
83
60
  _activateModify: (element: any) => void;
84
61
  _deactivateModify: (element: any) => void;
85
62
  _endCallback: (evt: EventTypes.InteractionEventType) => void;
86
63
  _dragCallback: (evt: EventTypes.InteractionEventType) => void;
87
- _applyDeltaShiftToSelectedViewportCameras(renderingEngine: any, viewportsAnnotationsToUpdate: any, delta: any): void;
88
- _applyDeltaShiftToViewportCamera(renderingEngine: Types.IRenderingEngine, annotation: any, delta: any): void;
89
64
  _pointNearTool(element: any, annotation: any, canvasCoords: any, proximity: any): boolean;
90
65
  }
91
66
  export default VolumeCroppingControlTool;