@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,8 +1,9 @@
|
|
|
1
1
|
export function handleUseSegmentCenterIndex({ operationData, existingValue, index, }) {
|
|
2
|
-
const { previewSegmentIndex, memo, centerSegmentIndexInfo, previewOnHover, segmentIndex, } = operationData;
|
|
2
|
+
const { previewSegmentIndex, memo, centerSegmentIndexInfo, previewOnHover, segmentIndex, labelValue, } = operationData;
|
|
3
|
+
const activeLabelValue = labelValue ?? segmentIndex;
|
|
3
4
|
const { hasPreviewIndex, hasSegmentIndex, segmentIndex: centerSegmentIndex, } = centerSegmentIndexInfo;
|
|
4
5
|
if (centerSegmentIndex === 0 && hasSegmentIndex && hasPreviewIndex) {
|
|
5
|
-
if (existingValue ===
|
|
6
|
+
if (existingValue === activeLabelValue) {
|
|
6
7
|
return;
|
|
7
8
|
}
|
|
8
9
|
if (previewOnHover) {
|
|
@@ -15,7 +16,7 @@ export function handleUseSegmentCenterIndex({ operationData, existingValue, inde
|
|
|
15
16
|
return;
|
|
16
17
|
}
|
|
17
18
|
if (centerSegmentIndex === 0 && hasSegmentIndex && !hasPreviewIndex) {
|
|
18
|
-
if (existingValue === 0 || existingValue !==
|
|
19
|
+
if (existingValue === 0 || existingValue !== activeLabelValue) {
|
|
19
20
|
return;
|
|
20
21
|
}
|
|
21
22
|
memo.voxelManager.setAtIndex(index, previewSegmentIndex);
|
|
@@ -23,7 +24,7 @@ export function handleUseSegmentCenterIndex({ operationData, existingValue, inde
|
|
|
23
24
|
return;
|
|
24
25
|
}
|
|
25
26
|
if (centerSegmentIndex === 0 && !hasSegmentIndex && hasPreviewIndex) {
|
|
26
|
-
if (existingValue ===
|
|
27
|
+
if (existingValue === activeLabelValue) {
|
|
27
28
|
return;
|
|
28
29
|
}
|
|
29
30
|
if (previewOnHover) {
|
|
@@ -36,7 +37,7 @@ export function handleUseSegmentCenterIndex({ operationData, existingValue, inde
|
|
|
36
37
|
return;
|
|
37
38
|
}
|
|
38
39
|
if (centerSegmentIndex === 0 && !hasSegmentIndex && !hasPreviewIndex) {
|
|
39
|
-
if (existingValue ===
|
|
40
|
+
if (existingValue === activeLabelValue) {
|
|
40
41
|
return;
|
|
41
42
|
}
|
|
42
43
|
if (existingValue === previewSegmentIndex) {
|
|
@@ -48,7 +49,7 @@ export function handleUseSegmentCenterIndex({ operationData, existingValue, inde
|
|
|
48
49
|
if (centerSegmentIndex === previewSegmentIndex &&
|
|
49
50
|
hasSegmentIndex &&
|
|
50
51
|
hasPreviewIndex) {
|
|
51
|
-
if (existingValue ===
|
|
52
|
+
if (existingValue === activeLabelValue) {
|
|
52
53
|
return;
|
|
53
54
|
}
|
|
54
55
|
memo.voxelManager.setAtIndex(index, previewSegmentIndex);
|
|
@@ -57,25 +58,25 @@ export function handleUseSegmentCenterIndex({ operationData, existingValue, inde
|
|
|
57
58
|
if (centerSegmentIndex === previewSegmentIndex &&
|
|
58
59
|
!hasSegmentIndex &&
|
|
59
60
|
hasPreviewIndex) {
|
|
60
|
-
if (existingValue ===
|
|
61
|
+
if (existingValue === activeLabelValue) {
|
|
61
62
|
return;
|
|
62
63
|
}
|
|
63
64
|
memo.voxelManager.setAtIndex(index, previewSegmentIndex);
|
|
64
65
|
return;
|
|
65
66
|
}
|
|
66
|
-
if (centerSegmentIndex ===
|
|
67
|
+
if (centerSegmentIndex === activeLabelValue &&
|
|
67
68
|
hasSegmentIndex &&
|
|
68
69
|
hasPreviewIndex) {
|
|
69
|
-
if (existingValue ===
|
|
70
|
+
if (existingValue === activeLabelValue) {
|
|
70
71
|
return;
|
|
71
72
|
}
|
|
72
73
|
memo.voxelManager.setAtIndex(index, previewSegmentIndex);
|
|
73
74
|
return;
|
|
74
75
|
}
|
|
75
|
-
if (centerSegmentIndex ===
|
|
76
|
+
if (centerSegmentIndex === activeLabelValue &&
|
|
76
77
|
hasSegmentIndex &&
|
|
77
78
|
!hasPreviewIndex) {
|
|
78
|
-
if (existingValue ===
|
|
79
|
+
if (existingValue === activeLabelValue) {
|
|
79
80
|
return;
|
|
80
81
|
}
|
|
81
82
|
memo.voxelManager.setAtIndex(index, previewSegmentIndex);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { InitializedOperationData } from '../BrushStrategy';
|
|
2
|
+
import { eraseCrossLayerOverwrites } from './crossLayerErase';
|
|
3
|
+
declare function prepareOverlapOperationData(operationData: InitializedOperationData): void;
|
|
4
|
+
export { eraseCrossLayerOverwrites, prepareOverlapOperationData };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { getSegmentation } from '../../../../stateManagement/segmentation/getSegmentation';
|
|
2
|
+
import { beginLabelmapEditTransaction, resolveLabelmapLayerEditTarget, } from '../../../../stateManagement/segmentation/helpers/labelmapSegmentationState';
|
|
3
|
+
import { eraseCrossLayerOverwrites } from './crossLayerErase';
|
|
4
|
+
import { resolveOverwriteSegmentIndices } from './overwritePolicy';
|
|
5
|
+
function prepareOverlapOperationData(operationData) {
|
|
6
|
+
const segmentation = getSegmentation(operationData.segmentationId);
|
|
7
|
+
if (!segmentation) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
operationData.overwriteSegmentIndices =
|
|
11
|
+
resolveOverwriteSegmentIndices(operationData);
|
|
12
|
+
const transaction = beginLabelmapEditTransaction(segmentation, {
|
|
13
|
+
segmentIndex: operationData.segmentIndex,
|
|
14
|
+
overwriteSegmentIndices: operationData.overwriteSegmentIndices,
|
|
15
|
+
segmentationVoxelManager: operationData.segmentationVoxelManager,
|
|
16
|
+
segmentationImageData: operationData.segmentationImageData,
|
|
17
|
+
isInObject: operationData.isInObject,
|
|
18
|
+
isInObjectBoundsIJK: operationData.isInObjectBoundsIJK,
|
|
19
|
+
});
|
|
20
|
+
operationData.labelmapEditTransaction = transaction;
|
|
21
|
+
operationData.labelValue = transaction.labelValue;
|
|
22
|
+
operationData.labelmapId = transaction.labelmapId;
|
|
23
|
+
operationData.crossLayerEraseBindings = transaction.crossLayerEraseBindings;
|
|
24
|
+
if (transaction.movedSegment && transaction.activeLayer) {
|
|
25
|
+
const target = resolveLabelmapLayerEditTarget(transaction.activeLayer, {
|
|
26
|
+
viewport: operationData.viewport,
|
|
27
|
+
imageId: operationData.imageId,
|
|
28
|
+
sourceLayer: transaction.sourceLayer,
|
|
29
|
+
});
|
|
30
|
+
if (target.imageId) {
|
|
31
|
+
operationData.imageId = target.imageId;
|
|
32
|
+
}
|
|
33
|
+
if (target.imageData) {
|
|
34
|
+
operationData.segmentationImageData = target.imageData;
|
|
35
|
+
}
|
|
36
|
+
if (target.voxelManager) {
|
|
37
|
+
operationData.segmentationVoxelManager = target.voxelManager;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export { eraseCrossLayerOverwrites, prepareOverlapOperationData };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { getConfig } from '../../../../config';
|
|
2
|
+
import { SegmentationRepresentations } from '../../../../enums';
|
|
3
|
+
import { getSegmentation } from '../../../../stateManagement/segmentation/getSegmentation';
|
|
4
|
+
import { getSegmentationRepresentation } from '../../../../stateManagement/segmentation/getSegmentationRepresentation';
|
|
5
|
+
function resolveOverwriteSegmentIndices(operationData) {
|
|
6
|
+
const { segmentationId, segmentIndex, segmentsLocked, viewport } = operationData;
|
|
7
|
+
const segmentation = getSegmentation(segmentationId);
|
|
8
|
+
if (!segmentation || segmentIndex === 0) {
|
|
9
|
+
return [];
|
|
10
|
+
}
|
|
11
|
+
const overwriteMode = getConfig().segmentation?.overwriteMode ?? 'all';
|
|
12
|
+
if (overwriteMode === 'none') {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
const allSegmentIndices = Object.keys(segmentation.segments)
|
|
16
|
+
.map(Number)
|
|
17
|
+
.filter((candidateSegmentIndex) => candidateSegmentIndex !== segmentIndex &&
|
|
18
|
+
!segmentsLocked.includes(candidateSegmentIndex));
|
|
19
|
+
if (overwriteMode === 'all') {
|
|
20
|
+
return allSegmentIndices;
|
|
21
|
+
}
|
|
22
|
+
const representation = getSegmentationRepresentation(viewport.id, {
|
|
23
|
+
segmentationId,
|
|
24
|
+
type: SegmentationRepresentations.Labelmap,
|
|
25
|
+
});
|
|
26
|
+
if (!representation?.visible) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
return allSegmentIndices.filter((candidateSegmentIndex) => representation.segments[candidateSegmentIndex]?.visible !== false);
|
|
30
|
+
}
|
|
31
|
+
export { resolveOverwriteSegmentIndices };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { getSegmentation } from '../../../../stateManagement/segmentation/getSegmentation';
|
|
2
|
+
import { beginLabelmapEditTransaction, resolveLabelmapLayerEditTarget, } from '../../../../stateManagement/segmentation/helpers/labelmapSegmentationState';
|
|
3
|
+
function separateSegmentIfNeeded(operationData) {
|
|
4
|
+
const segmentation = getSegmentation(operationData.segmentationId);
|
|
5
|
+
if (!segmentation || !operationData.segmentIndex) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
const transaction = beginLabelmapEditTransaction(segmentation, {
|
|
9
|
+
segmentIndex: operationData.segmentIndex,
|
|
10
|
+
overwriteSegmentIndices: operationData.overwriteSegmentIndices,
|
|
11
|
+
segmentationVoxelManager: operationData.segmentationVoxelManager,
|
|
12
|
+
segmentationImageData: operationData.segmentationImageData,
|
|
13
|
+
isInObject: operationData.isInObject,
|
|
14
|
+
isInObjectBoundsIJK: operationData.isInObjectBoundsIJK,
|
|
15
|
+
});
|
|
16
|
+
operationData.labelmapEditTransaction = transaction;
|
|
17
|
+
operationData.labelmapId = transaction.labelmapId;
|
|
18
|
+
operationData.labelValue = transaction.labelValue;
|
|
19
|
+
operationData.crossLayerEraseBindings = transaction.crossLayerEraseBindings;
|
|
20
|
+
if (!transaction.movedSegment || !transaction.activeLayer) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const target = resolveLabelmapLayerEditTarget(transaction.activeLayer, {
|
|
24
|
+
viewport: operationData.viewport,
|
|
25
|
+
imageId: operationData.imageId,
|
|
26
|
+
sourceLayer: transaction.sourceLayer,
|
|
27
|
+
});
|
|
28
|
+
if (target.imageId) {
|
|
29
|
+
operationData.imageId = target.imageId;
|
|
30
|
+
}
|
|
31
|
+
if (target.imageData) {
|
|
32
|
+
operationData.segmentationImageData = target.imageData;
|
|
33
|
+
}
|
|
34
|
+
if (target.voxelManager) {
|
|
35
|
+
operationData.segmentationVoxelManager = target.voxelManager;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export { separateSegmentIfNeeded };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Types } from '@cornerstonejs/core';
|
|
2
|
+
declare class LazyBrushEditController {
|
|
3
|
+
private strokePointsWorld;
|
|
4
|
+
private previewPoints;
|
|
5
|
+
private pendingPreviewCleanup;
|
|
6
|
+
reset(): void;
|
|
7
|
+
clearPendingCleanup(): void;
|
|
8
|
+
appendStrokePoint(worldPoint: Types.Point3): void;
|
|
9
|
+
getStrokePointsWorld(): Types.Point3[];
|
|
10
|
+
capturePreviewCircle(hoverData: any): void;
|
|
11
|
+
scheduleCleanup({ element, centerCanvas, viewportId, segmentationId, refreshCursor, }: {
|
|
12
|
+
element: HTMLDivElement;
|
|
13
|
+
centerCanvas: Types.Point2;
|
|
14
|
+
viewportId: string;
|
|
15
|
+
segmentationId: string;
|
|
16
|
+
refreshCursor: (element: HTMLDivElement, centerCanvas: Types.Point2) => void;
|
|
17
|
+
}): void;
|
|
18
|
+
}
|
|
19
|
+
export default LazyBrushEditController;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { eventTarget } from '@cornerstonejs/core';
|
|
2
|
+
import { Events } from '../../../enums';
|
|
3
|
+
import { appendLazyBrushPreviewCircle, appendLazyBrushStrokePoint, } from './lazyBrushPreview';
|
|
4
|
+
class LazyBrushEditController {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.strokePointsWorld = [];
|
|
7
|
+
this.previewPoints = [];
|
|
8
|
+
this.pendingPreviewCleanup = null;
|
|
9
|
+
}
|
|
10
|
+
reset() {
|
|
11
|
+
this.strokePointsWorld = [];
|
|
12
|
+
this.previewPoints = [];
|
|
13
|
+
}
|
|
14
|
+
clearPendingCleanup() {
|
|
15
|
+
if (!this.pendingPreviewCleanup) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
eventTarget.removeEventListener(Events.SEGMENTATION_RENDERED, this.pendingPreviewCleanup.listener);
|
|
19
|
+
this.pendingPreviewCleanup = null;
|
|
20
|
+
}
|
|
21
|
+
appendStrokePoint(worldPoint) {
|
|
22
|
+
this.strokePointsWorld = appendLazyBrushStrokePoint(this.strokePointsWorld, worldPoint);
|
|
23
|
+
}
|
|
24
|
+
getStrokePointsWorld() {
|
|
25
|
+
return this.strokePointsWorld;
|
|
26
|
+
}
|
|
27
|
+
capturePreviewCircle(hoverData) {
|
|
28
|
+
if (!hoverData) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const circlePoints = hoverData.brushCursor?.data?.editPoints;
|
|
32
|
+
this.previewPoints = appendLazyBrushPreviewCircle(this.previewPoints, circlePoints);
|
|
33
|
+
hoverData.brushCursor.data.handles.points = this.previewPoints;
|
|
34
|
+
}
|
|
35
|
+
scheduleCleanup({ element, centerCanvas, viewportId, segmentationId, refreshCursor, }) {
|
|
36
|
+
this.clearPendingCleanup();
|
|
37
|
+
const listener = ((evt) => {
|
|
38
|
+
const detail = evt.detail;
|
|
39
|
+
if (detail.viewportId !== viewportId ||
|
|
40
|
+
detail.segmentationId !== segmentationId) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
this.clearPendingCleanup();
|
|
44
|
+
this.reset();
|
|
45
|
+
refreshCursor(element, centerCanvas);
|
|
46
|
+
});
|
|
47
|
+
this.pendingPreviewCleanup = {
|
|
48
|
+
viewportId,
|
|
49
|
+
segmentationId,
|
|
50
|
+
listener,
|
|
51
|
+
};
|
|
52
|
+
eventTarget.addEventListener(Events.SEGMENTATION_RENDERED, listener);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export default LazyBrushEditController;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { Types } from '@cornerstonejs/core';
|
|
2
|
+
export declare function appendLazyBrushStrokePoint(points?: Types.Point3[], point?: Types.Point3): Types.Point3[];
|
|
3
|
+
export declare function appendLazyBrushPreviewCircle(existingPoints?: Types.Point3[], circlePoints?: Types.Point3[]): Types.Point3[];
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const EPSILON = 1e-3;
|
|
2
|
+
function clonePoint(point) {
|
|
3
|
+
return [point[0], point[1], point[2]];
|
|
4
|
+
}
|
|
5
|
+
function isSamePoint(a, b) {
|
|
6
|
+
return (Math.abs(a[0] - b[0]) < EPSILON &&
|
|
7
|
+
Math.abs(a[1] - b[1]) < EPSILON &&
|
|
8
|
+
Math.abs(a[2] - b[2]) < EPSILON);
|
|
9
|
+
}
|
|
10
|
+
export function appendLazyBrushStrokePoint(points = [], point) {
|
|
11
|
+
if (!point) {
|
|
12
|
+
return points;
|
|
13
|
+
}
|
|
14
|
+
if (points.length && isSamePoint(points[points.length - 1], point)) {
|
|
15
|
+
return points;
|
|
16
|
+
}
|
|
17
|
+
return [...points, clonePoint(point)];
|
|
18
|
+
}
|
|
19
|
+
export function appendLazyBrushPreviewCircle(existingPoints = [], circlePoints = []) {
|
|
20
|
+
if (!circlePoints.length) {
|
|
21
|
+
return existingPoints;
|
|
22
|
+
}
|
|
23
|
+
const nextCircle = circlePoints.map((point) => clonePoint(point));
|
|
24
|
+
if (!existingPoints.length) {
|
|
25
|
+
return nextCircle;
|
|
26
|
+
}
|
|
27
|
+
const previousCircle = existingPoints.slice(-nextCircle.length);
|
|
28
|
+
const isDuplicateCircle = previousCircle.length === nextCircle.length &&
|
|
29
|
+
previousCircle.every((point, index) => isSamePoint(point, nextCircle[index]));
|
|
30
|
+
if (isDuplicateCircle) {
|
|
31
|
+
return existingPoints;
|
|
32
|
+
}
|
|
33
|
+
return [...existingPoints, ...nextCircle];
|
|
34
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ActorRenderMode, getShouldUseCPURendering, } from '@cornerstonejs/core';
|
|
2
|
+
import { getConfig } from '../../../config';
|
|
3
|
+
const CPU_RENDER_MODES = new Set([
|
|
4
|
+
ActorRenderMode.CPU_IMAGE,
|
|
5
|
+
ActorRenderMode.CPU_VOLUME,
|
|
6
|
+
]);
|
|
7
|
+
function getDefaultActor(viewport) {
|
|
8
|
+
try {
|
|
9
|
+
return viewport.getDefaultActor?.();
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function isCPUViewport(viewport) {
|
|
16
|
+
if (!viewport) {
|
|
17
|
+
return getShouldUseCPURendering();
|
|
18
|
+
}
|
|
19
|
+
const cpuViewport = viewport;
|
|
20
|
+
if (cpuViewport.useCPURendering === true) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
if (cpuViewport._cpuFallbackEnabledElement) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
const defaultActor = getDefaultActor(viewport);
|
|
27
|
+
const renderMode = defaultActor?.actorMapper?.renderMode;
|
|
28
|
+
if (renderMode && CPU_RENDER_MODES.has(renderMode)) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
const actorClassName = typeof defaultActor?.actor?.getClassName === 'function'
|
|
32
|
+
? defaultActor.actor.getClassName()
|
|
33
|
+
: undefined;
|
|
34
|
+
if (actorClassName === 'CanvasActor') {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
return getShouldUseCPURendering();
|
|
38
|
+
}
|
|
39
|
+
export function shouldUseLazyLabelmapEditing(viewport) {
|
|
40
|
+
return (getConfig().segmentation?.overwriteMode !== undefined ||
|
|
41
|
+
isCPUViewport(viewport));
|
|
42
|
+
}
|
|
@@ -2,9 +2,14 @@ import type { Types } from '@cornerstonejs/core';
|
|
|
2
2
|
import type { LabelmapSegmentationDataStack, LabelmapSegmentationDataVolume } from './LabelmapTypes';
|
|
3
3
|
import type vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
|
|
4
4
|
import type { LabelmapMemo } from '../utilities/segmentation/createLabelmapMemo';
|
|
5
|
+
import type { SegmentLabelmapBindingState } from './LabelmapTypes';
|
|
5
6
|
type LabelmapToolOperationData = {
|
|
6
7
|
segmentationId: string;
|
|
7
8
|
segmentIndex: number;
|
|
9
|
+
labelValue?: number;
|
|
10
|
+
labelmapId?: string;
|
|
11
|
+
overwriteSegmentIndices?: number[];
|
|
12
|
+
crossLayerEraseBindings?: SegmentLabelmapBindingState[];
|
|
8
13
|
previewColor?: [number, number, number, number];
|
|
9
14
|
previewSegmentIndex?: number;
|
|
10
15
|
segmentsLocked: number[];
|
|
@@ -14,16 +14,39 @@ export type InactiveLabelmapStyle = {
|
|
|
14
14
|
outlineOpacityInactive?: number;
|
|
15
15
|
};
|
|
16
16
|
export type LabelmapStyle = BaseLabelmapStyle & InactiveLabelmapStyle;
|
|
17
|
-
export type
|
|
18
|
-
|
|
17
|
+
export type LabelmapLayerType = 'volume' | 'stack';
|
|
18
|
+
export type LabelmapLayer = {
|
|
19
|
+
labelmapId: string;
|
|
20
|
+
type: LabelmapLayerType;
|
|
21
|
+
volumeId?: string;
|
|
22
|
+
geometryVolumeId?: string;
|
|
19
23
|
referencedVolumeId?: string;
|
|
24
|
+
referencedImageIds?: string[];
|
|
25
|
+
imageIds?: string[];
|
|
26
|
+
labelToSegmentIndex?: {
|
|
27
|
+
[labelValue: number]: number;
|
|
28
|
+
};
|
|
20
29
|
};
|
|
21
|
-
export type
|
|
22
|
-
|
|
30
|
+
export type SegmentLabelmapBindingState = {
|
|
31
|
+
labelmapId: string;
|
|
32
|
+
labelValue: number;
|
|
23
33
|
};
|
|
24
|
-
export type
|
|
34
|
+
export type LabelmapSegmentationDataShared = {
|
|
35
|
+
referencedImageIds?: string[];
|
|
36
|
+
labelmaps?: {
|
|
37
|
+
[labelmapId: string]: LabelmapLayer;
|
|
38
|
+
};
|
|
39
|
+
segmentBindings?: {
|
|
40
|
+
[segmentIndex: number]: SegmentLabelmapBindingState;
|
|
41
|
+
};
|
|
42
|
+
primaryLabelmapId?: string;
|
|
43
|
+
sourceRepresentationName?: string;
|
|
44
|
+
};
|
|
45
|
+
export type LabelmapSegmentationDataVolume = LabelmapSegmentationDataShared & {
|
|
25
46
|
volumeId?: string;
|
|
26
47
|
referencedVolumeId?: string;
|
|
27
|
-
|
|
48
|
+
};
|
|
49
|
+
export type LabelmapSegmentationDataStack = LabelmapSegmentationDataShared & {
|
|
28
50
|
imageIds?: string[];
|
|
29
51
|
};
|
|
52
|
+
export type LabelmapSegmentationData = LabelmapSegmentationDataShared & LabelmapSegmentationDataVolume & LabelmapSegmentationDataStack;
|
|
@@ -27,6 +27,7 @@ export type Segmentation = {
|
|
|
27
27
|
segments: {
|
|
28
28
|
[segmentIndex: number]: Segment;
|
|
29
29
|
};
|
|
30
|
+
segmentOrder?: number[];
|
|
30
31
|
representationData: RepresentationsData;
|
|
31
32
|
cachedStats: {
|
|
32
33
|
[key: string]: unknown;
|
|
@@ -37,6 +38,7 @@ export type LabelmapRenderingConfig = {
|
|
|
37
38
|
ofun: vtkPiecewiseFunction;
|
|
38
39
|
colorLUTIndex: number;
|
|
39
40
|
blendMode?: coreEnums.BlendModes;
|
|
41
|
+
useSliceRendering?: boolean;
|
|
40
42
|
};
|
|
41
43
|
export type ContourRenderingConfig = {};
|
|
42
44
|
export type SurfaceRenderingConfig = {};
|
|
@@ -80,6 +82,7 @@ export type SegmentationPublicInput = {
|
|
|
80
82
|
segments?: {
|
|
81
83
|
[segmentIndex: number]: Partial<Segment>;
|
|
82
84
|
};
|
|
85
|
+
segmentOrder?: number[];
|
|
83
86
|
label?: string;
|
|
84
87
|
fallbackLabel?: string;
|
|
85
88
|
cachedStats?: {
|
|
@@ -93,6 +96,7 @@ export type RepresentationPublicInput = {
|
|
|
93
96
|
config?: {
|
|
94
97
|
colorLUTOrIndex?: Types.ColorLUT | number;
|
|
95
98
|
blendMode?: coreEnums.BlendModes;
|
|
99
|
+
useSliceRendering?: boolean;
|
|
96
100
|
};
|
|
97
101
|
};
|
|
98
102
|
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { utilities, Enums } from '@cornerstonejs/core';
|
|
2
|
+
import { viewportSupportsStackCalibration, viewportSupportsStackCompatibility, } from './viewportCapabilities';
|
|
2
3
|
const { calibratedPixelSpacingMetadataProvider } = utilities;
|
|
3
4
|
export default function calibrateImageSpacing(imageId, renderingEngine, calibrationOrScale) {
|
|
4
5
|
if (typeof calibrationOrScale === 'number') {
|
|
@@ -8,11 +9,25 @@ export default function calibrateImageSpacing(imageId, renderingEngine, calibrat
|
|
|
8
9
|
};
|
|
9
10
|
}
|
|
10
11
|
calibratedPixelSpacingMetadataProvider.add(imageId, calibrationOrScale);
|
|
11
|
-
const viewports = renderingEngine.
|
|
12
|
+
const viewports = renderingEngine.getViewports().filter((viewport) => {
|
|
13
|
+
return (viewportSupportsStackCalibration(viewport) ||
|
|
14
|
+
viewportSupportsStackCompatibility(viewport));
|
|
15
|
+
});
|
|
12
16
|
viewports.forEach((viewport) => {
|
|
13
17
|
const imageIds = viewport.getImageIds();
|
|
14
18
|
if (imageIds.includes(imageId)) {
|
|
15
|
-
viewport
|
|
19
|
+
if (viewportSupportsStackCalibration(viewport)) {
|
|
20
|
+
viewport.calibrateSpacing(imageId);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const currentImageIdIndex = viewport.getCurrentImageIdIndex();
|
|
24
|
+
void Promise.resolve(viewport.setStack(imageIds, currentImageIdIndex))
|
|
25
|
+
.then(() => {
|
|
26
|
+
viewport.render();
|
|
27
|
+
})
|
|
28
|
+
.catch((error) => {
|
|
29
|
+
console.warn('calibrateImageSpacing: failed to refresh stack-compatible viewport', error);
|
|
30
|
+
});
|
|
16
31
|
}
|
|
17
32
|
});
|
|
18
33
|
}
|
|
@@ -8,7 +8,6 @@ function validateAnnotation(annotation) {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
class AnnotationToPointData {
|
|
11
|
-
static { this.TOOL_NAMES = {}; }
|
|
12
11
|
constructor() {
|
|
13
12
|
}
|
|
14
13
|
static convert(annotation, segment, metadataProvider) {
|
|
@@ -36,5 +35,6 @@ class AnnotationToPointData {
|
|
|
36
35
|
AnnotationToPointData.TOOL_NAMES[toolClass.toolName] = toolClass;
|
|
37
36
|
}
|
|
38
37
|
}
|
|
38
|
+
AnnotationToPointData.TOOL_NAMES = {};
|
|
39
39
|
AnnotationToPointData.register(RectangleROIStartEndThreshold);
|
|
40
40
|
export default AnnotationToPointData;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { utilities as csUtils } from '@cornerstonejs/core';
|
|
2
2
|
import { vec3 } from 'gl-matrix';
|
|
3
3
|
import { getBoundingBoxAroundShapeIJK } from './boundingBox';
|
|
4
|
+
import getViewportICamera from './getViewportICamera';
|
|
4
5
|
const { transformWorldToIndex } = csUtils;
|
|
5
6
|
function _getSphereBoundsInfo(circlePoints, imageData, directionVectors) {
|
|
6
7
|
const [bottom, top] = circlePoints;
|
|
@@ -32,7 +33,10 @@ function getSphereBoundsInfoFromViewport(circlePoints, imageData, viewport) {
|
|
|
32
33
|
if (!viewport) {
|
|
33
34
|
throw new Error('viewport is required in order to calculate the sphere bounds');
|
|
34
35
|
}
|
|
35
|
-
const camera = viewport
|
|
36
|
+
const camera = getViewportICamera(viewport);
|
|
37
|
+
if (!camera.viewUp || !camera.viewPlaneNormal) {
|
|
38
|
+
throw new Error('viewport view plane is required in order to calculate the sphere bounds');
|
|
39
|
+
}
|
|
36
40
|
const viewUp = vec3.fromValues(camera.viewUp[0], camera.viewUp[1], camera.viewUp[2]);
|
|
37
41
|
const viewPlaneNormal = vec3.fromValues(camera.viewPlaneNormal[0], camera.viewPlaneNormal[1], camera.viewPlaneNormal[2]);
|
|
38
42
|
const viewRight = vec3.create();
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type Types } from '@cornerstonejs/core';
|
|
2
|
+
type ViewportICamera = Pick<Types.ICamera, 'focalPoint' | 'position' | 'viewPlaneNormal' | 'viewUp'>;
|
|
3
|
+
export default function getViewportICamera(viewport: Types.IViewport, viewReference?: Types.ViewReference): Partial<ViewportICamera>;
|
|
4
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { utilities } from '@cornerstonejs/core';
|
|
2
|
+
export default function getViewportICamera(viewport, viewReference = viewport.getViewReference()) {
|
|
3
|
+
const genericViewport = viewport;
|
|
4
|
+
const camera = (genericViewport.getResolvedView?.()?.toICamera?.() ||
|
|
5
|
+
viewport.getCamera?.() ||
|
|
6
|
+
{});
|
|
7
|
+
const focalPoint = utilities.clonePoint3(viewReference?.cameraFocalPoint || camera.focalPoint);
|
|
8
|
+
const viewPlaneNormal = utilities.clonePoint3(viewReference?.viewPlaneNormal || camera.viewPlaneNormal);
|
|
9
|
+
const viewUp = utilities.clonePoint3(viewReference?.viewUp || camera.viewUp);
|
|
10
|
+
const position = utilities.clonePoint3(camera.position ||
|
|
11
|
+
(focalPoint &&
|
|
12
|
+
viewPlaneNormal && [
|
|
13
|
+
focalPoint[0] - viewPlaneNormal[0],
|
|
14
|
+
focalPoint[1] - viewPlaneNormal[1],
|
|
15
|
+
focalPoint[2] - viewPlaneNormal[2],
|
|
16
|
+
]));
|
|
17
|
+
return {
|
|
18
|
+
focalPoint,
|
|
19
|
+
position,
|
|
20
|
+
viewPlaneNormal,
|
|
21
|
+
viewUp,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getEnabledElements, utilities as csUtils } from '@cornerstonejs/core';
|
|
2
|
+
import getViewportICamera from './getViewportICamera';
|
|
2
3
|
const { isEqual } = csUtils;
|
|
3
4
|
export default function getViewportsForAnnotation(annotation) {
|
|
4
5
|
const { metadata } = annotation;
|
|
@@ -6,7 +7,10 @@ export default function getViewportsForAnnotation(annotation) {
|
|
|
6
7
|
.filter((enabledElement) => {
|
|
7
8
|
if (enabledElement.FrameOfReferenceUID === metadata.FrameOfReferenceUID) {
|
|
8
9
|
const viewport = enabledElement.viewport;
|
|
9
|
-
const { viewPlaneNormal, viewUp } = viewport
|
|
10
|
+
const { viewPlaneNormal, viewUp } = getViewportICamera(viewport);
|
|
11
|
+
if (!viewPlaneNormal) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
10
14
|
return (isEqual(viewPlaneNormal, metadata.viewPlaneNormal) &&
|
|
11
15
|
(!metadata.viewUp || isEqual(viewUp, metadata.viewUp)));
|
|
12
16
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
var _a;
|
|
1
2
|
import { utilities } from '@cornerstonejs/core';
|
|
2
3
|
import { Calculator, InstanceCalculator } from './Calculator';
|
|
3
4
|
const { PointsManager } = utilities;
|
|
@@ -204,20 +205,21 @@ function basicGetStatistics(state, unit) {
|
|
|
204
205
|
return named;
|
|
205
206
|
}
|
|
206
207
|
export class BasicStatsCalculator extends Calculator {
|
|
207
|
-
static { this.state = createBasicStatsState(true); }
|
|
208
208
|
static statsInit(options) {
|
|
209
209
|
if (!options.storePointData) {
|
|
210
210
|
this.state.pointsInShape = null;
|
|
211
211
|
}
|
|
212
212
|
this.state = createBasicStatsState(options.storePointData);
|
|
213
213
|
}
|
|
214
|
-
static { this.statsCallback = ({ value: newValue, pointLPS = null, pointIJK = null, }) => {
|
|
215
|
-
basicStatsCallback(this.state, newValue, pointLPS, pointIJK);
|
|
216
|
-
}; }
|
|
217
|
-
static { this.getStatistics = (options) => {
|
|
218
|
-
return basicGetStatistics(this.state, options?.unit);
|
|
219
|
-
}; }
|
|
220
214
|
}
|
|
215
|
+
_a = BasicStatsCalculator;
|
|
216
|
+
BasicStatsCalculator.state = createBasicStatsState(true);
|
|
217
|
+
BasicStatsCalculator.statsCallback = ({ value: newValue, pointLPS = null, pointIJK = null, }) => {
|
|
218
|
+
basicStatsCallback(_a.state, newValue, pointLPS, pointIJK);
|
|
219
|
+
};
|
|
220
|
+
BasicStatsCalculator.getStatistics = (options) => {
|
|
221
|
+
return basicGetStatistics(_a.state, options?.unit);
|
|
222
|
+
};
|
|
221
223
|
export class InstanceBasicStatsCalculator extends InstanceCalculator {
|
|
222
224
|
constructor(options) {
|
|
223
225
|
super(options);
|
|
@@ -2,6 +2,7 @@ import { utilities as csUtils } from '@cornerstonejs/core';
|
|
|
2
2
|
import { vec3 } from 'gl-matrix';
|
|
3
3
|
import { pointInSphere } from './math/sphere';
|
|
4
4
|
import { getBoundingBoxAroundShape } from './boundingBox';
|
|
5
|
+
import getViewportICamera from './getViewportICamera';
|
|
5
6
|
const { transformWorldToIndex } = csUtils;
|
|
6
7
|
export function pointInSurroundingSphereCallback(imageData, circlePoints, callback, viewport) {
|
|
7
8
|
const { boundsIJK, centerWorld, radiusWorld } = _getBounds(circlePoints, imageData, viewport);
|
|
@@ -51,7 +52,13 @@ function _getBounds(circlePoints, imageData, viewport) {
|
|
|
51
52
|
function _computeBoundsIJKWithCamera(imageData, viewport, circlePoints, centerWorld, radiusWorld) {
|
|
52
53
|
const [bottom, top] = circlePoints;
|
|
53
54
|
const dimensions = imageData.getDimensions();
|
|
54
|
-
const camera = viewport
|
|
55
|
+
const camera = getViewportICamera(viewport);
|
|
56
|
+
if (!camera.viewUp || !camera.viewPlaneNormal) {
|
|
57
|
+
return getBoundingBoxAroundShape([
|
|
58
|
+
transformWorldToIndex(imageData, top),
|
|
59
|
+
transformWorldToIndex(imageData, bottom),
|
|
60
|
+
], dimensions);
|
|
61
|
+
}
|
|
55
62
|
const viewUp = vec3.fromValues(camera.viewUp[0], camera.viewUp[1], camera.viewUp[2]);
|
|
56
63
|
const viewPlaneNormal = vec3.fromValues(camera.viewPlaneNormal[0], camera.viewPlaneNormal[1], camera.viewPlaneNormal[2]);
|
|
57
64
|
const viewRight = vec3.create();
|