@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
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import { getEnabledElement } from '@cornerstonejs/core';
|
|
2
2
|
export default function getTouchEventPoints(evt, element) {
|
|
3
3
|
const elementToUse = element || evt.currentTarget;
|
|
4
|
+
const { viewport } = getEnabledElement(elementToUse) || {};
|
|
5
|
+
if (!viewport) {
|
|
6
|
+
return [];
|
|
7
|
+
}
|
|
4
8
|
const touches = evt.type === 'touchend' ? evt.changedTouches : evt.touches;
|
|
5
|
-
return Object.keys(touches)
|
|
9
|
+
return Object.keys(touches)
|
|
10
|
+
.map((i) => {
|
|
6
11
|
const clientPoint = _clientToPoint(touches[i]);
|
|
7
12
|
const pagePoint = _pageToPoint(touches[i]);
|
|
8
13
|
const canvasPoint = _pagePointsToCanvasPoints(elementToUse, pagePoint);
|
|
9
|
-
const
|
|
10
|
-
|
|
14
|
+
const worldPoint = getWorldPoint(viewport, canvasPoint);
|
|
15
|
+
if (!worldPoint) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
11
18
|
return {
|
|
12
19
|
page: pagePoint,
|
|
13
20
|
client: clientPoint,
|
|
@@ -21,7 +28,8 @@ export default function getTouchEventPoints(evt, element) {
|
|
|
21
28
|
rotationAngle: touches[i].rotationAngle,
|
|
22
29
|
},
|
|
23
30
|
};
|
|
24
|
-
})
|
|
31
|
+
})
|
|
32
|
+
.filter(Boolean);
|
|
25
33
|
}
|
|
26
34
|
function _pagePointsToCanvasPoints(element, pagePoint) {
|
|
27
35
|
const rect = element.getBoundingClientRect();
|
|
@@ -36,3 +44,18 @@ function _pageToPoint(touch) {
|
|
|
36
44
|
function _clientToPoint(touch) {
|
|
37
45
|
return [touch.clientX, touch.clientY];
|
|
38
46
|
}
|
|
47
|
+
function getWorldPoint(viewport, canvasPoint) {
|
|
48
|
+
try {
|
|
49
|
+
return viewport.canvasToWorld(canvasPoint);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if (isNoMountedDataError(error)) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function isNoMountedDataError(error) {
|
|
59
|
+
return (error instanceof Error &&
|
|
60
|
+
error.message.includes('because no data is mounted'));
|
|
61
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getEnabledElement, triggerEvent } from '@cornerstonejs/core';
|
|
1
|
+
import { getEnabledElement, triggerEvent, utilities, } from '@cornerstonejs/core';
|
|
2
2
|
import Events from '../../enums/Events';
|
|
3
3
|
import { Swipe } from '../../enums/Touch';
|
|
4
4
|
import getTouchEventPoints from './getTouchEventPoints';
|
|
@@ -59,8 +59,8 @@ const defaultTapState = {
|
|
|
59
59
|
tapMaxDistance: 24,
|
|
60
60
|
tapToleranceMs: 300,
|
|
61
61
|
};
|
|
62
|
-
let state =
|
|
63
|
-
let tapState =
|
|
62
|
+
let state = utilities.deepClone(defaultState);
|
|
63
|
+
let tapState = utilities.deepClone(defaultTapState);
|
|
64
64
|
function triggerEventCallback(ele, name, eventDetail) {
|
|
65
65
|
return triggerEvent(ele, name, eventDetail);
|
|
66
66
|
}
|
|
@@ -194,7 +194,7 @@ function _onTouchEnd(evt) {
|
|
|
194
194
|
};
|
|
195
195
|
triggerEventCallback(eventDetail.element, TOUCH_END, eventDetail);
|
|
196
196
|
_checkTouchTap(evt);
|
|
197
|
-
state =
|
|
197
|
+
state = utilities.deepClone(defaultState);
|
|
198
198
|
document.removeEventListener('touchmove', _onTouchDrag);
|
|
199
199
|
document.removeEventListener('touchend', _onTouchEnd);
|
|
200
200
|
}
|
|
@@ -236,7 +236,7 @@ function _checkTouchTap(evt) {
|
|
|
236
236
|
taps: tapState.taps,
|
|
237
237
|
};
|
|
238
238
|
triggerEventCallback(eventDetail.element, TOUCH_TAP, eventDetail);
|
|
239
|
-
tapState =
|
|
239
|
+
tapState = utilities.deepClone(defaultTapState);
|
|
240
240
|
}, tapState.tapToleranceMs);
|
|
241
241
|
}
|
|
242
242
|
function _checkTouchSwipe(evt, deltaPoints) {
|
|
@@ -267,9 +267,22 @@ function _checkTouchSwipe(evt, deltaPoints) {
|
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
269
|
function _updateTouchEventsLastPoints(element, lastPoints) {
|
|
270
|
-
const { viewport } = getEnabledElement(element);
|
|
271
|
-
|
|
272
|
-
|
|
270
|
+
const { viewport } = getEnabledElement(element) || {};
|
|
271
|
+
if (!viewport) {
|
|
272
|
+
return lastPoints;
|
|
273
|
+
}
|
|
274
|
+
return lastPoints
|
|
275
|
+
.map((lp) => {
|
|
276
|
+
let world;
|
|
277
|
+
try {
|
|
278
|
+
world = viewport.canvasToWorld(lp.canvas);
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
if (isNoMountedDataError(error)) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
throw error;
|
|
285
|
+
}
|
|
273
286
|
return {
|
|
274
287
|
page: lp.page,
|
|
275
288
|
client: lp.client,
|
|
@@ -277,6 +290,11 @@ function _updateTouchEventsLastPoints(element, lastPoints) {
|
|
|
277
290
|
world,
|
|
278
291
|
touch: lp.touch,
|
|
279
292
|
};
|
|
280
|
-
})
|
|
293
|
+
})
|
|
294
|
+
.filter(Boolean);
|
|
295
|
+
}
|
|
296
|
+
function isNoMountedDataError(error) {
|
|
297
|
+
return (error instanceof Error &&
|
|
298
|
+
error.message.includes('because no data is mounted'));
|
|
281
299
|
}
|
|
282
300
|
export default touchStartListener;
|
|
@@ -9,6 +9,10 @@ function wheelListener(evt) {
|
|
|
9
9
|
if (evt.deltaY > -1 && evt.deltaY < 1) {
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
|
+
const points = getMouseEventPoints(evt);
|
|
13
|
+
if (!points) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
12
16
|
evt.preventDefault();
|
|
13
17
|
const { spinX, spinY, pixelX, pixelY } = normalizeWheel(evt);
|
|
14
18
|
const direction = spinY < 0 ? -1 : 1;
|
|
@@ -27,7 +31,7 @@ function wheelListener(evt) {
|
|
|
27
31
|
pixelY,
|
|
28
32
|
direction,
|
|
29
33
|
},
|
|
30
|
-
points
|
|
34
|
+
points,
|
|
31
35
|
};
|
|
32
36
|
triggerEvent(element, Events.MOUSE_WHEEL, eventDetail);
|
|
33
37
|
}
|
package/dist/esm/init.js
CHANGED
|
@@ -10,11 +10,13 @@ import { defaultSegmentationStateManager } from './stateManagement/segmentation/
|
|
|
10
10
|
import segmentationRepresentationModifiedListener from './eventListeners/segmentation/segmentationRepresentationModifiedListener';
|
|
11
11
|
import { setConfig } from './config';
|
|
12
12
|
import segmentationRemovedListener from './eventListeners/segmentation/segmentationRemovedEventListener';
|
|
13
|
+
import { registerBuiltInSegmentationRepresentationDisplays } from './tools/displayTools/registerBuiltInSegmentationRepresentationDisplays';
|
|
13
14
|
let csToolsInitialized = false;
|
|
14
15
|
export function init(defaultConfiguration = {}) {
|
|
15
16
|
if (csToolsInitialized) {
|
|
16
17
|
return;
|
|
17
18
|
}
|
|
19
|
+
registerBuiltInSegmentationRepresentationDisplays();
|
|
18
20
|
setConfig(defaultConfiguration);
|
|
19
21
|
_addCornerstoneEventListeners();
|
|
20
22
|
_addCornerstoneToolsEventListeners();
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { Enums, eventTarget, getEnabledElement, utilities, } from '@cornerstonejs/core';
|
|
2
|
+
function isUnsafeKey(key) {
|
|
3
|
+
return key === '__proto__' || key === 'constructor' || key === 'prototype';
|
|
4
|
+
}
|
|
2
5
|
class FrameOfReferenceSpecificAnnotationManager {
|
|
3
6
|
constructor(uid) {
|
|
4
7
|
this.getGroupKey = (annotationGroupSelector) => {
|
|
@@ -77,6 +80,9 @@ class FrameOfReferenceSpecificAnnotationManager {
|
|
|
77
80
|
const { metadata } = annotation;
|
|
78
81
|
const { FrameOfReferenceUID, toolName } = metadata;
|
|
79
82
|
groupKey = groupKey || FrameOfReferenceUID;
|
|
83
|
+
if (isUnsafeKey(groupKey) || isUnsafeKey(toolName)) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
80
86
|
const annotations = this.annotations;
|
|
81
87
|
let frameOfReferenceSpecificAnnotations = annotations[groupKey];
|
|
82
88
|
if (!frameOfReferenceSpecificAnnotations) {
|
|
@@ -146,13 +152,13 @@ class FrameOfReferenceSpecificAnnotationManager {
|
|
|
146
152
|
return;
|
|
147
153
|
}
|
|
148
154
|
const toolSpecificAnnotations = frameOfReferenceSpecificAnnotations[toolName];
|
|
149
|
-
return
|
|
155
|
+
return utilities.deepClone(toolSpecificAnnotations);
|
|
150
156
|
}
|
|
151
157
|
else if (groupKey) {
|
|
152
158
|
const frameOfReferenceSpecificAnnotations = annotations[groupKey];
|
|
153
|
-
return
|
|
159
|
+
return utilities.deepClone(frameOfReferenceSpecificAnnotations);
|
|
154
160
|
}
|
|
155
|
-
return
|
|
161
|
+
return utilities.deepClone(annotations);
|
|
156
162
|
};
|
|
157
163
|
this.restoreAnnotations = (state, groupKey, toolName) => {
|
|
158
164
|
const annotations = this.annotations;
|
|
@@ -168,7 +174,7 @@ class FrameOfReferenceSpecificAnnotationManager {
|
|
|
168
174
|
annotations[groupKey] = state;
|
|
169
175
|
}
|
|
170
176
|
else {
|
|
171
|
-
this.annotations =
|
|
177
|
+
this.annotations = utilities.deepClone(state);
|
|
172
178
|
}
|
|
173
179
|
};
|
|
174
180
|
this.getAllAnnotations = () => {
|
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
import { triggerEvent, eventTarget, Enums, getRenderingEngines, getEnabledElementByViewportId, } from '@cornerstonejs/core';
|
|
2
2
|
import { SegmentationRepresentations, Events as csToolsEvents, } from '../../enums';
|
|
3
|
-
import Representations from '../../enums/SegmentationRepresentations';
|
|
4
3
|
import { getSegmentation } from './getSegmentation';
|
|
5
4
|
import { getSegmentationRepresentations } from './getSegmentationRepresentation';
|
|
6
|
-
import surfaceDisplay from '../../tools/displayTools/Surface/surfaceDisplay';
|
|
7
|
-
import contourDisplay from '../../tools/displayTools/Contour/contourDisplay';
|
|
8
|
-
import labelmapDisplay from '../../tools/displayTools/Labelmap/labelmapDisplay';
|
|
9
5
|
import { addTool } from '../../store/addTool';
|
|
10
6
|
import { state } from '../../store/state';
|
|
11
7
|
import PlanarFreehandContourSegmentationTool from '../../tools/annotation/PlanarFreehandContourSegmentationTool';
|
|
12
8
|
import { getToolGroupForViewport } from '../../store/ToolGroupManager';
|
|
13
9
|
import { addDefaultSegmentationListener } from './segmentationEventManager';
|
|
14
|
-
|
|
15
|
-
[Representations.Labelmap]: labelmapDisplay,
|
|
16
|
-
[Representations.Contour]: contourDisplay,
|
|
17
|
-
[Representations.Surface]: surfaceDisplay,
|
|
18
|
-
};
|
|
10
|
+
import { getSegmentationRepresentationDisplay } from './SegmentationRepresentationDisplayRegistry';
|
|
19
11
|
const planarContourToolName = PlanarFreehandContourSegmentationTool.toolName;
|
|
20
12
|
class SegmentationRenderingEngine {
|
|
21
13
|
constructor() {
|
|
@@ -108,22 +100,33 @@ class SegmentationRenderingEngine {
|
|
|
108
100
|
if (representation.type === SegmentationRepresentations.Contour) {
|
|
109
101
|
this._addPlanarFreeHandToolIfAbsent(viewport);
|
|
110
102
|
}
|
|
111
|
-
const display =
|
|
103
|
+
const display = getSegmentationRepresentationDisplay(representation.type);
|
|
112
104
|
const segmentation = getSegmentation(representation.segmentationId);
|
|
113
105
|
const existingRepresentation = segmentation.representationData[representation.type] !== undefined;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
106
|
+
if (!display) {
|
|
107
|
+
console.warn(`No display registered for segmentation representation type ${representation.type}.`);
|
|
108
|
+
return Promise.resolve({
|
|
109
|
+
segmentationId: representation.segmentationId,
|
|
110
|
+
type: representation.type,
|
|
119
111
|
});
|
|
120
112
|
}
|
|
121
|
-
|
|
113
|
+
return display
|
|
114
|
+
.render(viewport, representation)
|
|
115
|
+
.then(() => {
|
|
116
|
+
if (!existingRepresentation) {
|
|
117
|
+
addDefaultSegmentationListener(viewport, representation.segmentationId, representation.type);
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
segmentationId: representation.segmentationId,
|
|
121
|
+
type: representation.type,
|
|
122
|
+
};
|
|
123
|
+
})
|
|
124
|
+
.catch((error) => {
|
|
122
125
|
console.error(error);
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
126
|
+
return {
|
|
127
|
+
segmentationId: representation.segmentationId,
|
|
128
|
+
type: representation.type,
|
|
129
|
+
};
|
|
127
130
|
});
|
|
128
131
|
});
|
|
129
132
|
Promise.allSettled(segmentationRenderList).then((results) => {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Types } from '@cornerstonejs/core';
|
|
2
|
+
import type SegmentationRepresentations from '../../enums/SegmentationRepresentations';
|
|
3
|
+
import type { SegmentationRepresentation } from '../../types/SegmentationStateTypes';
|
|
4
|
+
type SegmentationRepresentationUpdateFunction = (segmentationId: string) => Promise<void>;
|
|
5
|
+
export type SegmentationRepresentationDisplay = {
|
|
6
|
+
getUpdateFunction: (viewport: Types.IVolumeViewport | Types.IStackViewport) => SegmentationRepresentationUpdateFunction | void | null;
|
|
7
|
+
render: (viewport: Types.IVolumeViewport | Types.IStackViewport, representation: SegmentationRepresentation) => Promise<void>;
|
|
8
|
+
removeRepresentation: (viewportId: string, segmentationId: string, renderImmediate?: boolean) => void;
|
|
9
|
+
};
|
|
10
|
+
export declare function registerSegmentationRepresentationDisplay(representationType: SegmentationRepresentations, display: SegmentationRepresentationDisplay): void;
|
|
11
|
+
export declare function getSegmentationRepresentationDisplay(representationType: SegmentationRepresentations): SegmentationRepresentationDisplay | undefined;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const segmentationRepresentationDisplays = new Map();
|
|
2
|
+
export function registerSegmentationRepresentationDisplay(representationType, display) {
|
|
3
|
+
segmentationRepresentationDisplays.set(representationType, display);
|
|
4
|
+
}
|
|
5
|
+
export function getSegmentationRepresentationDisplay(representationType) {
|
|
6
|
+
return segmentationRepresentationDisplays.get(representationType);
|
|
7
|
+
}
|
|
@@ -4,9 +4,7 @@ import type { RenderingConfig, RepresentationsData, Segmentation, SegmentationRe
|
|
|
4
4
|
export default class SegmentationStateManager {
|
|
5
5
|
private state;
|
|
6
6
|
readonly uid: string;
|
|
7
|
-
private
|
|
8
|
-
private _labelmapImageIdReferenceMap;
|
|
9
|
-
private _labelmapKeysBySegmentationId;
|
|
7
|
+
private readonly labelmapImageReferenceResolver;
|
|
10
8
|
constructor(uid?: string);
|
|
11
9
|
getState(): Readonly<SegmentationState>;
|
|
12
10
|
private updateState;
|
|
@@ -21,9 +19,7 @@ export default class SegmentationStateManager {
|
|
|
21
19
|
private addDefaultSegmentationRepresentation;
|
|
22
20
|
addLabelmapRepresentation(state: SegmentationState, viewportId: string, segmentationId: string, renderingConfig?: RenderingConfig): void;
|
|
23
21
|
processLabelmapRepresentationAddition(viewportId: string, segmentationId: string): Promise<void>;
|
|
24
|
-
_updateLabelmapSegmentationReferences(segmentationId: any, viewport: any, labelmapImageIds: any, updateCallback: any): string | undefined;
|
|
25
22
|
updateLabelmapSegmentationImageReferences(viewportId: any, segmentationId: any): string;
|
|
26
|
-
_updateAllLabelmapSegmentationImageReferences(viewportId: any, segmentationId: any): void;
|
|
27
23
|
getLabelmapImageIds(representationData: RepresentationsData): any;
|
|
28
24
|
getLabelmapImageIdsForImageId(imageId: string, segmentationId: string): string[];
|
|
29
25
|
getCurrentLabelmapImageIdsForViewport(viewportId: string, segmentationId: string): string[] | undefined;
|
|
@@ -44,11 +40,6 @@ export default class SegmentationStateManager {
|
|
|
44
40
|
segmentationId: string;
|
|
45
41
|
type: SegmentationRepresentations;
|
|
46
42
|
}>;
|
|
47
|
-
_updateLabelmapImageIdReferenceMap({ segmentationId, referenceImageId, labelmapImageId, }: {
|
|
48
|
-
segmentationId: any;
|
|
49
|
-
referenceImageId: any;
|
|
50
|
-
labelmapImageId: any;
|
|
51
|
-
}): void;
|
|
52
43
|
_setActiveSegmentation(state: SegmentationState, viewportId: string, segmentationId: string): void;
|
|
53
44
|
setActiveSegmentation(viewportId: string, segmentationId: string): void;
|
|
54
45
|
getActiveSegmentation(viewportId: string): Segmentation | undefined;
|
|
@@ -79,7 +70,6 @@ export default class SegmentationStateManager {
|
|
|
79
70
|
viewportId: string;
|
|
80
71
|
representations: SegmentationRepresentation[];
|
|
81
72
|
}[];
|
|
82
|
-
private _generateMapKey;
|
|
83
73
|
}
|
|
84
74
|
declare function internalComputeVolumeLabelmapFromStack({ imageIds, options, }: {
|
|
85
75
|
imageIds: string[];
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { utilities as csUtils, getEnabledElementByViewportId, volumeLoader, } from '@cornerstonejs/core';
|
|
2
2
|
import { SegmentationRepresentations } from '../../enums';
|
|
3
3
|
import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';
|
|
4
4
|
import vtkPiecewiseFunction from '@kitware/vtk.js/Common/DataModel/PiecewiseFunction';
|
|
5
|
+
import getViewportLabelmapRenderMode from './helpers/getViewportLabelmapRenderMode';
|
|
5
6
|
import { triggerSegmentationModified, triggerSegmentationRemoved, triggerSegmentationRepresentationModified, triggerSegmentationRepresentationRemoved, } from './triggerSegmentationEvents';
|
|
6
7
|
import { segmentationStyle } from './SegmentationStyle';
|
|
7
8
|
import { triggerSegmentationAdded } from './events/triggerSegmentationAdded';
|
|
9
|
+
import { ensureLabelmapState, LabelmapImageReferenceResolver, syncLegacyLabelmapData, } from './labelmapModel';
|
|
8
10
|
const initialDefaultState = {
|
|
9
11
|
colorLUT: [],
|
|
10
12
|
segmentations: [],
|
|
@@ -12,12 +14,10 @@ const initialDefaultState = {
|
|
|
12
14
|
};
|
|
13
15
|
export default class SegmentationStateManager {
|
|
14
16
|
constructor(uid) {
|
|
15
|
-
this._stackLabelmapImageIdReferenceMap = new Map();
|
|
16
|
-
this._labelmapImageIdReferenceMap = new Map();
|
|
17
|
-
this._labelmapKeysBySegmentationId = new Map();
|
|
18
17
|
uid ||= csUtils.uuidv4();
|
|
19
18
|
this.state = Object.freeze(csUtils.deepClone(initialDefaultState));
|
|
20
19
|
this.uid = uid;
|
|
20
|
+
this.labelmapImageReferenceResolver = new LabelmapImageReferenceResolver(this.getSegmentation.bind(this));
|
|
21
21
|
}
|
|
22
22
|
getState() {
|
|
23
23
|
return this.state;
|
|
@@ -34,9 +34,7 @@ export default class SegmentationStateManager {
|
|
|
34
34
|
return this.state.colorLUT.length;
|
|
35
35
|
}
|
|
36
36
|
resetState() {
|
|
37
|
-
this.
|
|
38
|
-
this._labelmapImageIdReferenceMap.clear();
|
|
39
|
-
this._labelmapKeysBySegmentationId.clear();
|
|
37
|
+
this.labelmapImageReferenceResolver.reset();
|
|
40
38
|
this.state = Object.freeze(csUtils.deepClone(initialDefaultState));
|
|
41
39
|
}
|
|
42
40
|
getSegmentation(segmentationId) {
|
|
@@ -50,6 +48,10 @@ export default class SegmentationStateManager {
|
|
|
50
48
|
return;
|
|
51
49
|
}
|
|
52
50
|
Object.assign(segmentation, payload);
|
|
51
|
+
if (segmentation.representationData?.Labelmap) {
|
|
52
|
+
ensureLabelmapState(segmentation);
|
|
53
|
+
syncLegacyLabelmapData(segmentation);
|
|
54
|
+
}
|
|
53
55
|
});
|
|
54
56
|
triggerSegmentationModified(segmentationId);
|
|
55
57
|
}
|
|
@@ -59,9 +61,12 @@ export default class SegmentationStateManager {
|
|
|
59
61
|
}
|
|
60
62
|
this.updateState((state) => {
|
|
61
63
|
const newSegmentation = csUtils.deepClone(segmentation);
|
|
62
|
-
if (newSegmentation.representationData
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
if (newSegmentation.representationData?.Labelmap) {
|
|
65
|
+
ensureLabelmapState(newSegmentation);
|
|
66
|
+
syncLegacyLabelmapData(newSegmentation);
|
|
67
|
+
}
|
|
68
|
+
const labelmapData = newSegmentation.representationData.Labelmap;
|
|
69
|
+
if (labelmapData?.volumeId && !('imageIds' in labelmapData)) {
|
|
65
70
|
const imageIds = this.getLabelmapImageIds(newSegmentation.representationData);
|
|
66
71
|
newSegmentation.representationData
|
|
67
72
|
.Labelmap.imageIds = imageIds;
|
|
@@ -71,14 +76,7 @@ export default class SegmentationStateManager {
|
|
|
71
76
|
triggerSegmentationAdded(segmentation.segmentationId);
|
|
72
77
|
}
|
|
73
78
|
removeSegmentation(segmentationId) {
|
|
74
|
-
this.
|
|
75
|
-
const keys = this._labelmapKeysBySegmentationId.get(segmentationId);
|
|
76
|
-
if (keys) {
|
|
77
|
-
for (const key of keys) {
|
|
78
|
-
this._labelmapImageIdReferenceMap.delete(key);
|
|
79
|
-
}
|
|
80
|
-
this._labelmapKeysBySegmentationId.delete(segmentationId);
|
|
81
|
-
}
|
|
79
|
+
this.labelmapImageReferenceResolver.removeSegmentation(segmentationId);
|
|
82
80
|
this.updateState((state) => {
|
|
83
81
|
const filteredSegmentations = state.segmentations.filter((segmentation) => segmentation.segmentationId !== segmentationId);
|
|
84
82
|
state.segmentations.splice(0, state.segmentations.length, ...filteredSegmentations);
|
|
@@ -96,6 +94,7 @@ export default class SegmentationStateManager {
|
|
|
96
94
|
});
|
|
97
95
|
if (existingRepresentations.length > 0) {
|
|
98
96
|
console.debug('A segmentation representation of type', type, 'already exists in viewport', viewportId, 'for segmentation', segmentationId);
|
|
97
|
+
triggerSegmentationRepresentationModified(viewportId, segmentationId, type);
|
|
99
98
|
return;
|
|
100
99
|
}
|
|
101
100
|
this.updateState((state) => {
|
|
@@ -162,148 +161,30 @@ export default class SegmentationStateManager {
|
|
|
162
161
|
if (!segmentation) {
|
|
163
162
|
return;
|
|
164
163
|
}
|
|
165
|
-
const volumeViewport = enabledElement.viewport
|
|
164
|
+
const volumeViewport = getViewportLabelmapRenderMode(enabledElement.viewport) === 'volume';
|
|
166
165
|
const { representationData } = segmentation;
|
|
167
|
-
const isBaseVolumeSegmentation =
|
|
168
|
-
const viewport = enabledElement.viewport;
|
|
166
|
+
const isBaseVolumeSegmentation = !!representationData.Labelmap.volumeId;
|
|
169
167
|
if (!volumeViewport && !isBaseVolumeSegmentation) {
|
|
170
168
|
!this.updateLabelmapSegmentationImageReferences(viewportId, segmentation.segmentationId);
|
|
171
169
|
}
|
|
172
170
|
}
|
|
173
|
-
_updateLabelmapSegmentationReferences(segmentationId, viewport, labelmapImageIds, updateCallback) {
|
|
174
|
-
const referenceImageId = viewport.getCurrentImageId();
|
|
175
|
-
let viewableLabelmapImageIdFound = false;
|
|
176
|
-
for (const labelmapImageId of labelmapImageIds) {
|
|
177
|
-
const viewableImageId = viewport.isReferenceViewable({ referencedImageId: labelmapImageId }, { asOverlay: true });
|
|
178
|
-
if (viewableImageId) {
|
|
179
|
-
viewableLabelmapImageIdFound = true;
|
|
180
|
-
this._stackLabelmapImageIdReferenceMap
|
|
181
|
-
.get(segmentationId)
|
|
182
|
-
.set(referenceImageId, labelmapImageId);
|
|
183
|
-
this._updateLabelmapImageIdReferenceMap({
|
|
184
|
-
segmentationId,
|
|
185
|
-
referenceImageId,
|
|
186
|
-
labelmapImageId,
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
if (updateCallback) {
|
|
191
|
-
updateCallback(viewport, segmentationId, labelmapImageIds);
|
|
192
|
-
}
|
|
193
|
-
return viewableLabelmapImageIdFound
|
|
194
|
-
? this._stackLabelmapImageIdReferenceMap
|
|
195
|
-
.get(segmentationId)
|
|
196
|
-
.get(referenceImageId)
|
|
197
|
-
: undefined;
|
|
198
|
-
}
|
|
199
171
|
updateLabelmapSegmentationImageReferences(viewportId, segmentationId) {
|
|
200
|
-
|
|
201
|
-
if (!segmentation) {
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
if (!this._stackLabelmapImageIdReferenceMap.has(segmentationId)) {
|
|
205
|
-
this._stackLabelmapImageIdReferenceMap.set(segmentationId, new Map());
|
|
206
|
-
}
|
|
207
|
-
const { representationData } = segmentation;
|
|
208
|
-
if (!representationData.Labelmap) {
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
const labelmapImageIds = this.getLabelmapImageIds(representationData);
|
|
212
|
-
const enabledElement = getEnabledElementByViewportId(viewportId);
|
|
213
|
-
const stackViewport = enabledElement.viewport;
|
|
214
|
-
return this._updateLabelmapSegmentationReferences(segmentationId, stackViewport, labelmapImageIds, null);
|
|
215
|
-
}
|
|
216
|
-
_updateAllLabelmapSegmentationImageReferences(viewportId, segmentationId) {
|
|
217
|
-
const segmentation = this.getSegmentation(segmentationId);
|
|
218
|
-
if (!segmentation) {
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
if (!this._stackLabelmapImageIdReferenceMap.has(segmentationId)) {
|
|
222
|
-
this._stackLabelmapImageIdReferenceMap.set(segmentationId, new Map());
|
|
223
|
-
}
|
|
224
|
-
const { representationData } = segmentation;
|
|
225
|
-
if (!representationData.Labelmap) {
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
const labelmapImageIds = this.getLabelmapImageIds(representationData);
|
|
229
|
-
const enabledElement = getEnabledElementByViewportId(viewportId);
|
|
230
|
-
const stackViewport = enabledElement.viewport;
|
|
231
|
-
this._updateLabelmapSegmentationReferences(segmentationId, stackViewport, labelmapImageIds, (stackViewport, segmentationId, labelmapImageIds) => {
|
|
232
|
-
const imageIds = stackViewport.getImageIds();
|
|
233
|
-
imageIds.forEach((referenceImageId, index) => {
|
|
234
|
-
for (const labelmapImageId of labelmapImageIds) {
|
|
235
|
-
const viewableImageId = stackViewport.isReferenceViewable({ referencedImageId: labelmapImageId, sliceIndex: index }, { asOverlay: true, withNavigation: true });
|
|
236
|
-
if (viewableImageId) {
|
|
237
|
-
this._stackLabelmapImageIdReferenceMap
|
|
238
|
-
.get(segmentationId)
|
|
239
|
-
.set(referenceImageId, labelmapImageId);
|
|
240
|
-
this._updateLabelmapImageIdReferenceMap({
|
|
241
|
-
segmentationId,
|
|
242
|
-
referenceImageId,
|
|
243
|
-
labelmapImageId,
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
});
|
|
248
|
-
});
|
|
172
|
+
return this.labelmapImageReferenceResolver.updateLabelmapSegmentationImageReferences(viewportId, segmentationId);
|
|
249
173
|
}
|
|
250
174
|
getLabelmapImageIds(representationData) {
|
|
251
|
-
|
|
252
|
-
let labelmapImageIds;
|
|
253
|
-
if (labelmapData.imageIds) {
|
|
254
|
-
labelmapImageIds = labelmapData
|
|
255
|
-
.imageIds;
|
|
256
|
-
}
|
|
257
|
-
else if (!labelmapImageIds &&
|
|
258
|
-
labelmapData.volumeId) {
|
|
259
|
-
const volumeId = labelmapData
|
|
260
|
-
.volumeId;
|
|
261
|
-
const volume = cache.getVolume(volumeId);
|
|
262
|
-
labelmapImageIds = volume.imageIds;
|
|
263
|
-
}
|
|
264
|
-
return labelmapImageIds;
|
|
175
|
+
return this.labelmapImageReferenceResolver.getLabelmapImageIds(representationData);
|
|
265
176
|
}
|
|
266
177
|
getLabelmapImageIdsForImageId(imageId, segmentationId) {
|
|
267
|
-
|
|
268
|
-
segmentationId,
|
|
269
|
-
referenceImageId: imageId,
|
|
270
|
-
});
|
|
271
|
-
return this._labelmapImageIdReferenceMap.get(key);
|
|
178
|
+
return this.labelmapImageReferenceResolver.getLabelmapImageIdsForImageId(imageId, segmentationId);
|
|
272
179
|
}
|
|
273
180
|
getCurrentLabelmapImageIdsForViewport(viewportId, segmentationId) {
|
|
274
|
-
|
|
275
|
-
if (!enabledElement) {
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
278
|
-
const stackViewport = enabledElement.viewport;
|
|
279
|
-
const referenceImageId = stackViewport.getCurrentImageId();
|
|
280
|
-
return this.getLabelmapImageIdsForImageId(referenceImageId, segmentationId);
|
|
181
|
+
return this.labelmapImageReferenceResolver.getCurrentLabelmapImageIdsForViewport(viewportId, segmentationId);
|
|
281
182
|
}
|
|
282
183
|
getCurrentLabelmapImageIdForViewport(viewportId, segmentationId) {
|
|
283
|
-
|
|
284
|
-
if (!enabledElement) {
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
if (!this._stackLabelmapImageIdReferenceMap.has(segmentationId)) {
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
const stackViewport = enabledElement.viewport;
|
|
291
|
-
const currentImageId = stackViewport.getCurrentImageId();
|
|
292
|
-
const imageIdReferenceMap = this._stackLabelmapImageIdReferenceMap.get(segmentationId);
|
|
293
|
-
return imageIdReferenceMap.get(currentImageId);
|
|
184
|
+
return this.labelmapImageReferenceResolver.getCurrentLabelmapImageIdForViewport(viewportId, segmentationId);
|
|
294
185
|
}
|
|
295
186
|
getStackSegmentationImageIdsForViewport(viewportId, segmentationId) {
|
|
296
|
-
|
|
297
|
-
if (!segmentation) {
|
|
298
|
-
return [];
|
|
299
|
-
}
|
|
300
|
-
this._updateAllLabelmapSegmentationImageReferences(viewportId, segmentationId);
|
|
301
|
-
const { viewport } = getEnabledElementByViewportId(viewportId);
|
|
302
|
-
const imageIds = viewport.getImageIds();
|
|
303
|
-
const associatedReferenceImageAndLabelmapImageIds = this._stackLabelmapImageIdReferenceMap.get(segmentationId);
|
|
304
|
-
return imageIds.map((imageId) => {
|
|
305
|
-
return associatedReferenceImageAndLabelmapImageIds.get(imageId);
|
|
306
|
-
});
|
|
187
|
+
return this.labelmapImageReferenceResolver.getStackSegmentationImageIdsForViewport(viewportId, segmentationId);
|
|
307
188
|
}
|
|
308
189
|
removeSegmentationRepresentationsInternal(viewportId, specifier) {
|
|
309
190
|
const removedRepresentations = [];
|
|
@@ -369,23 +250,6 @@ export default class SegmentationStateManager {
|
|
|
369
250
|
}
|
|
370
251
|
return removedRepresentations;
|
|
371
252
|
}
|
|
372
|
-
_updateLabelmapImageIdReferenceMap({ segmentationId, referenceImageId, labelmapImageId, }) {
|
|
373
|
-
const key = this._generateMapKey({ segmentationId, referenceImageId });
|
|
374
|
-
if (!this._labelmapImageIdReferenceMap.has(key)) {
|
|
375
|
-
this._labelmapImageIdReferenceMap.set(key, [labelmapImageId]);
|
|
376
|
-
}
|
|
377
|
-
else {
|
|
378
|
-
const currentValues = this._labelmapImageIdReferenceMap.get(key);
|
|
379
|
-
const newValues = Array.from(new Set([...currentValues, labelmapImageId]));
|
|
380
|
-
this._labelmapImageIdReferenceMap.set(key, newValues);
|
|
381
|
-
}
|
|
382
|
-
let keys = this._labelmapKeysBySegmentationId.get(segmentationId);
|
|
383
|
-
if (!keys) {
|
|
384
|
-
keys = new Set();
|
|
385
|
-
this._labelmapKeysBySegmentationId.set(segmentationId, keys);
|
|
386
|
-
}
|
|
387
|
-
keys.add(key);
|
|
388
|
-
}
|
|
389
253
|
_setActiveSegmentation(state, viewportId, segmentationId) {
|
|
390
254
|
const viewport = state.viewportSegRepresentations[viewportId];
|
|
391
255
|
if (!viewport) {
|
|
@@ -444,13 +308,14 @@ export default class SegmentationStateManager {
|
|
|
444
308
|
}
|
|
445
309
|
setSegmentationRepresentationVisibility(viewportId, specifier, visible) {
|
|
446
310
|
this.updateState((state) => {
|
|
447
|
-
const viewportRepresentations =
|
|
311
|
+
const viewportRepresentations = state.viewportSegRepresentations[viewportId]?.filter((representation) => representation.segmentationId === specifier.segmentationId &&
|
|
312
|
+
representation.type === specifier.type);
|
|
448
313
|
if (!viewportRepresentations) {
|
|
449
314
|
return;
|
|
450
315
|
}
|
|
451
316
|
viewportRepresentations.forEach((representation) => {
|
|
452
317
|
representation.visible = visible;
|
|
453
|
-
Object.
|
|
318
|
+
Object.values(representation.segments).forEach((segment) => {
|
|
454
319
|
segment.visible = visible;
|
|
455
320
|
});
|
|
456
321
|
});
|
|
@@ -491,9 +356,6 @@ export default class SegmentationStateManager {
|
|
|
491
356
|
});
|
|
492
357
|
return result;
|
|
493
358
|
}
|
|
494
|
-
_generateMapKey({ segmentationId, referenceImageId }) {
|
|
495
|
-
return `${segmentationId}-${referenceImageId}`;
|
|
496
|
-
}
|
|
497
359
|
}
|
|
498
360
|
async function internalComputeVolumeLabelmapFromStack({ imageIds, options, }) {
|
|
499
361
|
const segmentationImageIds = imageIds;
|
|
@@ -2,6 +2,8 @@ import { utilities } from '@cornerstonejs/core';
|
|
|
2
2
|
import { defaultSegmentationStateManager } from './SegmentationStateManager';
|
|
3
3
|
import { getNextColorLUTIndex } from './getNextColorLUTIndex';
|
|
4
4
|
import CORNERSTONE_COLOR_LUT from '../../constants/COLOR_LUT';
|
|
5
|
+
const PREVIEW_COLOR_INDEX = 255;
|
|
6
|
+
const MINIMUM_COLOR_LUT_ENTRIES = PREVIEW_COLOR_INDEX + 1;
|
|
5
7
|
export function addColorLUT(colorLUT, index) {
|
|
6
8
|
const segmentationStateManager = defaultSegmentationStateManager;
|
|
7
9
|
const indexToUse = index ?? getNextColorLUTIndex();
|
|
@@ -16,10 +18,14 @@ export function addColorLUT(colorLUT, index) {
|
|
|
16
18
|
}
|
|
17
19
|
return color;
|
|
18
20
|
});
|
|
19
|
-
if (colorLUTToUse.length <
|
|
21
|
+
if (colorLUTToUse.length < MINIMUM_COLOR_LUT_ENTRIES) {
|
|
20
22
|
const missingColorLUTs = CORNERSTONE_COLOR_LUT.slice(colorLUTToUse.length);
|
|
21
23
|
colorLUTToUse = [...colorLUTToUse, ...missingColorLUTs];
|
|
22
24
|
}
|
|
25
|
+
while (colorLUTToUse.length < MINIMUM_COLOR_LUT_ENTRIES) {
|
|
26
|
+
const paletteIndex = ((colorLUTToUse.length - 1) % (CORNERSTONE_COLOR_LUT.length - 1)) + 1;
|
|
27
|
+
colorLUTToUse.push([...CORNERSTONE_COLOR_LUT[paletteIndex]]);
|
|
28
|
+
}
|
|
23
29
|
segmentationStateManager.addColorLUT(colorLUTToUse, indexToUse);
|
|
24
30
|
return indexToUse;
|
|
25
31
|
}
|