Files
ohif-viewer/extensions/cornerstone/src/utils/imageSliceSync/toggleImageSliceSync.ts
T

101 lines
3.2 KiB
TypeScript
Raw Normal View History

import { DisplaySetService, ViewportGridService } from '@ohif/core';
const IMAGE_SLICE_SYNC_NAME = 'IMAGE_SLICE_SYNC';
export default function toggleImageSliceSync({
servicesManager,
viewports: providedViewports,
syncId,
}: withAppTypes) {
const { syncGroupService, viewportGridService, displaySetService, cornerstoneViewportService } =
servicesManager.services;
syncId ||= IMAGE_SLICE_SYNC_NAME;
const viewports =
providedViewports || getReconstructableStackViewports(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
const someViewportHasSync = viewports.some(viewport => {
const syncStates = syncGroupService.getSynchronizersForViewport(
viewport.viewportOptions.viewportId
);
const imageSync = syncStates.find(syncState => syncState.id === syncId);
return !!imageSync;
});
if (someViewportHasSync) {
return disableSync(syncId, servicesManager);
}
// create synchronization group and add the viewports to it.
viewports.forEach(gridViewport => {
const { viewportId } = gridViewport.viewportOptions;
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
if (!viewport) {
return;
}
syncGroupService.addViewportToSyncGroup(viewportId, viewport.getRenderingEngine().id, {
type: 'imageSlice',
id: syncId,
source: true,
target: true,
});
});
}
function disableSync(syncName, servicesManager: AppTypes.ServicesManager) {
const { syncGroupService, viewportGridService, displaySetService, cornerstoneViewportService } =
servicesManager.services;
const viewports = getReconstructableStackViewports(viewportGridService, displaySetService);
viewports.forEach(gridViewport => {
const { viewportId } = gridViewport.viewportOptions;
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
if (!viewport) {
return;
}
syncGroupService.removeViewportFromSyncGroup(
viewport.id,
viewport.getRenderingEngine().id,
syncName
);
});
}
/**
* Gets the consistent spacing stack viewport types, which are the ones which
* can be navigated using the stack image sync right now.
*/
function getReconstructableStackViewports(
viewportGridService: ViewportGridService,
displaySetService: DisplaySetService
) {
let { viewports } = viewportGridService.getState();
viewports = [...viewports.values()];
// filter empty viewports
viewports = viewports.filter(
viewport => viewport.displaySetInstanceUIDs && viewport.displaySetInstanceUIDs.length
);
// filter reconstructable viewports
viewports = viewports.filter(viewport => {
const { displaySetInstanceUIDs } = viewport;
for (const displaySetInstanceUID of displaySetInstanceUIDs) {
const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
// TODO - add a better test than isReconstructable
if (displaySet && displaySet.isReconstructable) {
return true;
}
return false;
}
});
return viewports;
}