@cornerstonejs/tools 4.22.13 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/config.d.ts +4 -0
- package/dist/esm/drawingSvg/drawPath.d.ts +3 -0
- package/dist/esm/drawingSvg/drawPath.js +4 -1
- package/dist/esm/eventListeners/keyboard/keyDownListener.js +2 -2
- package/dist/esm/eventListeners/mouse/getMouseEventPoints.d.ts +1 -1
- package/dist/esm/eventListeners/mouse/getMouseEventPoints.js +19 -1
- package/dist/esm/eventListeners/mouse/mouseDoubleClickListener.js +8 -1
- package/dist/esm/eventListeners/mouse/mouseDownListener.js +37 -5
- package/dist/esm/eventListeners/mouse/mouseMoveListener.js +3 -0
- package/dist/esm/eventListeners/segmentation/imageChangeEventListener.js +60 -92
- package/dist/esm/eventListeners/segmentation/labelmap/onLabelmapSegmentationDataModified.js +49 -21
- package/dist/esm/eventListeners/segmentation/labelmap/performStackLabelmapUpdate.js +7 -13
- package/dist/esm/eventListeners/segmentation/labelmap/performVolumeLabelmapUpdate.js +44 -18
- package/dist/esm/eventListeners/touch/getTouchEventPoints.js +27 -4
- package/dist/esm/eventListeners/touch/touchStartListener.js +27 -9
- package/dist/esm/eventListeners/wheel/wheelListener.js +5 -1
- package/dist/esm/init.js +2 -0
- package/dist/esm/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.js +10 -4
- package/dist/esm/stateManagement/segmentation/SegmentationRenderingEngine.js +23 -20
- package/dist/esm/stateManagement/segmentation/SegmentationRepresentationDisplayRegistry.d.ts +12 -0
- package/dist/esm/stateManagement/segmentation/SegmentationRepresentationDisplayRegistry.js +7 -0
- package/dist/esm/stateManagement/segmentation/SegmentationStateManager.d.ts +1 -11
- package/dist/esm/stateManagement/segmentation/SegmentationStateManager.js +28 -166
- package/dist/esm/stateManagement/segmentation/addColorLUT.js +7 -1
- package/dist/esm/stateManagement/segmentation/getCurrentLabelmapImageIdForViewport.js +16 -1
- package/dist/esm/stateManagement/segmentation/helpers/clearSegmentValue.js +9 -7
- package/dist/esm/stateManagement/segmentation/helpers/getSegmentationActor.d.ts +1 -1
- package/dist/esm/stateManagement/segmentation/helpers/getSegmentationActor.js +3 -2
- package/dist/esm/stateManagement/segmentation/helpers/getViewportLabelmapRenderMode.d.ts +5 -0
- package/dist/esm/stateManagement/segmentation/helpers/getViewportLabelmapRenderMode.js +58 -0
- package/dist/esm/stateManagement/segmentation/helpers/labelmapImageMapperSupport.d.ts +52 -0
- package/dist/esm/stateManagement/segmentation/helpers/labelmapImageMapperSupport.js +246 -0
- package/dist/esm/stateManagement/segmentation/helpers/labelmapSegmentationState.d.ts +1 -0
- package/dist/esm/stateManagement/segmentation/helpers/labelmapSegmentationState.js +1 -0
- package/dist/esm/stateManagement/segmentation/helpers/normalizeSegmentationInput.js +11 -1
- package/dist/esm/stateManagement/segmentation/internalAddSegmentationRepresentation.js +3 -3
- package/dist/esm/stateManagement/segmentation/labelmapModel/index.d.ts +9 -0
- package/dist/esm/stateManagement/segmentation/labelmapModel/index.js +7 -0
- package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapEditTransaction.d.ts +54 -0
- package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapEditTransaction.js +224 -0
- package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageIdMapping.d.ts +6 -0
- package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageIdMapping.js +39 -0
- package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageReferenceResolver.d.ts +23 -0
- package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageReferenceResolver.js +269 -0
- package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLayerStore.d.ts +15 -0
- package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLayerStore.js +160 -0
- package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLegacyAdapter.d.ts +4 -0
- package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLegacyAdapter.js +42 -0
- package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapSegmentBindings.d.ts +11 -0
- package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapSegmentBindings.js +73 -0
- package/dist/esm/stateManagement/segmentation/labelmapModel/normalizeLabelmapSegmentationData.d.ts +17 -0
- package/dist/esm/stateManagement/segmentation/labelmapModel/normalizeLabelmapSegmentationData.js +75 -0
- package/dist/esm/stateManagement/segmentation/labelmapModel/privateLabelmap.d.ts +5 -0
- package/dist/esm/stateManagement/segmentation/labelmapModel/privateLabelmap.js +106 -0
- package/dist/esm/stateManagement/segmentation/models/SegmentModel.d.ts +11 -0
- package/dist/esm/stateManagement/segmentation/models/SegmentModel.js +19 -0
- package/dist/esm/stateManagement/segmentation/models/SegmentationModel.d.ts +12 -0
- package/dist/esm/stateManagement/segmentation/models/SegmentationModel.js +23 -0
- package/dist/esm/stateManagement/segmentation/removeSegmentationRepresentations.js +6 -10
- package/dist/esm/stateManagement/segmentation/segmentIndex.js +24 -0
- package/dist/esm/stateManagement/segmentation/segmentationEventManager.js +2 -9
- package/dist/esm/stateManagement/segmentation/segmentationState.d.ts +2 -1
- package/dist/esm/stateManagement/segmentation/segmentationState.js +4 -1
- package/dist/esm/store/state.js +2 -1
- package/dist/esm/synchronizers/callbacks/imageSliceSyncCallback.js +12 -3
- package/dist/esm/synchronizers/callbacks/presentationViewSyncCallback.js +5 -2
- package/dist/esm/synchronizers/callbacks/zoomPanSyncCallback.js +51 -3
- package/dist/esm/tools/AdvancedMagnifyTool.js +1 -1
- package/dist/esm/tools/CrosshairsTool.js +5 -5
- package/dist/esm/tools/OrientationControllerTool.js +1 -1
- package/dist/esm/tools/OrientationMarkerTool.js +4 -4
- package/dist/esm/tools/PanTool.js +26 -3
- package/dist/esm/tools/PlanarRotateTool.js +19 -4
- package/dist/esm/tools/ReferenceCursors.js +7 -1
- package/dist/esm/tools/SculptorTool/CircleSculptCursor.js +1 -1
- package/dist/esm/tools/TrackballRotateTool.js +3 -2
- package/dist/esm/tools/VolumeCroppingTool.js +3 -2
- package/dist/esm/tools/WindowLevelTool.d.ts +2 -1
- package/dist/esm/tools/WindowLevelTool.js +48 -4
- package/dist/esm/tools/ZoomTool.d.ts +8 -0
- package/dist/esm/tools/ZoomTool.js +92 -11
- package/dist/esm/tools/annotation/AngleTool.js +33 -31
- package/dist/esm/tools/annotation/ArrowAnnotateTool.js +30 -28
- package/dist/esm/tools/annotation/BidirectionalTool.js +51 -49
- package/dist/esm/tools/annotation/CircleROITool.js +49 -44
- package/dist/esm/tools/annotation/CobbAngleTool.js +1 -1
- package/dist/esm/tools/annotation/DragProbeTool.js +1 -1
- package/dist/esm/tools/annotation/ETDRSGridTool.js +1 -1
- package/dist/esm/tools/annotation/EllipticalROITool.js +42 -37
- package/dist/esm/tools/annotation/HeightTool.js +1 -1
- package/dist/esm/tools/annotation/KeyImageTool.js +11 -11
- package/dist/esm/tools/annotation/LabelTool.js +37 -35
- package/dist/esm/tools/annotation/LengthTool.js +35 -33
- package/dist/esm/tools/annotation/LivewireContourSegmentationTool.js +6 -4
- package/dist/esm/tools/annotation/LivewireContourTool.js +1 -1
- package/dist/esm/tools/annotation/PlanarFreehandContourSegmentationTool.js +6 -4
- package/dist/esm/tools/annotation/PlanarFreehandROITool.js +1 -1
- package/dist/esm/tools/annotation/ProbeTool.js +51 -46
- package/dist/esm/tools/annotation/RectangleROITool.js +42 -37
- package/dist/esm/tools/annotation/RegionSegmentPlusTool.js +1 -1
- package/dist/esm/tools/annotation/RegionSegmentTool.js +1 -1
- package/dist/esm/tools/annotation/SplineContourSegmentationTool.js +1 -1
- package/dist/esm/tools/annotation/SplineROITool.js +51 -49
- package/dist/esm/tools/annotation/UltrasoundDirectionalTool.js +1 -1
- package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/UltrasoundPleuraBLineTool.js +57 -55
- package/dist/esm/tools/annotation/VideoRedactionTool.js +1 -1
- package/dist/esm/tools/base/AnnotationDisplayTool.js +9 -6
- package/dist/esm/tools/base/AnnotationTool.js +2 -1
- package/dist/esm/tools/base/BaseTool.js +16 -10
- package/dist/esm/tools/base/ContourSegmentationBaseTool.js +1 -1
- package/dist/esm/tools/base/GrowCutBaseTool.js +2 -2
- package/dist/esm/tools/displayTools/Labelmap/addLabelmapToElement.d.ts +2 -4
- package/dist/esm/tools/displayTools/Labelmap/addLabelmapToElement.js +15 -85
- package/dist/esm/tools/displayTools/Labelmap/labelmapActorStyle.d.ts +5 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapActorStyle.js +191 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.d.ts +4 -3
- package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.js +48 -209
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/createLabelmapRenderPlan.d.ts +3 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/createLabelmapRenderPlan.js +51 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/index.d.ts +4 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/index.js +3 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/legacyVolumePlan.d.ts +14 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/legacyVolumePlan.js +143 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/planarGenericVolumeLabelmap.d.ts +40 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/planarGenericVolumeLabelmap.js +79 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/removeLabelmapRepresentationFromViewport.d.ts +3 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/removeLabelmapRepresentationFromViewport.js +18 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/resolveLabelmapRenderPlan.d.ts +9 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/resolveLabelmapRenderPlan.js +56 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/stackImagePlan.d.ts +11 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/stackImagePlan.js +35 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/types.d.ts +48 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/types.js +0 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/volumeSliceImageMapperPlan.d.ts +13 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/volumeSliceImageMapperPlan.js +34 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan.d.ts +2 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan.js +1 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRepresentationUID.d.ts +8 -0
- package/dist/esm/tools/displayTools/Labelmap/labelmapRepresentationUID.js +18 -0
- package/dist/esm/tools/displayTools/Labelmap/removeLabelmapFromElement.js +2 -5
- package/dist/esm/tools/displayTools/Labelmap/removeLabelmapRepresentationData.d.ts +3 -0
- package/dist/esm/tools/displayTools/Labelmap/removeLabelmapRepresentationData.js +16 -0
- package/dist/esm/tools/displayTools/Labelmap/syncStackLabelmapActors.d.ts +2 -0
- package/dist/esm/tools/displayTools/Labelmap/syncStackLabelmapActors.js +135 -0
- package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapImageMapper.d.ts +16 -0
- package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapImageMapper.js +267 -0
- package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapSliceData.d.ts +27 -0
- package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapSliceData.js +185 -0
- package/dist/esm/tools/displayTools/registerBuiltInSegmentationRepresentationDisplays.d.ts +1 -0
- package/dist/esm/tools/displayTools/registerBuiltInSegmentationRepresentationDisplays.js +16 -0
- package/dist/esm/tools/segmentation/BrushTool.d.ts +9 -2
- package/dist/esm/tools/segmentation/BrushTool.js +109 -25
- package/dist/esm/tools/segmentation/CircleScissorsTool.js +13 -6
- package/dist/esm/tools/segmentation/LabelmapBaseTool.d.ts +2 -3
- package/dist/esm/tools/segmentation/LabelmapBaseTool.js +77 -38
- package/dist/esm/tools/segmentation/LabelmapEditWithContour.js +3 -3
- package/dist/esm/tools/segmentation/PaintFillTool.js +11 -4
- package/dist/esm/tools/segmentation/RectangleROIStartEndThresholdTool.d.ts +2 -0
- package/dist/esm/tools/segmentation/RectangleROIStartEndThresholdTool.js +16 -8
- package/dist/esm/tools/segmentation/RectangleScissorsTool.js +13 -6
- package/dist/esm/tools/segmentation/SegmentBidirectionalTool.js +63 -61
- package/dist/esm/tools/segmentation/SegmentSelectTool.js +4 -4
- package/dist/esm/tools/segmentation/SphereScissorsTool.js +5 -1
- package/dist/esm/tools/segmentation/strategies/BrushStrategy.d.ts +7 -0
- package/dist/esm/tools/segmentation/strategies/BrushStrategy.js +47 -24
- package/dist/esm/tools/segmentation/strategies/compositions/circularCursor.js +49 -15
- package/dist/esm/tools/segmentation/strategies/compositions/determineSegmentIndex.js +2 -2
- package/dist/esm/tools/segmentation/strategies/compositions/dynamicThreshold.js +5 -1
- package/dist/esm/tools/segmentation/strategies/compositions/islandRemovalComposition.js +2 -2
- package/dist/esm/tools/segmentation/strategies/compositions/preview.js +2 -2
- package/dist/esm/tools/segmentation/strategies/compositions/setValue.js +14 -6
- package/dist/esm/tools/segmentation/strategies/utils/crossLayerErase.d.ts +4 -0
- package/dist/esm/tools/segmentation/strategies/utils/crossLayerErase.js +23 -0
- package/dist/esm/tools/segmentation/strategies/utils/getStrategyData.js +1 -1
- package/dist/esm/tools/segmentation/strategies/utils/handleUseSegmentCenterIndex.js +12 -11
- package/dist/esm/tools/segmentation/strategies/utils/labelmapOverlap.d.ts +4 -0
- package/dist/esm/tools/segmentation/strategies/utils/labelmapOverlap.js +41 -0
- package/dist/esm/tools/segmentation/strategies/utils/overwritePolicy.d.ts +3 -0
- package/dist/esm/tools/segmentation/strategies/utils/overwritePolicy.js +31 -0
- package/dist/esm/tools/segmentation/strategies/utils/segmentSeparation.d.ts +3 -0
- package/dist/esm/tools/segmentation/strategies/utils/segmentSeparation.js +38 -0
- package/dist/esm/tools/segmentation/utils/LazyBrushEditController.d.ts +19 -0
- package/dist/esm/tools/segmentation/utils/LazyBrushEditController.js +55 -0
- package/dist/esm/tools/segmentation/utils/lazyBrushPreview.d.ts +3 -0
- package/dist/esm/tools/segmentation/utils/lazyBrushPreview.js +34 -0
- package/dist/esm/tools/segmentation/utils/shouldUseLazyLabelmapEditing.d.ts +3 -0
- package/dist/esm/tools/segmentation/utils/shouldUseLazyLabelmapEditing.js +42 -0
- package/dist/esm/types/LabelmapToolOperationData.d.ts +5 -0
- package/dist/esm/types/LabelmapTypes.d.ts +29 -6
- package/dist/esm/types/SegmentationStateTypes.d.ts +4 -0
- package/dist/esm/utilities/calibrateImageSpacing.js +17 -2
- package/dist/esm/utilities/contours/AnnotationToPointData.js +1 -1
- package/dist/esm/utilities/getSphereBoundsInfo.js +5 -1
- package/dist/esm/utilities/getViewportICamera.d.ts +4 -0
- package/dist/esm/utilities/getViewportICamera.js +23 -0
- package/dist/esm/utilities/getViewportsForAnnotation.js +5 -1
- package/dist/esm/utilities/math/basic/BasicStatsCalculator.js +9 -7
- package/dist/esm/utilities/pointInSurroundingSphereCallback.js +8 -1
- package/dist/esm/utilities/segmentation/InterpolationManager/InterpolationManager.js +121 -118
- package/dist/esm/utilities/segmentation/SegmentStatsCalculator.js +5 -4
- package/dist/esm/utilities/segmentation/VolumetricCalculator.js +1 -1
- package/dist/esm/utilities/segmentation/createLabelmapVolumeForViewport.js +1 -1
- package/dist/esm/utilities/segmentation/getReferenceVolumeForSegmentation.js +1 -1
- package/dist/esm/utilities/segmentation/getReferenceVolumeForSegmentationVolume.js +11 -2
- package/dist/esm/utilities/segmentation/getSegmentIndexAtLabelmapBorder.js +36 -17
- package/dist/esm/utilities/segmentation/getSegmentIndexAtWorldPoint.js +42 -25
- package/dist/esm/utilities/segmentation/getUniqueSegmentIndices.js +3 -30
- package/dist/esm/utilities/segmentation/index.d.ts +2 -1
- package/dist/esm/utilities/segmentation/index.js +2 -1
- package/dist/esm/utilities/segmentation/utilsForWorker.js +2 -2
- package/dist/esm/utilities/segmentation/validateLabelmap.js +1 -1
- package/dist/esm/utilities/stackPrefetch/stackPrefetch.js +0 -1
- package/dist/esm/utilities/touch/index.js +3 -2
- package/dist/esm/utilities/viewportCapabilities.d.ts +16 -0
- package/dist/esm/utilities/viewportCapabilities.js +18 -0
- package/dist/esm/utilities/viewportFilters/filterViewportsWithParallelNormals.d.ts +1 -1
- package/dist/esm/utilities/viewportFilters/filterViewportsWithParallelNormals.js +12 -4
- package/dist/esm/utilities/viewportFilters/filterViewportsWithSameOrientation.d.ts +1 -1
- package/dist/esm/utilities/viewportFilters/filterViewportsWithSameOrientation.js +11 -4
- package/dist/esm/utilities/viewportFilters/getViewportIdsWithToolToRender.js +1 -1
- package/dist/esm/utilities/viewportPresentation.d.ts +3 -0
- package/dist/esm/utilities/viewportPresentation.js +26 -0
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +10 -10
|
@@ -9,6 +9,8 @@ import { resetElementCursor, hideElementCursor, } from '../../cursors/elementCur
|
|
|
9
9
|
import triggerAnnotationRenderForViewportUIDs from '../../utilities/triggerAnnotationRenderForViewportIds';
|
|
10
10
|
import LabelmapBaseTool from './LabelmapBaseTool';
|
|
11
11
|
import { getStrategyData } from './strategies/utils/getStrategyData';
|
|
12
|
+
import LazyBrushEditController from './utils/LazyBrushEditController';
|
|
13
|
+
import { shouldUseLazyLabelmapEditing } from './utils/shouldUseLazyLabelmapEditing';
|
|
12
14
|
import { getActiveSegmentation } from '../../stateManagement/segmentation/getActiveSegmentation';
|
|
13
15
|
class BrushTool extends LabelmapBaseTool {
|
|
14
16
|
constructor(toolProps = {}, defaultToolProps = {
|
|
@@ -81,13 +83,14 @@ class BrushTool extends LabelmapBaseTool {
|
|
|
81
83
|
}) {
|
|
82
84
|
super(toolProps, defaultToolProps);
|
|
83
85
|
this._lastDragInfo = null;
|
|
84
|
-
this.
|
|
86
|
+
this._lazyEdit = new LazyBrushEditController();
|
|
87
|
+
this.onSetToolPassive = (_evt) => {
|
|
85
88
|
this.disableCursor();
|
|
86
89
|
};
|
|
87
90
|
this.onSetToolEnabled = () => {
|
|
88
91
|
this.disableCursor();
|
|
89
92
|
};
|
|
90
|
-
this.onSetToolDisabled = (
|
|
93
|
+
this.onSetToolDisabled = (_evt) => {
|
|
91
94
|
this.disableCursor();
|
|
92
95
|
};
|
|
93
96
|
this.preMouseDownCallback = (evt) => {
|
|
@@ -122,8 +125,14 @@ class BrushTool extends LabelmapBaseTool {
|
|
|
122
125
|
canvas: canvasPoint,
|
|
123
126
|
world: vec3.clone(worldPoint),
|
|
124
127
|
};
|
|
125
|
-
|
|
126
|
-
|
|
128
|
+
this._hoverData = this.createHoverData(element, canvasPoint);
|
|
129
|
+
this._calculateCursor(element, canvasPoint);
|
|
130
|
+
this._resetLazyEditState();
|
|
131
|
+
if (this._isLazyLabelmapEditingEnabled(this._hoverData.viewport)) {
|
|
132
|
+
this._lazyEdit.appendStrokePoint(worldPoint);
|
|
133
|
+
this._captureLazyPreviewCircle();
|
|
134
|
+
}
|
|
135
|
+
triggerAnnotationRenderForViewportUIDs(this._hoverData.viewportIdsToRender);
|
|
127
136
|
const operationData = this.getOperationData(element);
|
|
128
137
|
if (!operationData) {
|
|
129
138
|
return false;
|
|
@@ -177,6 +186,9 @@ class BrushTool extends LabelmapBaseTool {
|
|
|
177
186
|
}
|
|
178
187
|
this._previewData.timer = null;
|
|
179
188
|
const operationData = this.getOperationData(this._previewData.element);
|
|
189
|
+
if (!operationData) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
180
192
|
const enabledElement = getEnabledElement(this._previewData.element);
|
|
181
193
|
if (!enabledElement) {
|
|
182
194
|
return;
|
|
@@ -204,6 +216,9 @@ class BrushTool extends LabelmapBaseTool {
|
|
|
204
216
|
const enabledElement = getEnabledElement(element);
|
|
205
217
|
const { viewport } = enabledElement;
|
|
206
218
|
this.updateCursor(evt);
|
|
219
|
+
if (!this._hoverData) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
207
222
|
const { viewportIdsToRender } = this._hoverData;
|
|
208
223
|
triggerAnnotationRenderForViewportUIDs(viewportIdsToRender);
|
|
209
224
|
const delta = vec2.distance(currentPoints.canvas, this._previewData.startPoint);
|
|
@@ -234,16 +249,26 @@ class BrushTool extends LabelmapBaseTool {
|
|
|
234
249
|
currentCanvas[1],
|
|
235
250
|
]);
|
|
236
251
|
this._hoverData = this.createHoverData(element, currentCanvas);
|
|
237
|
-
this.
|
|
238
|
-
const operationData = this.getOperationData(element);
|
|
239
|
-
if (!operationData) {
|
|
252
|
+
if (!this._hoverData) {
|
|
240
253
|
return;
|
|
241
254
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
255
|
+
this._calculateCursor(element, currentCanvas);
|
|
256
|
+
if (this._isLazyLabelmapEditingEnabled(this._hoverData.viewport)) {
|
|
257
|
+
this._lazyEdit.appendStrokePoint(currentWorld);
|
|
258
|
+
this._captureLazyPreviewCircle();
|
|
259
|
+
this._previewData.preview = null;
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
const operationData = this.getOperationData(element);
|
|
263
|
+
if (!operationData) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
operationData.strokePointsWorld = [
|
|
267
|
+
vec3.clone(this._lastDragInfo.world),
|
|
268
|
+
vec3.clone(currentWorld),
|
|
269
|
+
];
|
|
270
|
+
this._previewData.preview = this.applyActiveStrategy(enabledElement, operationData);
|
|
271
|
+
}
|
|
247
272
|
const currentCanvasClone = vec2.clone(currentCanvas);
|
|
248
273
|
this._lastDragInfo = {
|
|
249
274
|
canvas: currentCanvasClone,
|
|
@@ -262,15 +287,29 @@ class BrushTool extends LabelmapBaseTool {
|
|
|
262
287
|
if (!operationData) {
|
|
263
288
|
return;
|
|
264
289
|
}
|
|
265
|
-
|
|
290
|
+
const isLazyLabelmapEditing = this._isLazyLabelmapEditingEnabled(this._hoverData?.viewport);
|
|
291
|
+
if (isLazyLabelmapEditing && this._previewData.isDrag) {
|
|
292
|
+
operationData.strokePointsWorld = this._lazyEdit
|
|
293
|
+
.getStrokePointsWorld()
|
|
294
|
+
.map((point) => vec3.clone(point));
|
|
295
|
+
this.applyActiveStrategy(enabledElement, operationData);
|
|
296
|
+
}
|
|
297
|
+
else if (!this._previewData.preview && !this._previewData.isDrag) {
|
|
266
298
|
this.applyActiveStrategy(enabledElement, operationData);
|
|
267
299
|
}
|
|
268
300
|
this.doneEditMemo();
|
|
269
301
|
this._deactivateDraw(element);
|
|
270
302
|
resetElementCursor(element);
|
|
271
|
-
this.updateCursor(evt);
|
|
272
303
|
this._editData = null;
|
|
273
304
|
this._lastDragInfo = null;
|
|
305
|
+
if (isLazyLabelmapEditing && this._previewData.isDrag) {
|
|
306
|
+
this._scheduleLazyPreviewCleanup(element, evt.detail.currentPoints.canvas, enabledElement.viewport.id, operationData.segmentationId);
|
|
307
|
+
triggerAnnotationRenderForViewportUIDs(this._hoverData.viewportIdsToRender);
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
this._resetLazyEditState();
|
|
311
|
+
this.updateCursor(evt);
|
|
312
|
+
}
|
|
274
313
|
this.applyActiveStrategyCallback(enabledElement, operationData, StrategyCallbacks.OnInteractionEnd);
|
|
275
314
|
if (!this._previewData.isDrag) {
|
|
276
315
|
this.acceptPreview(element);
|
|
@@ -288,32 +327,69 @@ class BrushTool extends LabelmapBaseTool {
|
|
|
288
327
|
};
|
|
289
328
|
}
|
|
290
329
|
disableCursor() {
|
|
330
|
+
this._clearPendingLazyPreviewCleanup();
|
|
291
331
|
this._hoverData = undefined;
|
|
332
|
+
this._resetLazyEditState();
|
|
292
333
|
this.rejectPreview();
|
|
293
334
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
335
|
+
_isLazyLabelmapEditingEnabled(viewport) {
|
|
336
|
+
return shouldUseLazyLabelmapEditing(viewport ?? this._hoverData?.viewport);
|
|
337
|
+
}
|
|
338
|
+
_resetLazyEditState() {
|
|
339
|
+
this._lazyEdit.reset();
|
|
340
|
+
}
|
|
341
|
+
_clearPendingLazyPreviewCleanup() {
|
|
342
|
+
this._lazyEdit.clearPendingCleanup();
|
|
343
|
+
}
|
|
344
|
+
_refreshCursor(element, centerCanvas) {
|
|
299
345
|
this._hoverData = this.createHoverData(element, centerCanvas);
|
|
300
|
-
this._calculateCursor(element, centerCanvas);
|
|
301
346
|
if (!this._hoverData) {
|
|
302
347
|
return;
|
|
303
348
|
}
|
|
349
|
+
this._calculateCursor(element, centerCanvas);
|
|
304
350
|
BrushTool.activeCursorTool = this;
|
|
305
351
|
triggerAnnotationRenderForViewportUIDs(this._hoverData.viewportIdsToRender);
|
|
306
352
|
}
|
|
307
|
-
|
|
353
|
+
_scheduleLazyPreviewCleanup(element, centerCanvas, viewportId, segmentationId) {
|
|
354
|
+
this._lazyEdit.scheduleCleanup({
|
|
355
|
+
element,
|
|
356
|
+
centerCanvas,
|
|
357
|
+
viewportId,
|
|
358
|
+
segmentationId,
|
|
359
|
+
refreshCursor: this._refreshCursor.bind(this),
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
_captureLazyPreviewCircle() {
|
|
363
|
+
if (!this._isLazyLabelmapEditingEnabled() || !this._hoverData) {
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
this._lazyEdit.capturePreviewCircle(this._hoverData);
|
|
367
|
+
}
|
|
368
|
+
updateCursor(evt) {
|
|
369
|
+
const eventData = evt.detail;
|
|
370
|
+
const { element } = eventData;
|
|
371
|
+
const { currentPoints } = eventData;
|
|
372
|
+
const centerCanvas = currentPoints.canvas;
|
|
373
|
+
this._refreshCursor(element, centerCanvas);
|
|
374
|
+
}
|
|
375
|
+
_calculateCursor(element, _centerCanvas) {
|
|
308
376
|
const enabledElement = getEnabledElement(element);
|
|
309
|
-
|
|
377
|
+
const operationData = this.getOperationData(element);
|
|
378
|
+
if (!enabledElement || !operationData) {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
this.applyActiveStrategyCallback(enabledElement, operationData, StrategyCallbacks.CalculateCursorGeometry);
|
|
310
382
|
}
|
|
311
383
|
getStatistics(element, segmentIndices) {
|
|
312
384
|
if (!element) {
|
|
313
385
|
return;
|
|
314
386
|
}
|
|
315
387
|
const enabledElement = getEnabledElement(element);
|
|
316
|
-
const
|
|
388
|
+
const operationData = this.getOperationData(element);
|
|
389
|
+
if (!enabledElement || !operationData) {
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
const stats = this.applyActiveStrategyCallback(enabledElement, operationData, StrategyCallbacks.GetStatistics, segmentIndices);
|
|
317
393
|
return stats;
|
|
318
394
|
}
|
|
319
395
|
rejectPreview(element = this._previewData.element) {
|
|
@@ -325,7 +401,11 @@ class BrushTool extends LabelmapBaseTool {
|
|
|
325
401
|
if (!enabledElement) {
|
|
326
402
|
return;
|
|
327
403
|
}
|
|
328
|
-
|
|
404
|
+
const operationData = this.getOperationData(element);
|
|
405
|
+
if (!operationData) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
this.applyActiveStrategyCallback(enabledElement, operationData, StrategyCallbacks.RejectPreview);
|
|
329
409
|
this._previewData.preview = null;
|
|
330
410
|
this._previewData.isDrag = false;
|
|
331
411
|
}
|
|
@@ -340,7 +420,11 @@ class BrushTool extends LabelmapBaseTool {
|
|
|
340
420
|
return;
|
|
341
421
|
}
|
|
342
422
|
const enabledElement = getEnabledElement(element);
|
|
343
|
-
|
|
423
|
+
const operationData = this.getOperationData(element);
|
|
424
|
+
if (!enabledElement || !operationData) {
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
this._previewData.preview = this.applyActiveStrategyCallback(enabledElement, operationData, StrategyCallbacks.Interpolate, config.configuration);
|
|
344
428
|
this._previewData.isDrag = true;
|
|
345
429
|
}
|
|
346
430
|
invalidateBrushCursor() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseVolumeViewport,
|
|
1
|
+
import { BaseVolumeViewport, getEnabledElement } from '@cornerstonejs/core';
|
|
2
2
|
import { BaseTool } from '../base';
|
|
3
3
|
import { fillInsideCircle } from './strategies/fillCircle';
|
|
4
4
|
import { eraseInsideCircle } from './strategies/eraseCircle';
|
|
@@ -8,7 +8,9 @@ import { resetElementCursor, hideElementCursor, } from '../../cursors/elementCur
|
|
|
8
8
|
import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds';
|
|
9
9
|
import { segmentLocking, activeSegmentation, segmentIndex as segmentIndexController, config as segmentationConfig, } from '../../stateManagement/segmentation';
|
|
10
10
|
import { getCurrentLabelmapImageIdForViewport, getSegmentation, } from '../../stateManagement/segmentation/segmentationState';
|
|
11
|
+
import getViewportLabelmapRenderMode from '../../stateManagement/segmentation/helpers/getViewportLabelmapRenderMode';
|
|
11
12
|
import LabelmapBaseTool from './LabelmapBaseTool';
|
|
13
|
+
import { getOrCreateLabelmapVolume, resolveLabelmapForSegment, } from '../../stateManagement/segmentation/helpers/labelmapSegmentationState';
|
|
12
14
|
import getEllipseWorldCoordinates from '../../utilities/getEllipseWorldCoordinates';
|
|
13
15
|
import getCenterAndRadiusInCanvas from '../../utilities/getCenterAndRadiusInCanvas';
|
|
14
16
|
class CircleScissorsTool extends LabelmapBaseTool {
|
|
@@ -92,13 +94,18 @@ class CircleScissorsTool extends LabelmapBaseTool {
|
|
|
92
94
|
referencedVolumeId: null,
|
|
93
95
|
imageId: null,
|
|
94
96
|
};
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
const viewportRenderMode = getViewportLabelmapRenderMode(viewport);
|
|
98
|
+
if (viewportRenderMode === 'volume' ||
|
|
99
|
+
viewport instanceof BaseVolumeViewport) {
|
|
100
|
+
const layer = resolveLabelmapForSegment(getSegmentation(segmentationId), segmentIndex);
|
|
101
|
+
const segmentation = layer ? getOrCreateLabelmapVolume(layer) : undefined;
|
|
102
|
+
if (!segmentation) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
98
105
|
this.editData = {
|
|
99
106
|
...this.editData,
|
|
100
|
-
volumeId,
|
|
101
|
-
referencedVolumeId: segmentation.referencedVolumeId,
|
|
107
|
+
volumeId: segmentation.volumeId,
|
|
108
|
+
referencedVolumeId: layer?.referencedVolumeId ?? segmentation.referencedVolumeId,
|
|
102
109
|
};
|
|
103
110
|
}
|
|
104
111
|
else {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { StackViewport } from '@cornerstonejs/core';
|
|
2
1
|
import type { Types } from '@cornerstonejs/core';
|
|
3
2
|
import { BaseTool } from '../base';
|
|
4
3
|
import type vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
|
|
@@ -92,7 +91,7 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
92
91
|
};
|
|
93
92
|
centerCanvas: any;
|
|
94
93
|
segmentIndex: number;
|
|
95
|
-
viewport:
|
|
94
|
+
viewport: Types.IStackViewport | import("@cornerstonejs/core").VolumeViewport;
|
|
96
95
|
segmentationId: string;
|
|
97
96
|
segmentColor: Types.Color;
|
|
98
97
|
viewportIdsToRender: string[];
|
|
@@ -102,7 +101,7 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
102
101
|
segmentationId: string;
|
|
103
102
|
segmentColor: Types.Color;
|
|
104
103
|
};
|
|
105
|
-
protected getOperationData(element?: any): ModifiedLabelmapToolOperationData;
|
|
104
|
+
protected getOperationData(element?: any): ModifiedLabelmapToolOperationData | undefined;
|
|
106
105
|
addPreview(element?: HTMLDivElement, options?: {
|
|
107
106
|
acceptReject: boolean;
|
|
108
107
|
}): any;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getEnabledElement, cache, utilities as csUtils, Enums, eventTarget, BaseVolumeViewport,
|
|
1
|
+
import { getEnabledElement, cache, utilities as csUtils, Enums, eventTarget, BaseVolumeViewport, } from '@cornerstonejs/core';
|
|
2
2
|
import { BaseTool } from '../base';
|
|
3
3
|
import SegmentationRepresentations from '../../enums/SegmentationRepresentations';
|
|
4
4
|
import { getActiveSegmentation } from '../../stateManagement/segmentation/getActiveSegmentation';
|
|
@@ -14,15 +14,10 @@ import { filterAnnotationsForDisplay } from '../../utilities/planar';
|
|
|
14
14
|
import { isPointInsidePolyline3D } from '../../utilities/math/polyline';
|
|
15
15
|
import { triggerSegmentationDataModified } from '../../stateManagement/segmentation/triggerSegmentationEvents';
|
|
16
16
|
import { fillInsideCircle } from './strategies';
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
timerStart: 0,
|
|
22
|
-
timer: null,
|
|
23
|
-
startPoint: [NaN, NaN],
|
|
24
|
-
isDrag: false,
|
|
25
|
-
}; }
|
|
17
|
+
import getViewportLabelmapRenderMode from '../../stateManagement/segmentation/helpers/getViewportLabelmapRenderMode';
|
|
18
|
+
import { getOrCreateLabelmapVolume, resolveLabelmapForSegment, } from '../../stateManagement/segmentation/helpers/labelmapSegmentationState';
|
|
19
|
+
import getViewportICamera from '../../utilities/getViewportICamera';
|
|
20
|
+
class LabelmapBaseTool extends BaseTool {
|
|
26
21
|
constructor(toolProps, defaultToolProps) {
|
|
27
22
|
super(toolProps, defaultToolProps);
|
|
28
23
|
this.memoMap = new Map();
|
|
@@ -44,6 +39,9 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
44
39
|
const memoData = this.acceptedMemoIds.get(id);
|
|
45
40
|
const element = memoData?.element;
|
|
46
41
|
const operationData = this.getOperationData(element);
|
|
42
|
+
if (!operationData) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
47
45
|
operationData.segmentIndex = memoData?.segmentIndex;
|
|
48
46
|
if (element) {
|
|
49
47
|
this.applyActiveStrategyCallback(getEnabledElement(element), operationData, StrategyCallbacks.AcceptPreview);
|
|
@@ -100,40 +98,37 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
100
98
|
return editData;
|
|
101
99
|
}
|
|
102
100
|
getEditData({ viewport, representationData, segmentsLocked, segmentationId, }) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
101
|
+
const viewportRenderMode = getViewportLabelmapRenderMode(viewport);
|
|
102
|
+
const activeSegmentIndex = getActiveSegmentIndex(segmentationId);
|
|
103
|
+
const segmentation = getSegmentation(segmentationId);
|
|
104
|
+
const layerForEdit = activeSegmentIndex
|
|
105
|
+
? resolveLabelmapForSegment(segmentation, activeSegmentIndex)
|
|
106
|
+
: undefined;
|
|
107
|
+
if (viewportRenderMode === 'volume' ||
|
|
108
|
+
viewport instanceof BaseVolumeViewport) {
|
|
109
|
+
const segmentationVolume = layerForEdit
|
|
110
|
+
? getOrCreateLabelmapVolume(layerForEdit)
|
|
111
|
+
: undefined;
|
|
112
|
+
const volumeId = layerForEdit?.volumeId ?? segmentationVolume?.volumeId;
|
|
113
|
+
if (!segmentationVolume || !volumeId) {
|
|
109
114
|
return;
|
|
110
115
|
}
|
|
111
116
|
const actors = viewport.getActors();
|
|
112
|
-
const isStackViewport = viewport instanceof StackViewport;
|
|
113
|
-
if (isStackViewport) {
|
|
114
|
-
const event = new CustomEvent(Enums.Events.ERROR_EVENT, {
|
|
115
|
-
detail: {
|
|
116
|
-
type: 'Segmentation',
|
|
117
|
-
message: 'Cannot perform brush operation on the selected viewport',
|
|
118
|
-
},
|
|
119
|
-
cancelable: true,
|
|
120
|
-
});
|
|
121
|
-
eventTarget.dispatchEvent(event);
|
|
122
|
-
return null;
|
|
123
|
-
}
|
|
124
117
|
const volumes = actors
|
|
125
118
|
.filter((actorEntry) => actorEntry.referencedId)
|
|
126
|
-
.map((actorEntry) => cache.getVolume(actorEntry.referencedId))
|
|
127
|
-
|
|
119
|
+
.map((actorEntry) => cache.getVolume(actorEntry.referencedId))
|
|
120
|
+
.filter((volume) => !!volume);
|
|
128
121
|
const referencedVolumeIdToThreshold = volumes.find((volume) => csUtils.isEqual(volume.dimensions, segmentationVolume.dimensions))?.volumeId || volumes[0]?.volumeId;
|
|
129
122
|
return {
|
|
130
123
|
volumeId,
|
|
131
124
|
referencedVolumeId: this.configuration.threshold?.volumeId ??
|
|
125
|
+
layerForEdit?.referencedVolumeId ??
|
|
126
|
+
segmentationVolume.referencedVolumeId ??
|
|
132
127
|
referencedVolumeIdToThreshold,
|
|
133
128
|
segmentsLocked,
|
|
134
129
|
};
|
|
135
130
|
}
|
|
136
|
-
|
|
131
|
+
if (viewportRenderMode === 'image') {
|
|
137
132
|
const segmentationImageId = getCurrentLabelmapImageIdForViewport(viewport.id, segmentationId);
|
|
138
133
|
if (!segmentationImageId) {
|
|
139
134
|
return;
|
|
@@ -143,14 +138,30 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
143
138
|
segmentsLocked,
|
|
144
139
|
};
|
|
145
140
|
}
|
|
141
|
+
const event = new CustomEvent(Enums.Events.ERROR_EVENT, {
|
|
142
|
+
detail: {
|
|
143
|
+
type: 'Segmentation',
|
|
144
|
+
message: 'Cannot perform brush operation on the selected viewport',
|
|
145
|
+
},
|
|
146
|
+
cancelable: true,
|
|
147
|
+
});
|
|
148
|
+
eventTarget.dispatchEvent(event);
|
|
149
|
+
return null;
|
|
146
150
|
}
|
|
147
151
|
createHoverData(element, centerCanvas) {
|
|
148
152
|
const enabledElement = getEnabledElement(element);
|
|
149
153
|
const { viewport } = enabledElement;
|
|
150
|
-
const camera = viewport
|
|
154
|
+
const camera = getViewportICamera(viewport);
|
|
151
155
|
const { viewPlaneNormal, viewUp } = camera;
|
|
156
|
+
if (!viewPlaneNormal || !viewUp) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
152
159
|
const viewportIdsToRender = [viewport.id];
|
|
153
|
-
const
|
|
160
|
+
const activeSegmentationData = this.getActiveSegmentationData(viewport);
|
|
161
|
+
if (!activeSegmentationData) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const { segmentIndex, segmentationId, segmentColor } = activeSegmentationData;
|
|
154
165
|
const brushCursor = {
|
|
155
166
|
metadata: {
|
|
156
167
|
viewPlaneNormal: [...viewPlaneNormal],
|
|
@@ -192,11 +203,19 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
192
203
|
}
|
|
193
204
|
getOperationData(element) {
|
|
194
205
|
const editData = this._editData || this.createEditData(element);
|
|
195
|
-
const
|
|
206
|
+
const hoverData = this._hoverData || this.createHoverData(element);
|
|
207
|
+
if (!editData || !hoverData) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const { segmentIndex, segmentationId, brushCursor } = hoverData;
|
|
196
211
|
const { data, metadata = {} } = brushCursor || {};
|
|
197
212
|
const { viewPlaneNormal, viewUp } = metadata;
|
|
213
|
+
const points = data?.editPoints || data?.handles?.points;
|
|
198
214
|
const configColor = this.configuration.preview?.previewColors?.[segmentIndex];
|
|
199
|
-
const { viewport } = getEnabledElement(element);
|
|
215
|
+
const { viewport } = getEnabledElement(element) || {};
|
|
216
|
+
if (!viewport || !segmentIndex || !segmentationId) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
200
219
|
const segmentColor = getSegmentIndexColor(viewport.id, segmentationId, segmentIndex);
|
|
201
220
|
if (!configColor && !segmentColor) {
|
|
202
221
|
return;
|
|
@@ -208,7 +227,7 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
208
227
|
}
|
|
209
228
|
const operationData = {
|
|
210
229
|
...editData,
|
|
211
|
-
points
|
|
230
|
+
points,
|
|
212
231
|
segmentIndex,
|
|
213
232
|
viewPlaneNormal,
|
|
214
233
|
previewOnHover: !this._previewData.isDrag,
|
|
@@ -235,7 +254,11 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
235
254
|
this.rejectPreview(element);
|
|
236
255
|
}
|
|
237
256
|
const enabledElement = getEnabledElement(element);
|
|
238
|
-
const
|
|
257
|
+
const operationData = this.getOperationData(element);
|
|
258
|
+
if (!enabledElement || !operationData) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const results = this.applyActiveStrategyCallback(enabledElement, operationData, StrategyCallbacks.AddPreview);
|
|
239
262
|
_previewData.isDrag = true;
|
|
240
263
|
if (results?.modified) {
|
|
241
264
|
_previewData.preview = results;
|
|
@@ -249,7 +272,11 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
249
272
|
}
|
|
250
273
|
this.doneEditMemo();
|
|
251
274
|
const enabledElement = getEnabledElement(element);
|
|
252
|
-
|
|
275
|
+
const operationData = this.getOperationData(element);
|
|
276
|
+
if (!enabledElement || !operationData) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
this.applyActiveStrategyCallback(enabledElement, operationData, StrategyCallbacks.RejectPreview);
|
|
253
280
|
this._previewData.preview = null;
|
|
254
281
|
this._previewData.isDrag = false;
|
|
255
282
|
}
|
|
@@ -258,6 +285,9 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
258
285
|
return;
|
|
259
286
|
}
|
|
260
287
|
const operationData = this.getOperationData(element);
|
|
288
|
+
if (!operationData) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
261
291
|
if (this.memo && this.memo.id) {
|
|
262
292
|
this.acceptedMemoIds.set(this.memo.id, {
|
|
263
293
|
element,
|
|
@@ -357,6 +387,15 @@ export default class LabelmapBaseTool extends BaseTool {
|
|
|
357
387
|
triggerSegmentationDataModified(segmentationId, slices);
|
|
358
388
|
}
|
|
359
389
|
}
|
|
390
|
+
LabelmapBaseTool.previewData = {
|
|
391
|
+
preview: null,
|
|
392
|
+
element: null,
|
|
393
|
+
timerStart: 0,
|
|
394
|
+
timer: null,
|
|
395
|
+
startPoint: [NaN, NaN],
|
|
396
|
+
isDrag: false,
|
|
397
|
+
};
|
|
398
|
+
export default LabelmapBaseTool;
|
|
360
399
|
function lightenColor(r, g, b, a, factor = 0.4) {
|
|
361
400
|
return [
|
|
362
401
|
Math.round(r + (255 - r) * factor),
|
|
@@ -5,9 +5,6 @@ import BrushTool from './BrushTool';
|
|
|
5
5
|
import * as segmentation from '../../stateManagement/segmentation';
|
|
6
6
|
import { getSegmentationRepresentationsBySegmentationId } from '../../stateManagement/segmentation/getSegmentationRepresentation';
|
|
7
7
|
class LabelMapEditWithContourTool extends PlanarFreehandContourSegmentationTool {
|
|
8
|
-
static { this.toolName = 'LabelMapEditWithContour'; }
|
|
9
|
-
static { this.annotationsToViewportMap = new Map(); }
|
|
10
|
-
static { this.viewportIdsChecked = []; }
|
|
11
8
|
constructor(toolProps = {}) {
|
|
12
9
|
const initialProps = utilities.deepMerge({
|
|
13
10
|
configuration: {
|
|
@@ -119,4 +116,7 @@ class LabelMapEditWithContourTool extends PlanarFreehandContourSegmentationTool
|
|
|
119
116
|
}
|
|
120
117
|
}
|
|
121
118
|
}
|
|
119
|
+
LabelMapEditWithContourTool.toolName = 'LabelMapEditWithContour';
|
|
120
|
+
LabelMapEditWithContourTool.annotationsToViewportMap = new Map();
|
|
121
|
+
LabelMapEditWithContourTool.viewportIdsChecked = [];
|
|
122
122
|
export default LabelMapEditWithContourTool;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { cache, getEnabledElement, utilities as csUtils,
|
|
1
|
+
import { BaseVolumeViewport, cache, getEnabledElement, utilities as csUtils, } from '@cornerstonejs/core';
|
|
2
2
|
import { BaseTool } from '../base';
|
|
3
3
|
import { SegmentationRepresentations } from '../../enums';
|
|
4
4
|
import { triggerSegmentationDataModified } from '../../stateManagement/segmentation/triggerSegmentationEvents';
|
|
5
5
|
import { segmentLocking, activeSegmentation, segmentIndex as segmentIndexController, } from '../../stateManagement/segmentation';
|
|
6
6
|
import floodFill from '../../utilities/segmentation/floodFill';
|
|
7
7
|
import { getCurrentLabelmapImageIdForViewport, getSegmentation, } from '../../stateManagement/segmentation/segmentationState';
|
|
8
|
+
import getViewportLabelmapRenderMode from '../../stateManagement/segmentation/helpers/getViewportLabelmapRenderMode';
|
|
9
|
+
import { getOrCreateLabelmapVolume, resolveLabelmapForSegment, } from '../../stateManagement/segmentation/helpers/labelmapSegmentationState';
|
|
8
10
|
const { transformWorldToIndex, isEqual } = csUtils;
|
|
9
11
|
class PaintFillTool extends BaseTool {
|
|
10
12
|
constructor(toolProps = {}, defaultToolProps = {
|
|
@@ -32,9 +34,14 @@ class PaintFillTool extends BaseTool {
|
|
|
32
34
|
let index;
|
|
33
35
|
let voxelManager;
|
|
34
36
|
this.doneEditMemo();
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
const viewportRenderMode = getViewportLabelmapRenderMode(viewport);
|
|
38
|
+
if (viewportRenderMode === 'volume' ||
|
|
39
|
+
viewport instanceof BaseVolumeViewport) {
|
|
40
|
+
const layer = resolveLabelmapForSegment(getSegmentation(segmentationId), segmentIndex);
|
|
41
|
+
const segmentation = layer ? getOrCreateLabelmapVolume(layer) : undefined;
|
|
42
|
+
if (!segmentation) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
38
45
|
({ dimensions, direction } = segmentation);
|
|
39
46
|
voxelManager = segmentation.voxelManager;
|
|
40
47
|
index = transformWorldToIndex(segmentation.imageData, worldPos);
|
|
@@ -16,6 +16,8 @@ declare class RectangleROIStartEndThresholdTool extends RectangleROITool {
|
|
|
16
16
|
isDrawing: boolean;
|
|
17
17
|
isHandleOutsideImage: boolean;
|
|
18
18
|
constructor(toolProps?: PublicToolProps, defaultToolProps?: ToolProps);
|
|
19
|
+
private _isCoordinateTuple;
|
|
20
|
+
private _resolveViewPlaneCoordinate;
|
|
19
21
|
addNewAnnotation: (evt: EventTypes.InteractionEventType) => {
|
|
20
22
|
highlighted: boolean;
|
|
21
23
|
invalidated: boolean;
|
|
@@ -137,6 +137,7 @@ class RectangleROIStartEndThresholdTool extends RectangleROITool {
|
|
|
137
137
|
}
|
|
138
138
|
const targetId = this.getTargetId(enabledElement.viewport);
|
|
139
139
|
const imageVolume = cache.getVolume(targetId.split(/volumeId:|\?/)[1]);
|
|
140
|
+
this._computeProjectionPoints(annotation, imageVolume);
|
|
140
141
|
this._computePointsInsideVolume(annotation, targetId, imageVolume, enabledElement);
|
|
141
142
|
triggerAnnotationRenderForViewportIds(viewportIdsToRender);
|
|
142
143
|
if (newAnnotation) {
|
|
@@ -172,19 +173,16 @@ class RectangleROIStartEndThresholdTool extends RectangleROITool {
|
|
|
172
173
|
const color = this.getStyle('color', styleSpecifier, annotation);
|
|
173
174
|
const focalPoint = viewport.getCamera().focalPoint;
|
|
174
175
|
const viewplaneNormal = viewport.getCamera().viewPlaneNormal;
|
|
175
|
-
let startCoord = startCoordinate;
|
|
176
|
-
let endCoord = endCoordinate;
|
|
177
|
-
if (
|
|
178
|
-
startCoord = this._getCoordinateForViewplaneNormal(startCoord, viewplaneNormal);
|
|
176
|
+
let startCoord = this._resolveViewPlaneCoordinate(startCoordinate, viewplaneNormal);
|
|
177
|
+
let endCoord = this._resolveViewPlaneCoordinate(endCoordinate, viewplaneNormal);
|
|
178
|
+
if (this._isCoordinateTuple(startCoordinate)) {
|
|
179
179
|
const indexOfDirection = this._getIndexOfCoordinatesForViewplaneNormal(viewplaneNormal);
|
|
180
180
|
data.handles.points.forEach((point) => {
|
|
181
181
|
point[indexOfDirection] = startCoord;
|
|
182
182
|
});
|
|
183
183
|
data.startCoordinate = startCoord;
|
|
184
184
|
}
|
|
185
|
-
if (
|
|
186
|
-
endCoord = this._getCoordinateForViewplaneNormal(endCoord, viewplaneNormal);
|
|
187
|
-
data.endCoordinate = endCoord;
|
|
185
|
+
if (this._isCoordinateTuple(endCoordinate)) {
|
|
188
186
|
data.endCoordinate = endCoord;
|
|
189
187
|
}
|
|
190
188
|
const roundedStartCoord = csUtils.roundToPrecision(startCoord);
|
|
@@ -264,11 +262,21 @@ class RectangleROIStartEndThresholdTool extends RectangleROITool {
|
|
|
264
262
|
this._throttledCalculateCachedStats = debounce(this._calculateCachedStatsTool, this.configuration.throttleTimeout);
|
|
265
263
|
}
|
|
266
264
|
}
|
|
265
|
+
_isCoordinateTuple(value) {
|
|
266
|
+
return Array.isArray(value) || ArrayBuffer.isView(value);
|
|
267
|
+
}
|
|
268
|
+
_resolveViewPlaneCoordinate(coordinate, viewPlaneNormal) {
|
|
269
|
+
if (this._isCoordinateTuple(coordinate)) {
|
|
270
|
+
return this._getCoordinateForViewplaneNormal(coordinate, viewPlaneNormal);
|
|
271
|
+
}
|
|
272
|
+
return coordinate;
|
|
273
|
+
}
|
|
267
274
|
_computeProjectionPoints(annotation, imageVolume) {
|
|
268
275
|
const { data, metadata } = annotation;
|
|
269
276
|
const { viewPlaneNormal, spacingInNormal } = metadata;
|
|
270
277
|
const { imageData } = imageVolume;
|
|
271
|
-
const
|
|
278
|
+
const startCoordinate = this._resolveViewPlaneCoordinate(data.startCoordinate, viewPlaneNormal);
|
|
279
|
+
const endCoordinate = this._resolveViewPlaneCoordinate(data.endCoordinate, viewPlaneNormal);
|
|
272
280
|
const { points } = data.handles;
|
|
273
281
|
const startIJK = transformWorldToIndex(imageData, points[0]);
|
|
274
282
|
const endIJK = transformWorldToIndex(imageData, points[0]);
|