feat(4D): Add 4D dynamic volume rendering and new pre-clinical 4d pt/ct mode (#3664)
Co-authored-by: Alireza <ar.sedghi@gmail.com> Co-authored-by: Neil <neil.a.macphee@gmail.com>
This commit is contained in:
200 files changed
+9589
-2178
No files matched your search
@@ -5,23 +5,79 @@ import isDisplaySetReconstructable from '@ohif/core/src/utils/isDisplaySetRecons
|
||||
import { id } from './id';
|
||||
import getDisplaySetMessages from './getDisplaySetMessages';
|
||||
import getDisplaySetsFromUnsupportedSeries from './getDisplaySetsFromUnsupportedSeries';
|
||||
import { chartHandler } from './SOPClassHandlers/chartSOPClassHandler';
|
||||
|
||||
const DEFAULT_VOLUME_LOADER_SCHEME = 'cornerstoneStreamingImageVolume';
|
||||
const DYNAMIC_VOLUME_LOADER_SCHEME = 'cornerstoneStreamingDynamicImageVolume';
|
||||
const sopClassHandlerName = 'stack';
|
||||
let appContext = {};
|
||||
|
||||
const getDynamicVolumeInfo = instances => {
|
||||
const { extensionManager } = appContext;
|
||||
|
||||
if (!extensionManager) {
|
||||
throw new Error('extensionManager is not available');
|
||||
}
|
||||
|
||||
const imageIds = instances.map(({ imageId }) => imageId);
|
||||
const volumeLoaderUtility = extensionManager.getModuleEntry(
|
||||
'@ohif/extension-cornerstone.utilityModule.volumeLoader'
|
||||
);
|
||||
const { getDynamicVolumeInfo: csGetDynamicVolumeInfo } = volumeLoaderUtility.exports;
|
||||
|
||||
return csGetDynamicVolumeInfo(imageIds);
|
||||
};
|
||||
|
||||
const isMultiFrame = instance => {
|
||||
return instance.NumberOfFrames > 1;
|
||||
};
|
||||
|
||||
function getDisplaySetInfo(instances) {
|
||||
const dynamicVolumeInfo = getDynamicVolumeInfo(instances);
|
||||
const { isDynamicVolume, timePoints } = dynamicVolumeInfo;
|
||||
let displaySetInfo;
|
||||
|
||||
if (isDynamicVolume) {
|
||||
const timePoint = timePoints[0];
|
||||
const instancesMap = new Map();
|
||||
|
||||
// O(n) to convert it into a map and O(1) to find each instance
|
||||
instances.forEach(instance => instancesMap.set(instance.imageId, instance));
|
||||
|
||||
const firstTimePointInstances = timePoint.map(imageId => instancesMap.get(imageId));
|
||||
|
||||
displaySetInfo = isDisplaySetReconstructable(firstTimePointInstances);
|
||||
} else {
|
||||
displaySetInfo = isDisplaySetReconstructable(instances);
|
||||
}
|
||||
|
||||
return {
|
||||
isDynamicVolume,
|
||||
...displaySetInfo,
|
||||
dynamicVolumeInfo,
|
||||
};
|
||||
}
|
||||
|
||||
const makeDisplaySet = instances => {
|
||||
const instance = instances[0];
|
||||
const imageSet = new ImageSet(instances);
|
||||
|
||||
const { value: isReconstructable, averageSpacingBetweenFrames } =
|
||||
isDisplaySetReconstructable(instances);
|
||||
const {
|
||||
isDynamicVolume,
|
||||
value: isReconstructable,
|
||||
averageSpacingBetweenFrames,
|
||||
dynamicVolumeInfo,
|
||||
} = getDisplaySetInfo(instances);
|
||||
|
||||
const volumeLoaderSchema = isDynamicVolume
|
||||
? DYNAMIC_VOLUME_LOADER_SCHEME
|
||||
: DEFAULT_VOLUME_LOADER_SCHEME;
|
||||
|
||||
// set appropriate attributes to image set...
|
||||
const messages = getDisplaySetMessages(instances, isReconstructable);
|
||||
const messages = getDisplaySetMessages(instances, isReconstructable, isDynamicVolume);
|
||||
|
||||
imageSet.setAttributes({
|
||||
volumeLoaderSchema,
|
||||
displaySetInstanceUID: imageSet.uid, // create a local alias for the imageSet UID
|
||||
SeriesDate: instance.SeriesDate,
|
||||
SeriesTime: instance.SeriesTime,
|
||||
@@ -39,6 +95,8 @@ const makeDisplaySet = instances => {
|
||||
isReconstructable,
|
||||
messages,
|
||||
averageSpacingBetweenFrames: averageSpacingBetweenFrames || null,
|
||||
isDynamicVolume,
|
||||
dynamicVolumeInfo,
|
||||
});
|
||||
|
||||
// Sort the images in this series if needed
|
||||
@@ -88,7 +146,6 @@ function getSopClassUids(instances) {
|
||||
* - For all Image types that are stackable, create
|
||||
* a displaySet with a stack of images
|
||||
*
|
||||
* @param {Array} sopClassHandlerModules List of SOP Class Modules
|
||||
* @param {SeriesMetadata} series The series metadata object from which the display sets will be created
|
||||
* @returns {Array} The list of display sets created for the given series object
|
||||
*/
|
||||
@@ -203,7 +260,9 @@ const sopClassUids = [
|
||||
sopClassDictionary.EnhancedUSVolumeStorage,
|
||||
];
|
||||
|
||||
function getSopClassHandlerModule() {
|
||||
function getSopClassHandlerModule(appContextParam) {
|
||||
appContext = appContextParam;
|
||||
|
||||
return [
|
||||
{
|
||||
name: sopClassHandlerName,
|
||||
@@ -215,6 +274,11 @@ function getSopClassHandlerModule() {
|
||||
sopClassUids: [],
|
||||
getDisplaySetsFromSeries: getDisplaySetsFromUnsupportedSeries,
|
||||
},
|
||||
{
|
||||
name: chartHandler.name,
|
||||
sopClassUids: chartHandler.sopClassUids,
|
||||
getDisplaySetsFromSeries: chartHandler.getDisplaySetsFromSeries,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user