feat(SR): SCOORD3D point annotations support for stack viewports (#4315)
This commit is contained in:
1 parent
e0fca8c88c
commit
ac1cad25af
51 files changed
+978
-607
No files matched your search
@@ -610,5 +610,4 @@ OHIFCornerstoneViewport.propTypes = {
|
||||
// to set the initial state of the viewport's first image to render
|
||||
initialImageIdOrIndex: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
};
|
||||
|
||||
export default OHIFCornerstoneViewport;
|
||||
@@ -0,0 +1,9 @@
|
||||
export const CORNERSTONE_3D_TOOLS_SOURCE_NAME = 'Cornerstone3DTools';
|
||||
export const CORNERSTONE_3D_TOOLS_SOURCE_VERSION = '0.1';
|
||||
|
||||
const Enums = {
|
||||
CORNERSTONE_3D_TOOLS_SOURCE_NAME,
|
||||
CORNERSTONE_3D_TOOLS_SOURCE_VERSION,
|
||||
};
|
||||
|
||||
export default Enums;
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
import * as csStreamingImageVolumeLoader from '@cornerstonejs/streaming-image-volume-loader';
|
||||
import { Enums as cs3DToolsEnums } from '@cornerstonejs/tools';
|
||||
import { Types } from '@ohif/core';
|
||||
import Enums from './enums';
|
||||
|
||||
import init from './init';
|
||||
import getCustomizationModule from './getCustomizationModule';
|
||||
@@ -234,5 +235,6 @@ export {
|
||||
ImageOverlayViewerTool,
|
||||
getSOPInstanceAttributes,
|
||||
dicomLoaderService,
|
||||
Enums,
|
||||
};
|
||||
export default cornerstoneExtension;
|
||||
@@ -1,19 +1,17 @@
|
||||
import { eventTarget } from '@cornerstonejs/core';
|
||||
import { Enums, annotation } from '@cornerstonejs/tools';
|
||||
import { DicomMetadataStore } from '@ohif/core';
|
||||
|
||||
import * as CSExtensionEnums from './enums';
|
||||
import { toolNames } from './initCornerstoneTools';
|
||||
import { onCompletedCalibrationLine } from './tools/CalibrationLineTool';
|
||||
|
||||
import measurementServiceMappingsFactory from './utils/measurementServiceMappings/measurementServiceMappingsFactory';
|
||||
import getSOPInstanceAttributes from './utils/measurementServiceMappings/utils/getSOPInstanceAttributes';
|
||||
|
||||
const { CORNERSTONE_3D_TOOLS_SOURCE_NAME, CORNERSTONE_3D_TOOLS_SOURCE_VERSION } = CSExtensionEnums;
|
||||
const { removeAnnotation } = annotation.state;
|
||||
|
||||
const csToolsEvents = Enums.Events;
|
||||
|
||||
const CORNERSTONE_3D_TOOLS_SOURCE_NAME = 'Cornerstone3DTools';
|
||||
const CORNERSTONE_3D_TOOLS_SOURCE_VERSION = '0.1';
|
||||
|
||||
const initMeasurementService = (
|
||||
measurementService,
|
||||
displaySetService,
|
||||
@@ -189,11 +187,7 @@ const connectToolsToMeasurementService = (servicesManager: AppTypes.ServicesMana
|
||||
cornerstoneViewportService,
|
||||
customizationService
|
||||
);
|
||||
connectMeasurementServiceToTools(
|
||||
measurementService,
|
||||
cornerstoneViewportService,
|
||||
csTools3DVer1MeasurementSource
|
||||
);
|
||||
connectMeasurementServiceToTools(measurementService, cornerstoneViewportService);
|
||||
const { annotationToMeasurement, remove } = csTools3DVer1MeasurementSource;
|
||||
|
||||
//
|
||||
@@ -210,7 +204,7 @@ const connectToolsToMeasurementService = (servicesManager: AppTypes.ServicesMana
|
||||
onCompletedCalibrationLine(servicesManager, csToolsEvent)
|
||||
.then(
|
||||
() => {
|
||||
console.log('calibration applied');
|
||||
console.log('Calibration applied.');
|
||||
},
|
||||
() => true
|
||||
)
|
||||
@@ -230,7 +224,7 @@ const connectToolsToMeasurementService = (servicesManager: AppTypes.ServicesMana
|
||||
annotationToMeasurement(toolName, annotationAddedEventDetail);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to update measurement:', error);
|
||||
console.warn('Failed to add measurement:', error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,6 +251,7 @@ const connectToolsToMeasurementService = (servicesManager: AppTypes.ServicesMana
|
||||
console.warn('Failed to update measurement:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function selectMeasurement(csToolsEvent) {
|
||||
try {
|
||||
const annotationSelectionEventDetail = csToolsEvent.detail;
|
||||
@@ -276,7 +271,7 @@ const connectToolsToMeasurementService = (servicesManager: AppTypes.ServicesMana
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to select and unselect measurements:', error);
|
||||
console.warn('Failed to select/unselect measurements:', error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,20 +283,13 @@ const connectToolsToMeasurementService = (servicesManager: AppTypes.ServicesMana
|
||||
*/
|
||||
function removeMeasurement(csToolsEvent) {
|
||||
try {
|
||||
try {
|
||||
const annotationRemovedEventDetail = csToolsEvent.detail;
|
||||
const {
|
||||
annotation: { annotationUID },
|
||||
} = annotationRemovedEventDetail;
|
||||
|
||||
const measurement = measurementService.getMeasurement(annotationUID);
|
||||
|
||||
if (measurement) {
|
||||
console.log('~~ removeEvt', csToolsEvent);
|
||||
remove(annotationUID, annotationRemovedEventDetail);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to update measurement:', error);
|
||||
const annotationRemovedEventDetail = csToolsEvent.detail;
|
||||
const {
|
||||
annotation: { annotationUID },
|
||||
} = annotationRemovedEventDetail;
|
||||
const measurement = measurementService.getMeasurement(annotationUID);
|
||||
if (measurement) {
|
||||
remove(annotationUID, annotationRemovedEventDetail);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to remove measurement:', error);
|
||||
@@ -325,19 +313,10 @@ const connectToolsToMeasurementService = (servicesManager: AppTypes.ServicesMana
|
||||
return csTools3DVer1MeasurementSource;
|
||||
};
|
||||
|
||||
const connectMeasurementServiceToTools = (
|
||||
measurementService,
|
||||
cornerstoneViewportService,
|
||||
measurementSource
|
||||
) => {
|
||||
const connectMeasurementServiceToTools = (measurementService, cornerstoneViewportService) => {
|
||||
const { MEASUREMENT_REMOVED, MEASUREMENTS_CLEARED, MEASUREMENT_UPDATED, RAW_MEASUREMENT_ADDED } =
|
||||
measurementService.EVENTS;
|
||||
|
||||
const csTools3DVer1MeasurementSource = measurementService.getSource(
|
||||
CORNERSTONE_3D_TOOLS_SOURCE_NAME,
|
||||
CORNERSTONE_3D_TOOLS_SOURCE_VERSION
|
||||
);
|
||||
|
||||
measurementService.subscribe(MEASUREMENTS_CLEARED, ({ measurements }) => {
|
||||
if (!Object.keys(measurements).length) {
|
||||
return;
|
||||
@@ -348,7 +327,6 @@ const connectMeasurementServiceToTools = (
|
||||
if (source.name !== CORNERSTONE_3D_TOOLS_SOURCE_NAME) {
|
||||
continue;
|
||||
}
|
||||
|
||||
removeAnnotation(uid);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -188,6 +188,12 @@ class CornerstoneCacheService {
|
||||
|
||||
const displaySet = nonOverlayDisplaySets[0];
|
||||
|
||||
if (displaySet.load && displaySet.load instanceof Function) {
|
||||
const { userAuthenticationService } = this.servicesManager.services;
|
||||
const headers = userAuthenticationService.getAuthorizationHeader();
|
||||
await displaySet.load({ headers });
|
||||
}
|
||||
|
||||
let stackImageIds = this.stackImageIds.get(displaySet.displaySetInstanceUID);
|
||||
|
||||
if (!stackImageIds) {
|
||||
|
||||
@@ -404,6 +404,14 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
||||
): void {
|
||||
const renderingEngine = this.getRenderingEngine();
|
||||
|
||||
// if not valid viewportData then return early
|
||||
if (viewportData.viewportType === csEnums.ViewportType.STACK) {
|
||||
// check if imageIds is valid
|
||||
if (!viewportData.data[0].imageIds?.length) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// This is the old viewportInfo, which may have old options but we might be
|
||||
// using its viewport (same viewportId as the new viewportInfo)
|
||||
const viewportInfo = this.viewportsById.get(viewportId);
|
||||
@@ -641,6 +649,10 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
||||
|
||||
this._handleOverlays(viewport);
|
||||
|
||||
if (!imageIds?.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
return viewport.setStack(imageIds, initialImageIndexToUse).then(() => {
|
||||
viewport.setProperties({ ...properties });
|
||||
this.setPresentations(viewport.id, presentations, viewportInfo);
|
||||
|
||||
@@ -19,11 +19,11 @@ const Probe = {
|
||||
getValueTypeFromToolType,
|
||||
customizationService
|
||||
) => {
|
||||
const { annotation, viewportId } = csToolsEventDetail;
|
||||
const { annotation } = csToolsEventDetail;
|
||||
const { metadata, data, annotationUID } = annotation;
|
||||
|
||||
if (!metadata || !data) {
|
||||
console.warn('Length tool: Missing metadata or data');
|
||||
console.warn('Probe tool: Missing metadata or data');
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -1,4 +1,4 @@
|
||||
export default [
|
||||
const supportedTools = [
|
||||
'Length',
|
||||
'EllipticalROI',
|
||||
'CircleROI',
|
||||
@@ -11,6 +11,8 @@ export default [
|
||||
'PlanarFreehandROI',
|
||||
'SplineROI',
|
||||
'LivewireContour',
|
||||
'Probe',
|
||||
'UltrasoundDirectionalTool',
|
||||
'SCOORD3DPoint',
|
||||
];
|
||||
|
||||
export default supportedTools;
|
||||
-10
@@ -94,7 +94,6 @@ const measurementServiceMappingsFactory = (
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
EllipticalROI: {
|
||||
toAnnotation: EllipticalROI.toAnnotation,
|
||||
toMeasurement: csToolsAnnotation =>
|
||||
@@ -111,7 +110,6 @@ const measurementServiceMappingsFactory = (
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
CircleROI: {
|
||||
toAnnotation: CircleROI.toAnnotation,
|
||||
toMeasurement: csToolsAnnotation =>
|
||||
@@ -128,7 +126,6 @@ const measurementServiceMappingsFactory = (
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
RectangleROI: {
|
||||
toAnnotation: RectangleROI.toAnnotation,
|
||||
toMeasurement: csToolsAnnotation =>
|
||||
@@ -145,7 +142,6 @@ const measurementServiceMappingsFactory = (
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
PlanarFreehandROI: {
|
||||
toAnnotation: PlanarFreehandROI.toAnnotation,
|
||||
toMeasurement: csToolsAnnotation =>
|
||||
@@ -162,7 +158,6 @@ const measurementServiceMappingsFactory = (
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
SplineROI: {
|
||||
toAnnotation: SplineROI.toAnnotation,
|
||||
toMeasurement: csToolsAnnotation =>
|
||||
@@ -179,7 +174,6 @@ const measurementServiceMappingsFactory = (
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
LivewireContour: {
|
||||
toAnnotation: LivewireContour.toAnnotation,
|
||||
toMeasurement: csToolsAnnotation =>
|
||||
@@ -196,7 +190,6 @@ const measurementServiceMappingsFactory = (
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
ArrowAnnotate: {
|
||||
toAnnotation: ArrowAnnotate.toAnnotation,
|
||||
toMeasurement: csToolsAnnotation =>
|
||||
@@ -214,7 +207,6 @@ const measurementServiceMappingsFactory = (
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
Probe: {
|
||||
toAnnotation: Probe.toAnnotation,
|
||||
toMeasurement: csToolsAnnotation =>
|
||||
@@ -232,7 +224,6 @@ const measurementServiceMappingsFactory = (
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
CobbAngle: {
|
||||
toAnnotation: CobbAngle.toAnnotation,
|
||||
toMeasurement: csToolsAnnotation =>
|
||||
@@ -249,7 +240,6 @@ const measurementServiceMappingsFactory = (
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
Angle: {
|
||||
toAnnotation: Angle.toAnnotation,
|
||||
toMeasurement: csToolsAnnotation =>
|
||||
|
||||
Reference in new issue
Block a user