From 5c17c262eaa5c1229033cfff4b3e7709e874611f Mon Sep 17 00:00:00 2001 From: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com> Date: Wed, 19 Nov 2025 17:55:53 -0500 Subject: [PATCH] fix(SegmentationStyle): Fix inactive contour visibility and styling. (#5563) * Opacity, fill and outline properties for active and inactive contours are now consistent with those for label map segmentations. The properties for inactive segmentations are applied to BOTH inactive contours and label maps. * Activate the selected segmentation for a type when the alpha, outline width, or fill/outline visibility is changed. --- bun.lock | 312 +++++++++--------- diff.txt | 118 ------- .../cornerstone-dicom-pmap/package.json | 4 +- extensions/cornerstone-dicom-seg/package.json | 4 +- extensions/cornerstone-dicom-sr/package.json | 6 +- .../cornerstone-dynamic-volume/package.json | 4 +- extensions/cornerstone/package.json | 14 +- extensions/cornerstone/src/commandsModule.ts | 43 ++- .../segmentationPanelCustomization.tsx | 71 +++- extensions/cornerstone/src/init.tsx | 10 +- .../src/panels/PanelSegmentation.tsx | 20 +- .../SegmentationService.test.ts | 6 +- .../SegmentationService.ts | 14 +- extensions/measurement-tracking/package.json | 4 +- extensions/usAnnotation/package.json | 4 +- modes/usAnnotation/package.json | 4 +- platform/app/package.json | 2 +- platform/core/package.json | 4 +- .../services/data/SegmentationService.md | 1 + .../SegmentationTable/SegmentationTable.tsx | 9 +- .../SegmentationTableConfig.tsx | 42 ++- .../contexts/SegmentationTableContext.tsx | 4 +- yarn.lock | 56 ++-- 23 files changed, 395 insertions(+), 361 deletions(-) delete mode 100644 diff.txt diff --git a/bun.lock b/bun.lock index b07357383..c64495e74 100644 --- a/bun.lock +++ b/bun.lock @@ -52,7 +52,7 @@ }, "addOns/externals/devDependencies": { "name": "@externals/devDependencies", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", "@kitware/vtk.js": "32.12.0", @@ -137,22 +137,22 @@ }, "addOns/externals/dicom-microscopy-viewer": { "name": "@externals/dicom-microscopy-viewer", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "dicom-microscopy-viewer": "0.48.6", }, }, "extensions/cornerstone": { "name": "@ohif/extension-cornerstone", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/adapters": "4.9.1", - "@cornerstonejs/ai": "4.9.1", - "@cornerstonejs/core": "4.9.1", - "@cornerstonejs/labelmap-interpolation": "4.9.1", - "@cornerstonejs/polymorphic-segmentation": "4.9.1", - "@cornerstonejs/tools": "4.9.1", + "@cornerstonejs/adapters": "4.11.2", + "@cornerstonejs/ai": "4.11.2", + "@cornerstonejs/core": "4.11.2", + "@cornerstonejs/labelmap-interpolation": "4.11.2", + "@cornerstonejs/polymorphic-segmentation": "4.11.2", + "@cornerstonejs/tools": "4.11.2", "@itk-wasm/morphological-contour-interpolation": "1.1.0", "@kitware/vtk.js": "32.12.0", "html2canvas": "1.4.1", @@ -169,9 +169,9 @@ "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjph": "2.4.7", - "@cornerstonejs/dicom-image-loader": "4.9.1", - "@ohif/core": "3.12.0-beta.84", - "@ohif/ui": "3.12.0-beta.84", + "@cornerstonejs/dicom-image-loader": "4.11.2", + "@ohif/core": "3.12.0-beta.86", + "@ohif/ui": "3.12.0-beta.86", "dcmjs": "0.43.1", "dicom-parser": "1.8.21", "hammerjs": "2.0.8", @@ -183,19 +183,19 @@ }, "extensions/cornerstone-dicom-pmap": { "name": "@ohif/extension-cornerstone-dicom-pmap", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/adapters": "4.9.1", - "@cornerstonejs/core": "4.9.1", + "@cornerstonejs/adapters": "4.11.2", + "@cornerstonejs/core": "4.11.2", "@kitware/vtk.js": "32.12.0", "react-color": "2.19.3", }, "peerDependencies": { - "@ohif/core": "3.12.0-beta.83", - "@ohif/extension-cornerstone": "3.12.0-beta.83", - "@ohif/extension-default": "3.12.0-beta.83", - "@ohif/i18n": "3.12.0-beta.83", + "@ohif/core": "3.12.0-beta.86", + "@ohif/extension-cornerstone": "3.12.0-beta.86", + "@ohif/extension-default": "3.12.0-beta.86", + "@ohif/i18n": "3.12.0-beta.86", "prop-types": "15.8.1", "react": "18.3.1", "react-dom": "18.3.1", @@ -206,16 +206,16 @@ }, "extensions/cornerstone-dicom-rt": { "name": "@ohif/extension-cornerstone-dicom-rt", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", "react-color": "2.19.3", }, "peerDependencies": { - "@ohif/core": "3.12.0-beta.83", - "@ohif/extension-cornerstone": "3.12.0-beta.83", - "@ohif/extension-default": "3.12.0-beta.83", - "@ohif/i18n": "3.12.0-beta.83", + "@ohif/core": "3.12.0-beta.86", + "@ohif/extension-cornerstone": "3.12.0-beta.86", + "@ohif/extension-default": "3.12.0-beta.86", + "@ohif/i18n": "3.12.0-beta.86", "prop-types": "15.8.1", "react": "18.3.1", "react-dom": "18.3.1", @@ -226,19 +226,19 @@ }, "extensions/cornerstone-dicom-seg": { "name": "@ohif/extension-cornerstone-dicom-seg", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/adapters": "4.9.1", - "@cornerstonejs/core": "4.9.1", + "@cornerstonejs/adapters": "4.11.2", + "@cornerstonejs/core": "4.11.2", "@kitware/vtk.js": "32.12.0", "react-color": "2.19.3", }, "peerDependencies": { - "@ohif/core": "3.12.0-beta.83", - "@ohif/extension-cornerstone": "3.12.0-beta.83", - "@ohif/extension-default": "3.12.0-beta.83", - "@ohif/i18n": "3.12.0-beta.83", + "@ohif/core": "3.12.0-beta.86", + "@ohif/extension-cornerstone": "3.12.0-beta.86", + "@ohif/extension-default": "3.12.0-beta.86", + "@ohif/i18n": "3.12.0-beta.86", "prop-types": "15.8.1", "react": "18.3.1", "react-dom": "18.3.1", @@ -249,19 +249,19 @@ }, "extensions/cornerstone-dicom-sr": { "name": "@ohif/extension-cornerstone-dicom-sr", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/adapters": "4.9.1", - "@cornerstonejs/core": "4.9.1", - "@cornerstonejs/tools": "4.9.1", + "@cornerstonejs/adapters": "4.11.2", + "@cornerstonejs/core": "4.11.2", + "@cornerstonejs/tools": "4.11.2", "classnames": "2.5.1", }, "peerDependencies": { - "@ohif/core": "3.12.0-beta.84", - "@ohif/extension-cornerstone": "3.12.0-beta.84", - "@ohif/extension-measurement-tracking": "3.12.0-beta.84", - "@ohif/ui": "3.12.0-beta.84", + "@ohif/core": "3.12.0-beta.86", + "@ohif/extension-cornerstone": "3.12.0-beta.86", + "@ohif/extension-measurement-tracking": "3.12.0-beta.86", + "@ohif/ui": "3.12.0-beta.86", "dcmjs": "0.43.1", "dicom-parser": "1.8.21", "hammerjs": "2.0.8", @@ -271,19 +271,19 @@ }, "extensions/cornerstone-dynamic-volume": { "name": "@ohif/extension-cornerstone-dynamic-volume", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/core": "4.9.1", - "@cornerstonejs/tools": "4.9.1", + "@cornerstonejs/core": "4.11.2", + "@cornerstonejs/tools": "4.11.2", "classnames": "2.5.1", }, "peerDependencies": { - "@ohif/core": "3.12.0-beta.83", - "@ohif/extension-cornerstone": "3.12.0-beta.83", - "@ohif/extension-default": "3.12.0-beta.83", - "@ohif/i18n": "3.12.0-beta.83", - "@ohif/ui": "3.12.0-beta.83", + "@ohif/core": "3.12.0-beta.86", + "@ohif/extension-cornerstone": "3.12.0-beta.86", + "@ohif/extension-default": "3.12.0-beta.86", + "@ohif/i18n": "3.12.0-beta.86", + "@ohif/ui": "3.12.0-beta.86", "dcmjs": "0.43.1", "dicom-parser": "1.8.21", "hammerjs": "2.0.8", @@ -293,7 +293,7 @@ }, "extensions/default": { "name": "@ohif/extension-default", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", "@cornerstonejs/calculate-suv": "1.1.0", @@ -301,8 +301,8 @@ "lodash.uniqby": "4.7.0", }, "peerDependencies": { - "@ohif/core": "3.12.0-beta.84", - "@ohif/i18n": "3.12.0-beta.84", + "@ohif/core": "3.12.0-beta.86", + "@ohif/i18n": "3.12.0-beta.86", "dcmjs": "0.43.1", "dicomweb-client": "0.10.4", "prop-types": "15.8.1", @@ -316,7 +316,7 @@ }, "extensions/dicom-microscopy": { "name": "@ohif/extension-dicom-microscopy", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", "@cornerstonejs/codec-charls": "1.2.3", @@ -327,10 +327,10 @@ "mathjs": "12.4.3", }, "peerDependencies": { - "@ohif/core": "3.12.0-beta.83", - "@ohif/extension-default": "3.12.0-beta.83", - "@ohif/i18n": "3.12.0-beta.83", - "@ohif/ui": "3.12.0-beta.83", + "@ohif/core": "3.12.0-beta.86", + "@ohif/extension-default": "3.12.0-beta.86", + "@ohif/i18n": "3.12.0-beta.86", + "@ohif/ui": "3.12.0-beta.86", "prop-types": "15.8.1", "react": "18.3.1", "react-dom": "18.3.1", @@ -341,14 +341,14 @@ }, "extensions/dicom-pdf": { "name": "@ohif/extension-dicom-pdf", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", "classnames": "2.5.1", }, "peerDependencies": { - "@ohif/core": "3.12.0-beta.83", - "@ohif/ui": "3.12.0-beta.83", + "@ohif/core": "3.12.0-beta.86", + "@ohif/ui": "3.12.0-beta.86", "dcmjs": "0.43.1", "dicom-parser": "1.8.21", "hammerjs": "2.0.8", @@ -358,14 +358,14 @@ }, "extensions/dicom-video": { "name": "@ohif/extension-dicom-video", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", "classnames": "2.5.1", }, "peerDependencies": { - "@ohif/core": "3.12.0-beta.83", - "@ohif/ui": "3.12.0-beta.83", + "@ohif/core": "3.12.0-beta.86", + "@ohif/ui": "3.12.0-beta.86", "dcmjs": "0.43.1", "dicom-parser": "1.8.21", "hammerjs": "2.0.8", @@ -375,20 +375,20 @@ }, "extensions/measurement-tracking": { "name": "@ohif/extension-measurement-tracking", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", - "@ohif/ui": "3.12.0-beta.84", + "@ohif/ui": "3.12.0-beta.86", "@xstate/react": "3.2.2", "xstate": "4.38.3", }, "peerDependencies": { - "@cornerstonejs/core": "4.9.1", - "@cornerstonejs/tools": "4.9.1", - "@ohif/core": "3.12.0-beta.84", - "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.84", - "@ohif/extension-default": "3.12.0-beta.84", - "@ohif/ui": "3.12.0-beta.84", + "@cornerstonejs/core": "4.11.2", + "@cornerstonejs/tools": "4.11.2", + "@ohif/core": "3.12.0-beta.86", + "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.86", + "@ohif/extension-default": "3.12.0-beta.86", + "@ohif/ui": "3.12.0-beta.86", "classnames": "2.5.1", "dcmjs": "0.43.1", "lodash.debounce": "4.0.8", @@ -401,14 +401,14 @@ }, "extensions/test-extension": { "name": "@ohif/extension-test", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", "classnames": "2.5.1", }, "peerDependencies": { - "@ohif/core": "3.12.0-beta.83", - "@ohif/ui": "3.12.0-beta.83", + "@ohif/core": "3.12.0-beta.86", + "@ohif/ui": "3.12.0-beta.86", "dcmjs": "0.43.1", "dicom-parser": "1.8.21", "hammerjs": "2.0.8", @@ -418,7 +418,7 @@ }, "extensions/tmtv": { "name": "@ohif/extension-tmtv", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", "classnames": "2.5.1", @@ -435,16 +435,16 @@ }, "extensions/usAnnotation": { "name": "@ohif/extension-ultrasound-pleura-bline", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/core": "4.9.1", - "@cornerstonejs/tools": "4.9.1", - "@ohif/core": "3.12.0-beta.83", - "@ohif/extension-cornerstone": "3.12.0-beta.83", - "@ohif/extension-default": "3.12.0-beta.83", - "@ohif/i18n": "3.12.0-beta.83", - "@ohif/ui-next": "3.12.0-beta.83", + "@cornerstonejs/core": "4.11.2", + "@cornerstonejs/tools": "4.11.2", + "@ohif/core": "3.12.0-beta.86", + "@ohif/extension-cornerstone": "3.12.0-beta.86", + "@ohif/extension-default": "3.12.0-beta.86", + "@ohif/i18n": "3.12.0-beta.86", + "@ohif/ui-next": "3.12.0-beta.86", }, "devDependencies": { "@babel/core": "7.28.0", @@ -487,7 +487,7 @@ }, "modes/basic": { "name": "@ohif/mode-basic", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", }, @@ -508,7 +508,7 @@ }, "modes/basic-dev-mode": { "name": "@ohif/mode-basic-dev-mode", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", "i18next": "17.3.1", @@ -518,17 +518,17 @@ "webpack-merge": "5.10.0", }, "peerDependencies": { - "@ohif/core": "3.12.0-beta.83", - "@ohif/extension-cornerstone": "3.12.0-beta.83", - "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.83", - "@ohif/extension-default": "3.12.0-beta.83", - "@ohif/extension-dicom-pdf": "3.12.0-beta.83", - "@ohif/extension-dicom-video": "3.12.0-beta.83", + "@ohif/core": "3.12.0-beta.86", + "@ohif/extension-cornerstone": "3.12.0-beta.86", + "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.86", + "@ohif/extension-default": "3.12.0-beta.86", + "@ohif/extension-dicom-pdf": "3.12.0-beta.86", + "@ohif/extension-dicom-video": "3.12.0-beta.86", }, }, "modes/basic-test-mode": { "name": "@ohif/mode-test", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", "i18next": "17.3.1", @@ -538,19 +538,19 @@ "webpack-merge": "5.10.0", }, "peerDependencies": { - "@ohif/core": "3.12.0-beta.83", - "@ohif/extension-cornerstone": "3.12.0-beta.83", - "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.83", - "@ohif/extension-default": "3.12.0-beta.83", - "@ohif/extension-dicom-pdf": "3.12.0-beta.83", - "@ohif/extension-dicom-video": "3.12.0-beta.83", - "@ohif/extension-measurement-tracking": "3.12.0-beta.83", - "@ohif/extension-test": "3.12.0-beta.83", + "@ohif/core": "3.12.0-beta.86", + "@ohif/extension-cornerstone": "3.12.0-beta.86", + "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.86", + "@ohif/extension-default": "3.12.0-beta.86", + "@ohif/extension-dicom-pdf": "3.12.0-beta.86", + "@ohif/extension-dicom-video": "3.12.0-beta.86", + "@ohif/extension-measurement-tracking": "3.12.0-beta.86", + "@ohif/extension-test": "3.12.0-beta.86", }, }, "modes/longitudinal": { "name": "@ohif/mode-longitudinal", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", "i18next": "17.3.1", @@ -560,32 +560,32 @@ "webpack-merge": "5.10.0", }, "peerDependencies": { - "@ohif/core": "3.12.0-beta.83", - "@ohif/extension-cornerstone": "3.12.0-beta.83", - "@ohif/extension-cornerstone-dicom-rt": "3.12.0-beta.83", - "@ohif/extension-cornerstone-dicom-seg": "3.12.0-beta.83", - "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.83", - "@ohif/extension-default": "3.12.0-beta.83", - "@ohif/extension-dicom-pdf": "3.12.0-beta.83", - "@ohif/extension-dicom-video": "3.12.0-beta.83", - "@ohif/extension-measurement-tracking": "3.12.0-beta.83", + "@ohif/core": "3.12.0-beta.86", + "@ohif/extension-cornerstone": "3.12.0-beta.86", + "@ohif/extension-cornerstone-dicom-rt": "3.12.0-beta.86", + "@ohif/extension-cornerstone-dicom-seg": "3.12.0-beta.86", + "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.86", + "@ohif/extension-default": "3.12.0-beta.86", + "@ohif/extension-dicom-pdf": "3.12.0-beta.86", + "@ohif/extension-dicom-video": "3.12.0-beta.86", + "@ohif/extension-measurement-tracking": "3.12.0-beta.86", }, }, "modes/microscopy": { "name": "@ohif/mode-microscopy", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", "i18next": "17.3.1", }, "peerDependencies": { - "@ohif/core": "3.12.0-beta.83", - "@ohif/extension-dicom-microscopy": "3.12.0-beta.83", + "@ohif/core": "3.12.0-beta.86", + "@ohif/extension-dicom-microscopy": "3.12.0-beta.86", }, }, "modes/preclinical-4d": { "name": "@ohif/mode-preclinical-4d", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", }, @@ -604,7 +604,7 @@ }, "modes/segmentation": { "name": "@ohif/mode-segmentation", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", "i18next": "17.3.1", @@ -648,7 +648,7 @@ }, "modes/tmtv": { "name": "@ohif/mode-tmtv", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", "i18next": "17.3.1", @@ -669,14 +669,14 @@ }, "modes/usAnnotation": { "name": "@ohif/mode-ultrasound-pleura-bline", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/core": "4.9.1", - "@cornerstonejs/tools": "4.9.1", - "@ohif/core": "3.12.0-beta.83", - "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.83", - "@ohif/extension-ultrasound-pleura-bline": "3.12.0-beta.83", + "@cornerstonejs/core": "4.11.2", + "@cornerstonejs/tools": "4.11.2", + "@ohif/core": "3.12.0-beta.86", + "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.86", + "@ohif/extension-ultrasound-pleura-bline": "3.12.0-beta.86", "i18next": "17.3.1", }, "devDependencies": { @@ -708,34 +708,34 @@ }, "platform/app": { "name": "@ohif/app", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", "@cornerstonejs/codec-charls": "1.2.3", "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjph": "2.4.7", - "@cornerstonejs/dicom-image-loader": "4.9.1", + "@cornerstonejs/dicom-image-loader": "4.11.2", "@emotion/serialize": "1.3.3", - "@ohif/core": "3.12.0-beta.83", - "@ohif/extension-cornerstone": "3.12.0-beta.83", - "@ohif/extension-cornerstone-dicom-rt": "3.12.0-beta.83", - "@ohif/extension-cornerstone-dicom-seg": "3.12.0-beta.83", - "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.83", - "@ohif/extension-default": "3.12.0-beta.83", - "@ohif/extension-dicom-microscopy": "3.12.0-beta.83", - "@ohif/extension-dicom-pdf": "3.12.0-beta.83", - "@ohif/extension-dicom-video": "3.12.0-beta.83", - "@ohif/extension-test": "3.12.0-beta.83", - "@ohif/extension-ultrasound-pleura-bline": "3.12.0-beta.83", - "@ohif/i18n": "3.12.0-beta.83", - "@ohif/mode-basic-dev-mode": "3.12.0-beta.83", - "@ohif/mode-longitudinal": "3.12.0-beta.83", - "@ohif/mode-microscopy": "3.12.0-beta.83", - "@ohif/mode-test": "3.12.0-beta.83", - "@ohif/mode-ultrasound-pleura-bline": "3.12.0-beta.83", - "@ohif/ui": "3.12.0-beta.83", - "@ohif/ui-next": "3.12.0-beta.83", + "@ohif/core": "3.12.0-beta.86", + "@ohif/extension-cornerstone": "3.12.0-beta.86", + "@ohif/extension-cornerstone-dicom-rt": "3.12.0-beta.86", + "@ohif/extension-cornerstone-dicom-seg": "3.12.0-beta.86", + "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.86", + "@ohif/extension-default": "3.12.0-beta.86", + "@ohif/extension-dicom-microscopy": "3.12.0-beta.86", + "@ohif/extension-dicom-pdf": "3.12.0-beta.86", + "@ohif/extension-dicom-video": "3.12.0-beta.86", + "@ohif/extension-test": "3.12.0-beta.86", + "@ohif/extension-ultrasound-pleura-bline": "3.12.0-beta.86", + "@ohif/i18n": "3.12.0-beta.86", + "@ohif/mode-basic-dev-mode": "3.12.0-beta.86", + "@ohif/mode-longitudinal": "3.12.0-beta.86", + "@ohif/mode-microscopy": "3.12.0-beta.86", + "@ohif/mode-test": "3.12.0-beta.86", + "@ohif/mode-ultrasound-pleura-bline": "3.12.0-beta.86", + "@ohif/ui": "3.12.0-beta.86", + "@ohif/ui-next": "3.12.0-beta.86", "@svgr/webpack": "8.1.0", "@types/react": "18.3.23", "classnames": "2.5.1", @@ -787,7 +787,7 @@ }, "platform/cli": { "name": "@ohif/cli", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "bin": { "ohif-cli": "src/index.js", }, @@ -811,7 +811,7 @@ }, "platform/core": { "name": "@ohif/core", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", "dcmjs": "0.43.1", @@ -836,16 +836,16 @@ "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjph": "2.4.7", - "@cornerstonejs/core": "4.9.1", - "@cornerstonejs/dicom-image-loader": "4.9.1", - "@ohif/ui": "3.12.0-beta.84", + "@cornerstonejs/core": "4.11.2", + "@cornerstonejs/dicom-image-loader": "4.11.2", + "@ohif/ui": "3.12.0-beta.86", "cornerstone-math": "0.1.9", "dicom-parser": "1.8.21", }, }, "platform/i18n": { "name": "@ohif/i18n", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@babel/runtime": "7.28.2", "i18next-locize-backend": "2.2.2", @@ -870,7 +870,7 @@ }, "platform/ui": { "name": "@ohif/ui", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@testing-library/react": "13.4.0", "browser-detect": "0.2.28", @@ -921,7 +921,7 @@ }, "platform/ui-next": { "name": "@ohif/ui-next", - "version": "3.12.0-beta.84", + "version": "3.12.0-beta.86", "dependencies": { "@radix-ui/react-accordion": "1.2.11", "@radix-ui/react-checkbox": "1.3.2", @@ -1228,9 +1228,9 @@ "@bcoe/v8-coverage": ["@bcoe/v8-coverage@0.2.3", "", {}, "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="], - "@cornerstonejs/adapters": ["@cornerstonejs/adapters@4.9.1", "", { "dependencies": { "@babel/runtime-corejs2": "7.26.10", "buffer": "6.0.3", "dcmjs": "0.43.1", "gl-matrix": "3.4.3", "ndarray": "1.0.19" }, "peerDependencies": { "@cornerstonejs/core": "4.9.1", "@cornerstonejs/tools": "4.9.1" } }, "sha512-snDETfKHF5SuTetzsWSpS2XaIjpqQxKux+6rT5EYxwxD+xtoF8gZ8s9vumunHb9Y2+1Kqw8kXSb8tX7tYnAKzQ=="], + "@cornerstonejs/adapters": ["@cornerstonejs/adapters@4.11.2", "", { "dependencies": { "@babel/runtime-corejs2": "7.26.10", "buffer": "6.0.3", "dcmjs": "0.43.1", "gl-matrix": "3.4.3", "ndarray": "1.0.19" }, "peerDependencies": { "@cornerstonejs/core": "4.11.2", "@cornerstonejs/tools": "4.11.2" } }, "sha512-yYZd4W+BnM9So0SsPYYjYN+cho5FBlXIOg0o3JX+gQGoguSk9UedRfd5xa7f7TYoN4ect7RdU4ytwajdabRY5Q=="], - "@cornerstonejs/ai": ["@cornerstonejs/ai@4.9.1", "", { "dependencies": { "@babel/runtime-corejs2": "7.26.10", "buffer": "6.0.3", "dcmjs": "0.43.1", "gl-matrix": "3.4.3", "lodash.clonedeep": "4.5.0", "ndarray": "1.0.19", "onnxruntime-common": "1.17.1", "onnxruntime-web": "1.17.1" }, "peerDependencies": { "@cornerstonejs/core": "4.9.1", "@cornerstonejs/tools": "4.9.1" } }, "sha512-JZ4oU0jgCUTGI9X5N3ZEls59cjpCFkD9bBAwNsNG7a34kJPHwV/LxkBRoZdNibJ6WuzQnx1QKZex6xtXeN7XlA=="], + "@cornerstonejs/ai": ["@cornerstonejs/ai@4.11.2", "", { "dependencies": { "@babel/runtime-corejs2": "7.26.10", "buffer": "6.0.3", "dcmjs": "0.43.1", "gl-matrix": "3.4.3", "lodash.clonedeep": "4.5.0", "ndarray": "1.0.19", "onnxruntime-common": "1.17.1", "onnxruntime-web": "1.17.1" }, "peerDependencies": { "@cornerstonejs/core": "4.11.2", "@cornerstonejs/tools": "4.11.2" } }, "sha512-aUfcRidr8/48Szw9MPK4MFXZPhoPlABxOXltx6pZHFe7da3KE1WYoSLD/Dw0T72AtqV2w8blXQuNpplTL4ErAg=="], "@cornerstonejs/calculate-suv": ["@cornerstonejs/calculate-suv@1.1.0", "", {}, "sha512-Q9XraiDJif9aMFArD2iEuDO/HXbcRVCqB7KfaHgDrdTTjgDFovS91Psbdim7crypRSvE6dh/+HKeFNHdvNkA6w=="], @@ -1242,15 +1242,15 @@ "@cornerstonejs/codec-openjph": ["@cornerstonejs/codec-openjph@2.4.7", "", {}, "sha512-qvP4q4JDib7mi9r7LqKOwqz7YZ8gjtDX4ZCezeYf8+eb7MBXCz5uXAMeVF3yz9Axw4XiIMdB/pqXkm8tqCl13w=="], - "@cornerstonejs/core": ["@cornerstonejs/core@4.9.1", "", { "dependencies": { "@kitware/vtk.js": "32.12.1", "comlink": "4.4.2", "gl-matrix": "3.4.3", "loglevel": "1.9.2" } }, "sha512-2LiknffKmUWOtdsCU4HFWDvK8IcdxIxyWJttUVCUm6V+VBPCiNBItUrwdBnR6x7DCKoQUnKWRKj+QH6q9/QiMA=="], + "@cornerstonejs/core": ["@cornerstonejs/core@4.11.2", "", { "dependencies": { "@kitware/vtk.js": "32.12.1", "comlink": "4.4.2", "gl-matrix": "3.4.3", "loglevel": "1.9.2" } }, "sha512-8Lq3hq+k31C4KbU0sGfUEP/ORn/6nqVYioXvQG4iU+SpLbbQVyhUgEqtQPIKoZVsGaV2mX4HOU3fWXAmMfP4fQ=="], - "@cornerstonejs/dicom-image-loader": ["@cornerstonejs/dicom-image-loader@4.9.1", "", { "dependencies": { "@cornerstonejs/codec-charls": "1.2.3", "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjph": "2.4.7", "comlink": "4.4.2", "dicom-parser": "1.8.21", "jpeg-lossless-decoder-js": "2.1.2", "pako": "2.1.0", "uuid": "9.0.1" }, "peerDependencies": { "@cornerstonejs/core": "4.9.1" } }, "sha512-g+y5bdYYflTwvDJjm2lMx9maN6vdLRkgh4WcuCnBP7bctrHw78f2q4OltaVQRl7Ko5SJU37DF7UNyVdE+Zz3Mg=="], + "@cornerstonejs/dicom-image-loader": ["@cornerstonejs/dicom-image-loader@4.11.2", "", { "dependencies": { "@cornerstonejs/codec-charls": "1.2.3", "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjph": "2.4.7", "comlink": "4.4.2", "dicom-parser": "1.8.21", "jpeg-lossless-decoder-js": "2.1.2", "pako": "2.1.0", "uuid": "9.0.1" }, "peerDependencies": { "@cornerstonejs/core": "4.11.2" } }, "sha512-xIWbAOrkVBgpBpcqlyYIL2fiAZ8KRF453Ao6svDRixoL7Fl2gvhnpJGbG3wWCYhHaPXbYpbhmfzIovT9qZ7ACg=="], - "@cornerstonejs/labelmap-interpolation": ["@cornerstonejs/labelmap-interpolation@4.9.1", "", { "dependencies": { "@itk-wasm/morphological-contour-interpolation": "1.1.0", "itk-wasm": "1.0.0-b.165" }, "peerDependencies": { "@cornerstonejs/core": "4.9.1", "@cornerstonejs/tools": "4.9.1", "@kitware/vtk.js": "32.12.1" } }, "sha512-lak2Nj4X7xO9goHwBjEEhMtk0GDyQKI9jdhS2W9N73vlmfM0twRaie27hNCEZ2K9vBxKgVNknHRtGlajNxOuKQ=="], + "@cornerstonejs/labelmap-interpolation": ["@cornerstonejs/labelmap-interpolation@4.11.2", "", { "dependencies": { "@itk-wasm/morphological-contour-interpolation": "1.1.0", "itk-wasm": "1.0.0-b.165" }, "peerDependencies": { "@cornerstonejs/core": "4.11.2", "@cornerstonejs/tools": "4.11.2", "@kitware/vtk.js": "32.12.1" } }, "sha512-gS0Gt07U9hDzjoD75I3fKcXRM47sEWsAI706L23/3Q0nN3DGz5NDDySIDo8E+IfZDdSJeX2yBO38RqszVlTkcA=="], - "@cornerstonejs/polymorphic-segmentation": ["@cornerstonejs/polymorphic-segmentation@4.9.1", "", { "dependencies": { "@icr/polyseg-wasm": "0.4.0" }, "peerDependencies": { "@cornerstonejs/core": "4.9.1", "@cornerstonejs/tools": "4.9.1", "@kitware/vtk.js": "32.12.1" } }, "sha512-FU8krVwwBcDUIBIIesXpDR9TzVZ5UIhNzgdAsuATV3KUQ6VCbR6JWSfbt9ueklcVTmMHWplcSifP684TIhyhQQ=="], + "@cornerstonejs/polymorphic-segmentation": ["@cornerstonejs/polymorphic-segmentation@4.11.2", "", { "dependencies": { "@icr/polyseg-wasm": "0.4.0" }, "peerDependencies": { "@cornerstonejs/core": "4.11.2", "@cornerstonejs/tools": "4.11.2", "@kitware/vtk.js": "32.12.1" } }, "sha512-cW1kVQOiwzWnsHdQOi6wi/k7ji3+qC1sqWb7WgFqf7uTuBbab4Oh0KO6ODcg3G0SOWhzQCPT+GcZf7tsgQh2Tw=="], - "@cornerstonejs/tools": ["@cornerstonejs/tools@4.9.1", "", { "dependencies": { "@types/offscreencanvas": "2019.7.3", "comlink": "4.4.2", "lodash.get": "4.4.2" }, "peerDependencies": { "@cornerstonejs/core": "4.9.1", "@kitware/vtk.js": "32.12.1", "@types/d3-array": "3.2.1", "@types/d3-interpolate": "3.0.4", "d3-array": "3.2.4", "d3-interpolate": "3.0.1", "gl-matrix": "3.4.3" } }, "sha512-xyq+I9UX7hpX+qrSvEAqxoUVqPrGvZLrUrlb2snUTFq4ZsI5AIVmqRTYGW0JJO5E3lB/vWGooavk/JhI9TNtkA=="], + "@cornerstonejs/tools": ["@cornerstonejs/tools@4.11.2", "", { "dependencies": { "@types/offscreencanvas": "2019.7.3", "comlink": "4.4.2", "lodash.get": "4.4.2" }, "peerDependencies": { "@cornerstonejs/core": "4.11.2", "@kitware/vtk.js": "32.12.1", "@types/d3-array": "3.2.1", "@types/d3-interpolate": "3.0.4", "d3-array": "3.2.4", "d3-interpolate": "3.0.1", "gl-matrix": "3.4.3" } }, "sha512-7opk5t0l3HDSEEa2/PfoiuWBtK6wMdHUjCzy1LY9dVqTpkoqE7YRhNsCuByvd4xgzfp/gijaqlcxS1gyZz0hlw=="], "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="], diff --git a/diff.txt b/diff.txt deleted file mode 100644 index 88c9a6493..000000000 --- a/diff.txt +++ /dev/null @@ -1,118 +0,0 @@ -diff --git a/extensions/cornerstone/src/components/ViewportOrientationMenu/ViewportOrientationMenu.tsx b/extensions/cornerstone/src/components/ViewportOrientationMenu/ViewportOrientationMenu.tsx -index 6c1e4f8f6..56dac15b5 100644 ---- a/extensions/cornerstone/src/components/ViewportOrientationMenu/ViewportOrientationMenu.tsx -+++ b/extensions/cornerstone/src/components/ViewportOrientationMenu/ViewportOrientationMenu.tsx -@@ -156,65 +156,65 @@ function ViewportOrientationMenu({ - > - - - - - {/* Divider */} --
-+
- - - -diff --git a/platform/ui-next/src/components/Icons/Sources/Checked.tsx b/platform/ui-next/src/components/Icons/Sources/Checked.tsx -index 83c8fc57e..c88b75e0d 100644 ---- a/platform/ui-next/src/components/Icons/Sources/Checked.tsx -+++ b/platform/ui-next/src/components/Icons/Sources/Checked.tsx -@@ -4,14 +4,14 @@ import type { IconProps } from '../types'; - export const Checked = (props: IconProps) => ( - - { + const { segmentationService } = servicesManager.services; + segmentationService.setStyle({ type }, { renderFillInactive: value }); + }, + /** * Sets whether to render outline for a segmentation type * @param props.type - The type of segmentation @@ -1771,13 +1781,36 @@ function commandsModule({ }, /** - * Sets the fill alpha for inactive segmentations + * Sets whether to render outline for inactive segmentations of a segmentation type + * @param props.type - The type of segmentation + * @param props.value - Whether to render outline for inactive segmentations + */ + setRenderOutlineInactiveCommand: ({ type, value }) => { + const { segmentationService } = servicesManager.services; + segmentationService.setStyle({ type }, { renderOutlineInactive: value }); + }, + + /** + * Sets the fill alpha for inactive segmentations. + * If no type is provided, the fill alpha for all types will be set. * @param props.type - The type of segmentation * @param props.value - The alpha value to set */ setFillAlphaInactiveCommand: ({ type, value }) => { const { segmentationService } = servicesManager.services; - segmentationService.setStyle({ type }, { fillAlphaInactive: value }); + + if (type) { + segmentationService.setStyle({ type }, { fillAlphaInactive: value }); + } else { + segmentationService.setStyle( + { type: SegmentationRepresentations.Labelmap }, + { fillAlphaInactive: value } + ); + segmentationService.setStyle( + { type: SegmentationRepresentations.Contour }, + { fillAlphaInactive: value } + ); + } }, editSegmentLabel: async ({ segmentationId, segmentIndex }) => { @@ -2708,9 +2741,15 @@ function commandsModule({ setRenderFill: { commandFn: actions.setRenderFillCommand, }, + setRenderFillInactive: { + commandFn: actions.setRenderFillInactiveCommand, + }, setRenderOutline: { commandFn: actions.setRenderOutlineCommand, }, + setRenderOutlineInactive: { + commandFn: actions.setRenderOutlineInactiveCommand, + }, setFillAlphaInactive: { commandFn: actions.setFillAlphaInactiveCommand, }, diff --git a/extensions/cornerstone/src/customizations/segmentationPanelCustomization.tsx b/extensions/cornerstone/src/customizations/segmentationPanelCustomization.tsx index ffad85152..124b507fa 100644 --- a/extensions/cornerstone/src/customizations/segmentationPanelCustomization.tsx +++ b/extensions/cornerstone/src/customizations/segmentationPanelCustomization.tsx @@ -3,9 +3,28 @@ import { CustomSegmentStatisticsHeader } from './CustomSegmentStatisticsHeader'; import SegmentationToolConfig from '../components/SegmentationToolConfig'; import React from 'react'; import { SegmentationRepresentations } from '@cornerstonejs/tools/enums'; -import * as cornerstoneTools from '@cornerstonejs/tools'; export default function getSegmentationPanelCustomization({ commandsManager, servicesManager }) { + const { segmentationService } = servicesManager.services; + + let contourRenderFillChangedGlobally = false; + + // Listen to when the global CONTOUR type renderFill style property is changed. + const { unsubscribe } = segmentationService.subscribe( + segmentationService.EVENTS.SEGMENTATION_STYLE_MODIFIED, + ({ specifier, style }) => { + if ( + specifier.type === SegmentationRepresentations.Contour && + specifier.segmentationId == null && + specifier.viewportId == null && + style.renderFill != null + ) { + unsubscribe(); + contourRenderFillChangedGlobally = true; + } + } + ); + return { 'panelSegmentation.customDropdownMenuContent': CustomDropdownMenuContent, 'panelSegmentation.customSegmentStatisticsHeader': CustomSegmentStatisticsHeader, @@ -22,11 +41,51 @@ export default function getSegmentationPanelCustomization({ commandsManager, ser const segmentationId = await commandsManager.run('createContourForViewport', { viewportId, }); - cornerstoneTools.segmentation.config.style.setStyle( - { segmentationId, type: SegmentationRepresentations.Contour }, - { - fillAlpha: 0.5, - renderFill: true, + // Override the default (i.e. hydrated RTSTRUCT) style for contours if the global CONTOUR type + // renderFill style property has not been changed. + if (!contourRenderFillChangedGlobally) { + segmentationService.setStyle( + { segmentationId, type: SegmentationRepresentations.Contour }, + { + renderFill: true, + renderFillInactive: true, + }, + // Do not merge so that these created contours inherit other type-specific style properties like the fill alpha. + // Merging would otherwise permanently inherit the fill alpha and any inheritance from the type level would be lost. + false + ); + } + + // If the global CONTOUR type renderFill style property is already set, do not subscribe to the SEGMENTATION_STYLE_MODIFIED event. + if (contourRenderFillChangedGlobally) { + return; + } + + // Subscribe to the SEGMENTATION_STYLE_MODIFIED event to listen for changes to the CONTOUR type renderFill style property. + const { unsubscribe } = segmentationService.subscribe( + segmentationService.EVENTS.SEGMENTATION_STYLE_MODIFIED, + ({ specifier, style }) => { + if ( + specifier.type === SegmentationRepresentations.Contour && + specifier.segmentationId == null && + specifier.viewportId == null && + style.renderFill != null + ) { + // We are here because the renderFill style property is globally being changed for ALL contours. + // When this occurs, the desire is for ALL contours to inherit the property. To make this happen, + // we have to clear the style property that was set for this specific segmentation + // when it was created above. + // We can now also unsubscribe because this change only needs to be made when the global CONTOUR type + // renderFill style property is first changed. + + contourRenderFillChangedGlobally = true; + unsubscribe(); + segmentationService.setStyle( + { segmentationId, type: SegmentationRepresentations.Contour }, + {}, + false + ); + } } ); } diff --git a/extensions/cornerstone/src/init.tsx b/extensions/cornerstone/src/init.tsx index 6a141361b..c8fc0ffad 100644 --- a/extensions/cornerstone/src/init.tsx +++ b/extensions/cornerstone/src/init.tsx @@ -137,10 +137,18 @@ export default async function init({ getSegmentationPresentationId ); - cornerstoneTools.segmentation.config.style.setStyle( + segmentationService.setStyle( { type: SegmentationRepresentations.Contour }, { + // Declare these alpha values at the Contour type level so that they can be set/changed/inherited for all contour segmentations. + fillAlpha: 0.5, + fillAlphaInactive: 0.4, + + // In general do not fill contours so that hydrated RTSTRUCTs are not filled in when active or inactive by default. + // However, hydrated RTSTRUCTs are filled in when active or inactive if the user chooses to fill ALL contours. + // Those Contours created in OHIF (i.e. using the Segmentation Panel) will override both fill properties upon creation. renderFill: false, + renderFillInactive: false, } ); diff --git a/extensions/cornerstone/src/panels/PanelSegmentation.tsx b/extensions/cornerstone/src/panels/PanelSegmentation.tsx index 8eb8fea50..6120c7576 100644 --- a/extensions/cornerstone/src/panels/PanelSegmentation.tsx +++ b/extensions/cornerstone/src/panels/PanelSegmentation.tsx @@ -161,18 +161,36 @@ export default function PanelSegmentation({ commandsManager.run('deleteSegmentation', { segmentationId }); }, setFillAlpha: ({ type }, value) => { + commandsManager.run('activateSelectedSegmentationOfType', { + segmentationRepresentationType: type, + }); commandsManager.run('setFillAlpha', { type, value }); }, setOutlineWidth: ({ type }, value) => { + commandsManager.run('activateSelectedSegmentationOfType', { + segmentationRepresentationType: type, + }); commandsManager.run('setOutlineWidth', { type, value }); }, setRenderFill: ({ type }, value) => { + commandsManager.run('activateSelectedSegmentationOfType', { + segmentationRepresentationType: type, + }); commandsManager.run('setRenderFill', { type, value }); }, + setRenderFillInactive: ({ type }, value) => { + commandsManager.run('setRenderFillInactive', { type, value }); + }, setRenderOutline: ({ type }, value) => { + commandsManager.run('activateSelectedSegmentationOfType', { + segmentationRepresentationType: type, + }); commandsManager.run('setRenderOutline', { type, value }); }, - setFillAlphaInactive: ({ type }, value) => { + setRenderOutlineInactive: ({ type }, value) => { + commandsManager.run('setRenderOutlineInactive', { type, value }); + }, + setFillAlphaInactive: ({ type }: { type?: string }, value) => { commandsManager.run('setFillAlphaInactive', { type, value }); }, getRenderInactiveSegmentations: () => { diff --git a/extensions/cornerstone/src/services/SegmentationService/SegmentationService.test.ts b/extensions/cornerstone/src/services/SegmentationService/SegmentationService.test.ts index e5abe17e5..d6c670925 100644 --- a/extensions/cornerstone/src/services/SegmentationService/SegmentationService.test.ts +++ b/extensions/cornerstone/src/services/SegmentationService/SegmentationService.test.ts @@ -1954,7 +1954,8 @@ describe('SegmentationService', () => { type, segmentIndex, }, - style + style, + true ); }); }); @@ -2829,7 +2830,8 @@ describe('SegmentationService', () => { segmentIndex, type: csToolsEnums.SegmentationRepresentations.Labelmap, }, - {} + {}, + false ); expect(window.requestAnimationFrame).not.toHaveBeenCalledTimes(3); diff --git a/extensions/cornerstone/src/services/SegmentationService/SegmentationService.ts b/extensions/cornerstone/src/services/SegmentationService/SegmentationService.ts index 36209f84e..015edacea 100644 --- a/extensions/cornerstone/src/services/SegmentationService/SegmentationService.ts +++ b/extensions/cornerstone/src/services/SegmentationService/SegmentationService.ts @@ -84,6 +84,7 @@ const EVENTS = { // fired when a contour annotation cut merge process is completed SEGMENTATION_ANNOTATION_CUT_MERGE_PROCESS_COMPLETED: 'event::annotation_cut_merge_process_completed', + SEGMENTATION_STYLE_MODIFIED: 'event::segmentation_style_modified', }; const VALUE_TYPES = {}; @@ -835,9 +836,15 @@ class SegmentationService extends PubSubService { segmentationId?: string; segmentIndex?: number; }, - style: cstTypes.LabelmapStyle | cstTypes.ContourStyle | cstTypes.SurfaceStyle + style: cstTypes.LabelmapStyle | cstTypes.ContourStyle | cstTypes.SurfaceStyle, + merge: boolean = true ) => { - cstSegmentation.config.style.setStyle(specifier, style); + cstSegmentation.config.style.setStyle(specifier, style, merge); + this._broadcastEvent(EVENTS.SEGMENTATION_STYLE_MODIFIED, { + specifier, + style, + merge, + }); }; public resetToGlobalStyle = () => { @@ -1737,7 +1744,8 @@ class SegmentationService extends PubSubService { segmentIndex, type: LABELMAP, }, - {} + {}, + false ); } }; diff --git a/extensions/measurement-tracking/package.json b/extensions/measurement-tracking/package.json index 7cb338ac4..4fd95e583 100644 --- a/extensions/measurement-tracking/package.json +++ b/extensions/measurement-tracking/package.json @@ -32,8 +32,8 @@ "start": "yarn run dev" }, "peerDependencies": { - "@cornerstonejs/core": "4.9.1", - "@cornerstonejs/tools": "4.9.1", + "@cornerstonejs/core": "4.11.2", + "@cornerstonejs/tools": "4.11.2", "@ohif/core": "3.12.0-beta.86", "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.86", "@ohif/extension-default": "3.12.0-beta.86", diff --git a/extensions/usAnnotation/package.json b/extensions/usAnnotation/package.json index 3bd117b63..3602e061d 100644 --- a/extensions/usAnnotation/package.json +++ b/extensions/usAnnotation/package.json @@ -42,8 +42,8 @@ }, "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/core": "4.9.1", - "@cornerstonejs/tools": "4.9.1", + "@cornerstonejs/core": "4.11.2", + "@cornerstonejs/tools": "4.11.2", "@ohif/core": "3.12.0-beta.86", "@ohif/extension-cornerstone": "3.12.0-beta.86", "@ohif/extension-default": "3.12.0-beta.86", diff --git a/modes/usAnnotation/package.json b/modes/usAnnotation/package.json index 7f72bb2ee..6baa42d56 100644 --- a/modes/usAnnotation/package.json +++ b/modes/usAnnotation/package.json @@ -34,8 +34,8 @@ }, "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/core": "4.9.1", - "@cornerstonejs/tools": "4.9.1", + "@cornerstonejs/core": "4.11.2", + "@cornerstonejs/tools": "4.11.2", "@ohif/core": "3.12.0-beta.86", "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.86", "@ohif/extension-ultrasound-pleura-bline": "3.12.0-beta.86", diff --git a/platform/app/package.json b/platform/app/package.json index b9f02ac11..fcaae3aeb 100644 --- a/platform/app/package.json +++ b/platform/app/package.json @@ -53,7 +53,7 @@ "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjph": "2.4.7", - "@cornerstonejs/dicom-image-loader": "4.9.1", + "@cornerstonejs/dicom-image-loader": "4.11.2", "@emotion/serialize": "1.3.3", "@ohif/core": "3.12.0-beta.86", "@ohif/extension-cornerstone": "3.12.0-beta.86", diff --git a/platform/core/package.json b/platform/core/package.json index e82cf4ba7..9f88acb1f 100644 --- a/platform/core/package.json +++ b/platform/core/package.json @@ -37,8 +37,8 @@ "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjph": "2.4.7", - "@cornerstonejs/core": "4.9.1", - "@cornerstonejs/dicom-image-loader": "4.9.1", + "@cornerstonejs/core": "4.11.2", + "@cornerstonejs/dicom-image-loader": "4.11.2", "@ohif/ui": "3.12.0-beta.86", "cornerstone-math": "0.1.9", "dicom-parser": "1.8.21" diff --git a/platform/docs/docs/platform/services/data/SegmentationService.md b/platform/docs/docs/platform/services/data/SegmentationService.md index fbe89025c..4ed7ffc5e 100644 --- a/platform/docs/docs/platform/services/data/SegmentationService.md +++ b/platform/docs/docs/platform/services/data/SegmentationService.md @@ -18,6 +18,7 @@ SEGMENTATION_REMOVED // When segmentation is remo SEGMENT_LOADING_COMPLETE // When segment group adds pixel data to volume SEGMENTATION_LOADING_COMPLETE // When full segmentation volume is filled SEGMENTATION_ANNOTATION_CUT_MERGE_PROCESS_COMPLETED // When a segmentation's annotation cut merge process is completed. +SEGMENTATION_STYLE_MODIFIED // When a segmentation style is modified. ``` ## Core APIs diff --git a/platform/ui-next/src/components/SegmentationTable/SegmentationTable.tsx b/platform/ui-next/src/components/SegmentationTable/SegmentationTable.tsx index b517d583b..111023118 100644 --- a/platform/ui-next/src/components/SegmentationTable/SegmentationTable.tsx +++ b/platform/ui-next/src/components/SegmentationTable/SegmentationTable.tsx @@ -40,6 +40,7 @@ export const SegmentationTableRoot = (props: SegmentationTableProps) => { disabled = false, children, showConfig: externalShowConfig, + selectedSegmentationIdForType, ...contextProps } = props; @@ -55,6 +56,11 @@ export const SegmentationTableRoot = (props: SegmentationTableProps) => { const activeRepresentation = props.activeRepresentation || activeSegmentationInfo?.representation; const activeSegmentation = props.activeSegmentation || activeSegmentationInfo?.segmentation; + const selectedSegmentationForTypeInfo = data.find( + info => info.segmentation?.segmentationId === selectedSegmentationIdForType + ); + const selectedSegmentationForTypeRepresentation = selectedSegmentationForTypeInfo?.representation; + // Extract style properties or use defaults const { fillAlpha = props.fillAlpha || 0.5, @@ -62,7 +68,7 @@ export const SegmentationTableRoot = (props: SegmentationTableProps) => { outlineWidth = props.outlineWidth || 1, renderFill = props.renderFill !== undefined ? props.renderFill : true, renderOutline = props.renderOutline !== undefined ? props.renderOutline : true, - } = activeRepresentation?.styles ?? {}; + } = selectedSegmentationForTypeRepresentation?.styles ?? {}; // Check if SegmentationTableConfig is present in children const hasConfigComponent = Children.toArray(children).some( @@ -102,6 +108,7 @@ export const SegmentationTableRoot = (props: SegmentationTableProps) => { activeSegmentationId, activeSegmentation, activeRepresentation, + selectedSegmentationIdForType, ...contextProps, setShowConfig: toggleShowConfig, }} diff --git a/platform/ui-next/src/components/SegmentationTable/SegmentationTableConfig.tsx b/platform/ui-next/src/components/SegmentationTable/SegmentationTableConfig.tsx index 60935c133..354ad7567 100644 --- a/platform/ui-next/src/components/SegmentationTable/SegmentationTableConfig.tsx +++ b/platform/ui-next/src/components/SegmentationTable/SegmentationTableConfig.tsx @@ -14,8 +14,9 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> = renderFill, renderOutline, setRenderFill, + setRenderFillInactive, setRenderOutline, - activeRepresentation, + setRenderOutlineInactive, fillAlpha, fillAlphaInactive, outlineWidth, @@ -24,6 +25,7 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> = setOutlineWidth, renderInactiveSegmentations, toggleRenderInactiveSegmentations, + segmentationRepresentationType, data, } = useSegmentationTableContext('SegmentationTableConfig'); @@ -48,14 +50,20 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> = } onValueChange={value => { if (value === 'fill-and-outline') { - setRenderFill({ type: activeRepresentation.type }, true); - setRenderOutline({ type: activeRepresentation.type }, true); + setRenderFill({ type: segmentationRepresentationType }, true); + setRenderOutline({ type: segmentationRepresentationType }, true); + setRenderFillInactive({ type: segmentationRepresentationType }, true); + setRenderOutlineInactive({ type: segmentationRepresentationType }, true); } else if (value === 'outline') { - setRenderFill({ type: activeRepresentation.type }, false); - setRenderOutline({ type: activeRepresentation.type }, true); + setRenderFill({ type: segmentationRepresentationType }, false); + setRenderOutline({ type: segmentationRepresentationType }, true); + setRenderFillInactive({ type: segmentationRepresentationType }, false); + setRenderOutlineInactive({ type: segmentationRepresentationType }, true); } else { - setRenderFill({ type: activeRepresentation.type }, true); - setRenderOutline({ type: activeRepresentation.type }, false); + setRenderFill({ type: segmentationRepresentationType }, true); + setRenderOutline({ type: segmentationRepresentationType }, false); + setRenderFillInactive({ type: segmentationRepresentationType }, true); + setRenderOutlineInactive({ type: segmentationRepresentationType }, false); } }} > @@ -81,7 +89,9 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> = setFillAlpha({ type: activeRepresentation.type }, value)} + onValueChange={([value]) => + setFillAlpha({ type: segmentationRepresentationType }, value) + } max={1} min={0} step={0.1} @@ -90,7 +100,7 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> = className="mx-1 w-10 flex-none" value={fillAlpha} onChange={e => - setFillAlpha({ type: activeRepresentation.type }, Number(e.target.value)) + setFillAlpha({ type: segmentationRepresentationType }, Number(e.target.value)) } />
@@ -101,7 +111,9 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> = setOutlineWidth({ type: activeRepresentation.type }, value)} + onValueChange={([value]) => + setOutlineWidth({ type: segmentationRepresentationType }, value) + } max={10} min={0} step={0.1} @@ -110,7 +122,7 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> = - setOutlineWidth({ type: activeRepresentation.type }, Number(e.target.value)) + setOutlineWidth({ type: segmentationRepresentationType }, Number(e.target.value)) } className="mx-1 w-10 flex-none text-center" /> @@ -136,9 +148,7 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> = - setFillAlphaInactive({ type: activeRepresentation.type }, value) - } + onValueChange={([value]) => setFillAlphaInactive({}, value)} max={1} min={0} step={0.1} @@ -146,9 +156,7 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> = - setFillAlphaInactive({ type: activeRepresentation.type }, Number(e.target.value)) - } + onChange={e => setFillAlphaInactive({}, Number(e.target.value))} />
)} diff --git a/platform/ui-next/src/components/SegmentationTable/contexts/SegmentationTableContext.tsx b/platform/ui-next/src/components/SegmentationTable/contexts/SegmentationTableContext.tsx index f1f66f794..648b93e91 100644 --- a/platform/ui-next/src/components/SegmentationTable/contexts/SegmentationTableContext.tsx +++ b/platform/ui-next/src/components/SegmentationTable/contexts/SegmentationTableContext.tsx @@ -75,10 +75,12 @@ export interface SegmentationTableContextType { // Function handlers setShowConfig?: (show: boolean) => void; setRenderFill?: ({ type }: { type: string }, value: boolean) => void; + setRenderFillInactive?: ({ type }: { type: string }, value: boolean) => void; setRenderOutline?: ({ type }: { type: string }, value: boolean) => void; + setRenderOutlineInactive?: ({ type }: { type: string }, value: boolean) => void; setOutlineWidth?: ({ type }: { type: string }, value: number) => void; setFillAlpha?: ({ type }: { type: string }, value: number) => void; - setFillAlphaInactive?: ({ type }: { type: string }, value: number) => void; + setFillAlphaInactive?: ({ type }: { type?: string }, value: number) => void; toggleRenderInactiveSegmentations?: () => void; onSegmentationAdd?: ({ segmentationId, diff --git a/yarn.lock b/yarn.lock index aed2d4ab5..b6a98e9cf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1280,10 +1280,10 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@cornerstonejs/adapters@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@cornerstonejs/adapters/-/adapters-4.9.1.tgz#d439ab907e9cc99cbdf06ac02a33347a075e8fd1" - integrity sha512-snDETfKHF5SuTetzsWSpS2XaIjpqQxKux+6rT5EYxwxD+xtoF8gZ8s9vumunHb9Y2+1Kqw8kXSb8tX7tYnAKzQ== +"@cornerstonejs/adapters@4.11.2": + version "4.11.2" + resolved "https://registry.yarnpkg.com/@cornerstonejs/adapters/-/adapters-4.11.2.tgz#f33a4321f53722c30fcf8e08bf76e894ae5c5e5e" + integrity sha512-yYZd4W+BnM9So0SsPYYjYN+cho5FBlXIOg0o3JX+gQGoguSk9UedRfd5xa7f7TYoN4ect7RdU4ytwajdabRY5Q== dependencies: "@babel/runtime-corejs2" "7.26.10" buffer "6.0.3" @@ -1291,10 +1291,10 @@ gl-matrix "3.4.3" ndarray "1.0.19" -"@cornerstonejs/ai@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@cornerstonejs/ai/-/ai-4.9.1.tgz#162d46429a9d637f28ba79d06e081ba75715e5e2" - integrity sha512-JZ4oU0jgCUTGI9X5N3ZEls59cjpCFkD9bBAwNsNG7a34kJPHwV/LxkBRoZdNibJ6WuzQnx1QKZex6xtXeN7XlA== +"@cornerstonejs/ai@4.11.2": + version "4.11.2" + resolved "https://registry.yarnpkg.com/@cornerstonejs/ai/-/ai-4.11.2.tgz#e55085c6daa5a804ae64123b385c2aa565425761" + integrity sha512-aUfcRidr8/48Szw9MPK4MFXZPhoPlABxOXltx6pZHFe7da3KE1WYoSLD/Dw0T72AtqV2w8blXQuNpplTL4ErAg== dependencies: "@babel/runtime-corejs2" "7.26.10" buffer "6.0.3" @@ -1330,20 +1330,20 @@ resolved "https://registry.yarnpkg.com/@cornerstonejs/codec-openjph/-/codec-openjph-2.4.7.tgz#784394d05d8cf735640e9c3baa206535ee8e0376" integrity sha512-qvP4q4JDib7mi9r7LqKOwqz7YZ8gjtDX4ZCezeYf8+eb7MBXCz5uXAMeVF3yz9Axw4XiIMdB/pqXkm8tqCl13w== -"@cornerstonejs/core@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@cornerstonejs/core/-/core-4.9.1.tgz#613e1e11938289928b94f98c4e18d09d4aa9741c" - integrity sha512-2LiknffKmUWOtdsCU4HFWDvK8IcdxIxyWJttUVCUm6V+VBPCiNBItUrwdBnR6x7DCKoQUnKWRKj+QH6q9/QiMA== +"@cornerstonejs/core@4.11.2": + version "4.11.2" + resolved "https://registry.yarnpkg.com/@cornerstonejs/core/-/core-4.11.2.tgz#9ba3559d1cddc3fe9f50ec6f6ebc6f803622e39a" + integrity sha512-8Lq3hq+k31C4KbU0sGfUEP/ORn/6nqVYioXvQG4iU+SpLbbQVyhUgEqtQPIKoZVsGaV2mX4HOU3fWXAmMfP4fQ== dependencies: "@kitware/vtk.js" "32.12.1" comlink "4.4.2" gl-matrix "3.4.3" loglevel "1.9.2" -"@cornerstonejs/dicom-image-loader@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@cornerstonejs/dicom-image-loader/-/dicom-image-loader-4.9.1.tgz#351b0e6788017817a07ec8f1c1a3e58cb0825a69" - integrity sha512-g+y5bdYYflTwvDJjm2lMx9maN6vdLRkgh4WcuCnBP7bctrHw78f2q4OltaVQRl7Ko5SJU37DF7UNyVdE+Zz3Mg== +"@cornerstonejs/dicom-image-loader@4.11.2": + version "4.11.2" + resolved "https://registry.yarnpkg.com/@cornerstonejs/dicom-image-loader/-/dicom-image-loader-4.11.2.tgz#2cb74fa20dc349317a037a96011d7f5ed44facee" + integrity sha512-xIWbAOrkVBgpBpcqlyYIL2fiAZ8KRF453Ao6svDRixoL7Fl2gvhnpJGbG3wWCYhHaPXbYpbhmfzIovT9qZ7ACg== dependencies: "@cornerstonejs/codec-charls" "1.2.3" "@cornerstonejs/codec-libjpeg-turbo-8bit" "1.2.2" @@ -1355,25 +1355,25 @@ pako "2.1.0" uuid "9.0.1" -"@cornerstonejs/labelmap-interpolation@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@cornerstonejs/labelmap-interpolation/-/labelmap-interpolation-4.9.1.tgz#321f9ac2a58ade2fee7c1ed78cf9b491a5d2d94f" - integrity sha512-lak2Nj4X7xO9goHwBjEEhMtk0GDyQKI9jdhS2W9N73vlmfM0twRaie27hNCEZ2K9vBxKgVNknHRtGlajNxOuKQ== +"@cornerstonejs/labelmap-interpolation@4.11.2": + version "4.11.2" + resolved "https://registry.yarnpkg.com/@cornerstonejs/labelmap-interpolation/-/labelmap-interpolation-4.11.2.tgz#4868455c0c5084e0f54d1d0292fa9cde681ff243" + integrity sha512-gS0Gt07U9hDzjoD75I3fKcXRM47sEWsAI706L23/3Q0nN3DGz5NDDySIDo8E+IfZDdSJeX2yBO38RqszVlTkcA== dependencies: "@itk-wasm/morphological-contour-interpolation" "1.1.0" itk-wasm "1.0.0-b.165" -"@cornerstonejs/polymorphic-segmentation@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@cornerstonejs/polymorphic-segmentation/-/polymorphic-segmentation-4.9.1.tgz#d34011f640295bcee7748374bb834d5f4dfd7c6a" - integrity sha512-FU8krVwwBcDUIBIIesXpDR9TzVZ5UIhNzgdAsuATV3KUQ6VCbR6JWSfbt9ueklcVTmMHWplcSifP684TIhyhQQ== +"@cornerstonejs/polymorphic-segmentation@4.11.2": + version "4.11.2" + resolved "https://registry.yarnpkg.com/@cornerstonejs/polymorphic-segmentation/-/polymorphic-segmentation-4.11.2.tgz#228bd205d0aef2d5cf8d13d4b8811839ccf54fc2" + integrity sha512-cW1kVQOiwzWnsHdQOi6wi/k7ji3+qC1sqWb7WgFqf7uTuBbab4Oh0KO6ODcg3G0SOWhzQCPT+GcZf7tsgQh2Tw== dependencies: "@icr/polyseg-wasm" "0.4.0" -"@cornerstonejs/tools@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@cornerstonejs/tools/-/tools-4.9.1.tgz#f3bfaf51b636d7a1d5904986834963628bb0615e" - integrity sha512-xyq+I9UX7hpX+qrSvEAqxoUVqPrGvZLrUrlb2snUTFq4ZsI5AIVmqRTYGW0JJO5E3lB/vWGooavk/JhI9TNtkA== +"@cornerstonejs/tools@4.11.2": + version "4.11.2" + resolved "https://registry.yarnpkg.com/@cornerstonejs/tools/-/tools-4.11.2.tgz#185cb573895c0a604868cb42777f22f3b8158841" + integrity sha512-7opk5t0l3HDSEEa2/PfoiuWBtK6wMdHUjCzy1LY9dVqTpkoqE7YRhNsCuByvd4xgzfp/gijaqlcxS1gyZz0hlw== dependencies: "@types/offscreencanvas" "2019.7.3" comlink "4.4.2"