feat: explicit layout apply via HangingProtocolService (#2936)

* feat: add more types to HP service

* change hp to have apply protocol

* feat: mpr initial work

* apply protocol by id

* feat: mode should be able to apply protocol directly

* fix: wrong inheritance for viewports drag and drop

* apply review comments
This commit is contained in:
Alireza authored and GitHub committed 2022-09-20 23:40:26 -04:00
1 parent fb9744a817
commit 5f480ff746
28 files changed
+705 -226

No files matched your search

@@ -22,6 +22,20 @@ function areEqual(prevProps, nextProps) {
return false;
}
if (
prevProps.viewportOptions.orientation !==
nextProps.viewportOptions.orientation
) {
return false;
}
if (
prevProps.viewportOptions.viewportType !==
nextProps.viewportOptions.viewportType
) {
return false;
}
const prevDisplaySets = prevProps.displaySets[0];
const nextDisplaySets = nextProps.displaySets[0];
@@ -258,8 +258,14 @@ function _getInstanceNumberFromVolume(
const isAcquisitionPlane = vec3.length(cross) < EPSILON;
if (isAcquisitionPlane) {
const imageId = imageIds[imageIndex];
if (!imageId) {
return {};
}
const { instanceNumber } =
metaData.get('generalImageModule', imageIds[imageIndex]) || {};
metaData.get('generalImageModule', imageId) || {};
return parseInt(instanceNumber);
}
}
@@ -11,6 +11,8 @@ import {
segmentation,
utilities as csToolsUtils,
} from '@cornerstonejs/tools';
import { Types } from '@ohif/core';
import CornerstoneViewportDownloadForm from './utils/CornerstoneViewportDownloadForm';
import { getEnabledElement as OHIFgetEnabledElement } from './state';
@@ -26,6 +28,9 @@ const commandsModule = ({ servicesManager }) => {
UIDialogService,
CornerstoneViewportService,
SegmentationService,
DisplaySetService,
HangingProtocolService,
UINotificationService,
} = servicesManager.services;
function _getActiveViewportEnabledElement() {
@@ -415,6 +420,9 @@ const commandsModule = ({ servicesManager }) => {
(activeViewportIndex - 1 + viewports.length) % viewports.length;
ViewportGridService.setActiveViewportIndex(nextViewportIndex);
},
setHangingProtocol: ({ protocolId }) => {
HangingProtocolService.setProtocol(protocolId);
},
};
const definitions = {
@@ -537,6 +545,11 @@ const commandsModule = ({ servicesManager }) => {
storeContexts: [],
options: {},
},
setHangingProtocol: {
commandFn: actions.setHangingProtocol,
storeContexts: [],
options: {},
},
};
return {
@@ -0,0 +1,146 @@
import { Types } from '@ohif/core';
const MPRHangingProtocolGenerator: Types.HangingProtocol.ProtocolGenerator = ({
servicesManager,
commandsManager,
}) => {
const {
ViewportGridService,
UINotificationService,
DisplaySetService,
} = servicesManager.services;
const { activeViewportIndex, viewports } = ViewportGridService.getState();
const viewportDisplaySetInstanceUIDs =
viewports[activeViewportIndex].displaySetInstanceUIDs;
if (
!viewportDisplaySetInstanceUIDs ||
!viewportDisplaySetInstanceUIDs.length
) {
return;
}
const displaySetsToHang = viewportDisplaySetInstanceUIDs.map(
displaySetInstanceUID => {
const displaySet = DisplaySetService.getDisplaySetByUID(
displaySetInstanceUID
);
return displaySet;
}
);
if (displaySetsToHang.some(ds => !ds.isReconstructable)) {
UINotificationService.show({
title: 'Multiplanar reconstruction (MPR) ',
message:
'Cannot create MPR for this series since it is not reconstructable.',
type: 'warning',
displayTime: 3000,
});
return;
}
const matchingDisplaySets = {};
displaySetsToHang.forEach(displaySet => {
const {
displaySetInstanceUID,
SeriesInstanceUID,
StudyInstanceUID,
} = displaySet;
matchingDisplaySets[displaySetInstanceUID] = {
displaySetInstanceUID,
SeriesInstanceUID,
StudyInstanceUID,
} as Types.HangingProtocol.DisplaySetMatchDetails;
});
const hpViewports: Types.HangingProtocol.Viewport[] = [
'axial',
'sagittal',
'coronal',
].map(viewportOrientation => {
return {
viewportOptions: {
toolGroupId: 'mpr',
viewportType: 'volume',
orientation: viewportOrientation,
initialImageOptions: {
preset: 'middle',
},
syncGroups: [
{
type: 'voi',
id: 'mpr',
source: true,
target: true,
},
],
},
displaySets: viewportDisplaySetInstanceUIDs.map(displaySetInstanceUID => {
return {
id: displaySetInstanceUID,
};
}),
};
});
const protocol = {
id: 'mpr',
stages: [
{
id: 'mprStage',
name: 'mpr',
viewportStructure: {
layoutType: 'grid',
properties: {
rows: 1,
columns: 3,
layoutOptions: [
{
x: 0,
y: 0,
width: 1 / 3,
height: 1,
},
{
x: 1 / 3,
y: 0,
width: 1 / 3,
height: 1,
},
{
x: 2 / 3,
y: 0,
width: 1 / 3,
height: 1,
},
],
},
},
displaySets: [],
viewports: hpViewports,
},
],
};
return {
protocol,
matchingDisplaySets,
};
};
function getHangingProtocolModule() {
return [
{
id: 'mpr',
protocol: MPRHangingProtocolGenerator,
},
];
}
export default getHangingProtocolModule;
+2
View File
@@ -9,6 +9,7 @@ import {
import { Enums as cs3DToolsEnums } from '@cornerstonejs/tools';
import init from './init.js';
import commandsModule from './commandsModule';
import getHangingProtocolModule from './getHangingProtocolModule';
import ToolGroupService from './services/ToolGroupService';
import SyncGroupService from './services/SyncGroupService';
import { toolNames } from './initCornerstoneTools';
@@ -70,6 +71,7 @@ const cornerstoneExtension = {
servicesManager.registerService(SyncGroupService(servicesManager));
await init({ servicesManager, commandsManager, configuration, appConfig });
},
getHangingProtocolModule,
getViewportModule({ servicesManager, commandsManager }) {
const ExtendedOHIFCornerstoneViewport = props => {
// const onNewImageHandler = jumpData => {