From 1fe8ae0dad26a840ba86a5df2102babd588ddd78 Mon Sep 17 00:00:00 2001 From: Adithyan Dinesh Date: Thu, 26 Feb 2026 14:25:56 +0530 Subject: [PATCH 1/2] Create and add PHI Bounding Box Tool as a new button section and enable 'simplified' measurement tracking mode --- .../cornerstone/src/initCornerstoneTools.js | 3 +++ .../cornerstone/src/initMeasurementService.ts | 9 +++++++++ .../cornerstone/src/tools/PHIBoundingBoxTool.ts | 15 +++++++++++++++ .../constants/supportedTools.js | 1 + .../measurementServiceMappingsFactory.ts | 16 ++++++++++++++++ extensions/measurement-tracking/src/index.tsx | 12 +++++++++++- modes/basic/src/index.tsx | 2 ++ modes/basic/src/initToolGroups.ts | 2 ++ modes/basic/src/toolbarButtons.ts | 11 +++++++++++ modes/segmentation/src/index.tsx | 2 ++ modes/segmentation/src/initToolGroups.ts | 1 + modes/segmentation/src/toolbarButtons.ts | 11 +++++++++++ platform/app/public/config/gradient.js | 2 +- .../app/public/config/gradient_production.js | 2 +- 14 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 extensions/cornerstone/src/tools/PHIBoundingBoxTool.ts diff --git a/extensions/cornerstone/src/initCornerstoneTools.js b/extensions/cornerstone/src/initCornerstoneTools.js index 788622fa2eb..7982847b8a2 100644 --- a/extensions/cornerstone/src/initCornerstoneTools.js +++ b/extensions/cornerstone/src/initCornerstoneTools.js @@ -52,6 +52,7 @@ import * as polySeg from '@cornerstonejs/polymorphic-segmentation'; import CalibrationLineTool from './tools/CalibrationLineTool'; import ImageOverlayViewerTool from './tools/ImageOverlayViewerTool'; import SmartStackScrollTool from './tools/SmartStackScrollTool'; +import PHIBoundingBoxTool from './tools/PHIBoundingBoxTool'; export default function initCornerstoneTools(configuration = {}) { CrosshairsTool.isAnnotation = false; @@ -119,6 +120,7 @@ export default function initCornerstoneTools(configuration = {}) { addTool(SplineContourSegmentationTool); addTool(LabelMapEditWithContourTool); addTool(SmartStackScrollTool); + addTool(PHIBoundingBoxTool); // Modify annotation tools to use dashed lines on SR const annotationStyle = { textBoxFontSize: '15px', @@ -183,6 +185,7 @@ const toolNames = { SplineContourSegmentation: SplineContourSegmentationTool.toolName, LabelMapEditWithContourTool: LabelMapEditWithContourTool.toolName, SmartStackScroll: SmartStackScrollTool.toolName, + PHIBoundingBox: PHIBoundingBoxTool.toolName, }; export { toolNames }; diff --git a/extensions/cornerstone/src/initMeasurementService.ts b/extensions/cornerstone/src/initMeasurementService.ts index 9decf4cd433..c98ec24d779 100644 --- a/extensions/cornerstone/src/initMeasurementService.ts +++ b/extensions/cornerstone/src/initMeasurementService.ts @@ -33,6 +33,7 @@ const initMeasurementService = ( Angle, CobbAngle, RectangleROI, + PHIBoundingBox, PlanarFreehandROI, SplineROI, LivewireContour, @@ -128,6 +129,14 @@ const initMeasurementService = ( RectangleROI.toMeasurement ); + measurementService.addMapping( + csTools3DVer1MeasurementSource, + 'PHIBoundingBox', + PHIBoundingBox.matchingCriteria, + PHIBoundingBox.toAnnotation, + PHIBoundingBox.toMeasurement + ); + measurementService.addMapping( csTools3DVer1MeasurementSource, 'PlanarFreehandROI', diff --git a/extensions/cornerstone/src/tools/PHIBoundingBoxTool.ts b/extensions/cornerstone/src/tools/PHIBoundingBoxTool.ts new file mode 100644 index 00000000000..e8f2ea4b8b1 --- /dev/null +++ b/extensions/cornerstone/src/tools/PHIBoundingBoxTool.ts @@ -0,0 +1,15 @@ +import { RectangleROITool } from '@cornerstonejs/tools'; + +class PHIBoundingBoxTool extends RectangleROITool { + constructor( + toolProps = {}, + defaultToolProps = { + configuration: { getTextLines: () => ['PHI Bounding Box'] }, + } + ) { + super(toolProps, defaultToolProps); + } +} + +PHIBoundingBoxTool.toolName = 'PHIBoundingBox'; +export default PHIBoundingBoxTool; diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/constants/supportedTools.js b/extensions/cornerstone/src/utils/measurementServiceMappings/constants/supportedTools.js index 99713c3a466..4ba7d43f607 100644 --- a/extensions/cornerstone/src/utils/measurementServiceMappings/constants/supportedTools.js +++ b/extensions/cornerstone/src/utils/measurementServiceMappings/constants/supportedTools.js @@ -8,6 +8,7 @@ const supportedTools = [ 'CobbAngle', 'Probe', 'RectangleROI', + 'PHIBoundingBox', 'PlanarFreehandROI', 'SplineROI', 'LivewireContour', diff --git a/extensions/cornerstone/src/utils/measurementServiceMappings/measurementServiceMappingsFactory.ts b/extensions/cornerstone/src/utils/measurementServiceMappings/measurementServiceMappingsFactory.ts index eab15b4fef2..ecbf59084ca 100644 --- a/extensions/cornerstone/src/utils/measurementServiceMappings/measurementServiceMappingsFactory.ts +++ b/extensions/cornerstone/src/utils/measurementServiceMappings/measurementServiceMappingsFactory.ts @@ -166,6 +166,22 @@ const measurementServiceMappingsFactory = ( }, ], }, + PHIBoundingBox: { + toAnnotation: RectangleROI.toAnnotation, + toMeasurement: csToolsAnnotation => + RectangleROI.toMeasurement( + csToolsAnnotation, + displaySetService, + cornerstoneViewportService, + _getValueTypeFromToolType, + customizationService + ), + matchingCriteria: [ + { + valueType: MeasurementService.VALUE_TYPES.POLYLINE, + }, + ], + }, PlanarFreehandROI: { toAnnotation: PlanarFreehandROI.toAnnotation, toMeasurement: csToolsAnnotation => diff --git a/extensions/measurement-tracking/src/index.tsx b/extensions/measurement-tracking/src/index.tsx index cc669e6956a..3718ef034d9 100644 --- a/extensions/measurement-tracking/src/index.tsx +++ b/extensions/measurement-tracking/src/index.tsx @@ -1,4 +1,4 @@ -import getContextModule from './getContextModule'; +import getContextModule, { useTrackedMeasurements } from './getContextModule'; import getPanelModule from './getPanelModule'; import getViewportModule from './getViewportModule'; import { id } from './id.js'; @@ -51,6 +51,16 @@ const measurementTrackingExtension = { }); }, getCustomizationModule, + getUtilityModule() { + return [ + { + name: 'measurement-tracking', + exports: { + useTrackedMeasurements, + }, + }, + ]; + }, }; export default measurementTrackingExtension; diff --git a/modes/basic/src/index.tsx b/modes/basic/src/index.tsx index 9a0abbafb7f..3775781f69f 100644 --- a/modes/basic/src/index.tsx +++ b/modes/basic/src/index.tsx @@ -275,6 +275,8 @@ export const toolbarSections = { 'SegmentLabelTool', 'OPFSTool', ], + + PHIBoundingBox: ['PHIBoundingBox'], }; export const basicLayout = { diff --git a/modes/basic/src/initToolGroups.ts b/modes/basic/src/initToolGroups.ts index fe23b3dc8da..0810acd8a16 100644 --- a/modes/basic/src/initToolGroups.ts +++ b/modes/basic/src/initToolGroups.ts @@ -70,6 +70,7 @@ function initDefaultToolGroup(extensionManager, toolGroupService, commandsManage { toolName: toolNames.EllipticalROI }, { toolName: toolNames.CircleROI }, { toolName: toolNames.RectangleROI }, + { toolName: toolNames.PHIBoundingBox }, { toolName: toolNames.SmartStackScroll, bindings: [ @@ -231,6 +232,7 @@ function initMPRToolGroup(extensionManager, toolGroupService, commandsManager) { { toolName: toolNames.EllipticalROI }, { toolName: toolNames.CircleROI }, { toolName: toolNames.RectangleROI }, + { toolName: toolNames.PHIBoundingBox }, { toolName: toolNames.StackScroll }, { toolName: toolNames.Angle }, { toolName: toolNames.CobbAngle }, diff --git a/modes/basic/src/toolbarButtons.ts b/modes/basic/src/toolbarButtons.ts index b501dba77dc..58866189a37 100644 --- a/modes/basic/src/toolbarButtons.ts +++ b/modes/basic/src/toolbarButtons.ts @@ -518,6 +518,17 @@ const toolbarButtons: Button[] = [ evaluate: 'evaluate.cornerstoneTool', }, }, + { + id: 'PHIBoundingBox', + uiType: 'ohif.toolButton', + props: { + icon: 'tool-rectangle', + label: i18n.t('Buttons:PHIBoundingBox'), + tooltip: i18n.t('Buttons:PHI BoundingBox'), + commands: setToolActiveToolbar, + evaluate: 'evaluate.cornerstoneTool', + }, + }, { id: 'CircleROI', uiType: 'ohif.toolButton', diff --git a/modes/segmentation/src/index.tsx b/modes/segmentation/src/index.tsx index 99002c580e8..71023fefc2b 100644 --- a/modes/segmentation/src/index.tsx +++ b/modes/segmentation/src/index.tsx @@ -147,6 +147,8 @@ function modeFactory({ modeConfiguration }) { toolbarService.updateSection('BrushTools', ['Brush', 'Eraser', 'Threshold']); + toolbarService.updateSection('PHIBoundingBox', ['PHIBoundingBox']); + // Making the 'cornerstone.panelTool' the default/first right panel will automaically // handle the evaluate functions for segmentation panel tools through the toolbox components. // But since we changed the order, we need to call this here to handle the evaluate functions. diff --git a/modes/segmentation/src/initToolGroups.ts b/modes/segmentation/src/initToolGroups.ts index 9a225da8e48..3f3572f43c5 100644 --- a/modes/segmentation/src/initToolGroups.ts +++ b/modes/segmentation/src/initToolGroups.ts @@ -171,6 +171,7 @@ function createTools({ utilityModule, commandsManager }) { }, }, }, + { toolName: toolNames.PHIBoundingBox }, ], disabled: [{ toolName: toolNames.ReferenceLines }, { toolName: toolNames.AdvancedMagnify }], }; diff --git a/modes/segmentation/src/toolbarButtons.ts b/modes/segmentation/src/toolbarButtons.ts index dd6d8cb581f..ab9bce57c9b 100644 --- a/modes/segmentation/src/toolbarButtons.ts +++ b/modes/segmentation/src/toolbarButtons.ts @@ -1207,6 +1207,17 @@ export const toolbarButtons: Button[] = [ commands: 'showOPFSManagementTool', }, }, + { + id: 'PHIBoundingBox', + uiType: 'ohif.toolButton', + props: { + icon: 'tool-rectangle', + label: i18n.t('Buttons:PHIBoundingBox'), + tooltip: i18n.t('Buttons:PHI BoundingBox'), + commands: setToolActiveToolbar, + evaluate: 'evaluate.cornerstoneTool', + }, + }, ]; export default toolbarButtons; diff --git a/platform/app/public/config/gradient.js b/platform/app/public/config/gradient.js index 3b61345025c..36cde21b46f 100644 --- a/platform/app/public/config/gradient.js +++ b/platform/app/public/config/gradient.js @@ -10,7 +10,7 @@ window.config = { showStudyList: true, // some windows systems have issues with more than 3 web workers maxNumberOfWebWorkers: 3, - + measurementTrackingMode: 'simplified', // below flag is for performance reasons, but it might not work for all servers omitQuotationForMultipartRequest: true, showWarningMessageForCrossOrigin: true, diff --git a/platform/app/public/config/gradient_production.js b/platform/app/public/config/gradient_production.js index bdb1aef67b0..24dc67be98a 100644 --- a/platform/app/public/config/gradient_production.js +++ b/platform/app/public/config/gradient_production.js @@ -10,7 +10,7 @@ window.config = { showStudyList: true, // some windows systems have issues with more than 3 web workers maxNumberOfWebWorkers: 3, - + measurementTrackingMode: 'simplified', // below flag is for performance reasons, but it might not work for all servers omitQuotationForMultipartRequest: true, showWarningMessageForCrossOrigin: true, From 0238938b38e872c402bc79b1fc417ba6007158fb Mon Sep 17 00:00:00 2001 From: Adithyan Dinesh Date: Wed, 4 Mar 2026 18:49:41 +0530 Subject: [PATCH 2/2] Resolved PR review comments --- extensions/cornerstone/src/tools/PHIBoundingBoxTool.ts | 3 ++- extensions/cornerstone/src/tools/SmartStackScrollTool.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/extensions/cornerstone/src/tools/PHIBoundingBoxTool.ts b/extensions/cornerstone/src/tools/PHIBoundingBoxTool.ts index e8f2ea4b8b1..09c58c5f803 100644 --- a/extensions/cornerstone/src/tools/PHIBoundingBoxTool.ts +++ b/extensions/cornerstone/src/tools/PHIBoundingBoxTool.ts @@ -1,6 +1,8 @@ import { RectangleROITool } from '@cornerstonejs/tools'; class PHIBoundingBoxTool extends RectangleROITool { + static toolName = 'PHIBoundingBox'; + constructor( toolProps = {}, defaultToolProps = { @@ -11,5 +13,4 @@ class PHIBoundingBoxTool extends RectangleROITool { } } -PHIBoundingBoxTool.toolName = 'PHIBoundingBox'; export default PHIBoundingBoxTool; diff --git a/extensions/cornerstone/src/tools/SmartStackScrollTool.ts b/extensions/cornerstone/src/tools/SmartStackScrollTool.ts index d6aed4d31e5..9b19a8c58dd 100644 --- a/extensions/cornerstone/src/tools/SmartStackScrollTool.ts +++ b/extensions/cornerstone/src/tools/SmartStackScrollTool.ts @@ -2,6 +2,8 @@ import { getEnabledElement, getEnabledElementByIds } from '@cornerstonejs/core'; import { StackScrollTool, Types } from '@cornerstonejs/tools'; class SmartStackScrollTool extends StackScrollTool { + static toolName = 'SmartStackScroll'; + parentDragCallback: (evt: Types.EventTypes.InteractionEventType) => void; parentMouseWheelCallback: (evt: Types.EventTypes.MouseWheelEventType) => void; @@ -45,5 +47,4 @@ class SmartStackScrollTool extends StackScrollTool { } } -SmartStackScrollTool.toolName = 'SmartStackScroll'; export default SmartStackScrollTool;