104 lines
3.2 KiB
TypeScript
104 lines
3.2 KiB
TypeScript
import { DisplaySetService, ViewportGridService } from '@ohif/core';
|
|
|
|
const VOI_SYNC_NAME = 'VOI_SYNC';
|
|
|
|
const getSyncId = modality => `${VOI_SYNC_NAME}_${modality}`;
|
|
|
|
export default function toggleVOISliceSync({
|
|
servicesManager,
|
|
viewports: providedViewports,
|
|
syncId,
|
|
}: withAppTypes) {
|
|
const { syncGroupService, viewportGridService, displaySetService, cornerstoneViewportService } =
|
|
servicesManager.services;
|
|
|
|
const viewports =
|
|
providedViewports || groupViewportsByModality(viewportGridService, displaySetService);
|
|
|
|
// Todo: right now we don't have a proper way to define specific
|
|
// viewports to add to synchronizers, and right now it is global or not
|
|
// after we do that, we should do fine grained control of the synchronizers
|
|
|
|
// we can apply voi sync within each modality group
|
|
for (const [modality, modalityViewports] of Object.entries(viewports)) {
|
|
const syncIdToUse = syncId || getSyncId(modality);
|
|
|
|
const someViewportHasSync = modalityViewports.some(viewport => {
|
|
const syncStates = syncGroupService.getSynchronizersForViewport(
|
|
viewport.viewportOptions.viewportId
|
|
);
|
|
|
|
const imageSync = syncStates.find(syncState => syncState.id === syncIdToUse);
|
|
|
|
return !!imageSync;
|
|
});
|
|
|
|
if (someViewportHasSync) {
|
|
return disableSync(modalityViewports, syncIdToUse, servicesManager);
|
|
}
|
|
|
|
// create synchronization group and add the modalityViewports to it.
|
|
modalityViewports.forEach(gridViewport => {
|
|
const { viewportId } = gridViewport.viewportOptions;
|
|
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
if (!viewport) {
|
|
return;
|
|
}
|
|
syncGroupService.addViewportToSyncGroup(viewportId, viewport.getRenderingEngine().id, {
|
|
type: 'voi',
|
|
id: syncIdToUse as string,
|
|
source: true,
|
|
target: true,
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
function disableSync(modalityViewports, syncId, servicesManager: AppTypes.ServicesManager) {
|
|
const { syncGroupService, cornerstoneViewportService } = servicesManager.services;
|
|
|
|
const viewports = modalityViewports;
|
|
viewports.forEach(gridViewport => {
|
|
const { viewportId } = gridViewport.viewportOptions;
|
|
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
if (!viewport) {
|
|
return;
|
|
}
|
|
syncGroupService.removeViewportFromSyncGroup(
|
|
viewport.id,
|
|
viewport.getRenderingEngine().id,
|
|
syncId
|
|
);
|
|
});
|
|
}
|
|
|
|
function groupViewportsByModality(
|
|
viewportGridService: ViewportGridService,
|
|
displaySetService: DisplaySetService
|
|
) {
|
|
const { viewports } = viewportGridService.getState();
|
|
|
|
const viewportsArray = [...viewports.values()];
|
|
|
|
// group the viewports by modality
|
|
return viewportsArray.reduce((acc, viewport) => {
|
|
const { displaySetInstanceUIDs } = viewport;
|
|
// Todo: add proper fusion support
|
|
// Fix: Skip processing if the viewport is empty.
|
|
if (!displaySetInstanceUIDs?.length) {
|
|
return acc;
|
|
}
|
|
const displaySetInstanceUID = displaySetInstanceUIDs[0];
|
|
const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
|
|
|
|
const modality = displaySet.Modality;
|
|
if (!acc[modality]) {
|
|
acc[modality] = [];
|
|
}
|
|
|
|
acc[modality].push(viewport);
|
|
|
|
return acc;
|
|
}, {});
|
|
}
|