fix(core): Address 3D reconstruction and Android compatibility issues and clean up 4D data mode (#4762)

This commit is contained in:
Alireza authored and GitHub committed 2025-02-04 12:25:10 -05:00
1 parent 4d06a7d286
commit 149d6d049c
32 files changed
+529 -529

No files matched your search

+4 -4
View File
@@ -38,7 +38,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^2.17.2",
"@cornerstonejs/dicom-image-loader": "^2.19.3",
"@ohif/core": "3.10.0-beta.91",
"@ohif/ui": "3.10.0-beta.91",
"dcmjs": "*",
@@ -54,9 +54,9 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^2.17.2",
"@cornerstonejs/core": "^2.17.2",
"@cornerstonejs/tools": "^2.17.2",
"@cornerstonejs/adapters": "^2.19.3",
"@cornerstonejs/core": "^2.19.3",
"@cornerstonejs/tools": "^2.19.3",
"@icr/polyseg-wasm": "^0.4.0",
"@itk-wasm/morphological-contour-interpolation": "1.1.0",
"@kitware/vtk.js": "32.1.1",
@@ -53,13 +53,13 @@ function WrappedCinePlayer({
// check if the displaySet is dynamic and set the dynamic info
if (displaySet.isDynamicVolume) {
const { dynamicVolumeInfo } = displaySet;
const numTimePoints = dynamicVolumeInfo.timePoints.length;
const numDimensionGroups = dynamicVolumeInfo.timePoints.length;
const label = dynamicVolumeInfo.splittingTag;
const timePointIndex = dynamicVolumeInfo.timePointIndex || 0;
const dimensionGroupNumber = dynamicVolumeInfo.dimensionGroupNumber || 1;
setDynamicInfo({
volumeId: displaySet.displaySetInstanceUID,
timePointIndex,
numTimePoints,
dimensionGroupNumber,
numDimensionGroups,
label,
});
} else {
@@ -176,20 +176,20 @@ function RenderCinePlayer({
return;
}
const handleTimePointIndexChange = evt => {
const { volumeId, timePointIndex, numTimePoints, splittingTag } = evt.detail;
setDynamicInfo({ volumeId, timePointIndex, numTimePoints, label: splittingTag });
const handleDimensionGroupChange = evt => {
const { volumeId, dimensionGroupNumber, numDimensionGroups, splittingTag } = evt.detail;
setDynamicInfo({ volumeId, dimensionGroupNumber, numDimensionGroups, label: splittingTag });
};
eventTarget.addEventListener(
Enums.Events.DYNAMIC_VOLUME_TIME_POINT_INDEX_CHANGED,
handleTimePointIndexChange
Enums.Events.DYNAMIC_VOLUME_DIMENSION_GROUP_CHANGED,
handleDimensionGroupChange
);
return () => {
eventTarget.removeEventListener(
Enums.Events.DYNAMIC_VOLUME_TIME_POINT_INDEX_CHANGED,
handleTimePointIndexChange
Enums.Events.DYNAMIC_VOLUME_DIMENSION_GROUP_CHANGED,
handleDimensionGroupChange
);
};
}, [dynamicInfo]);
@@ -199,17 +199,17 @@ function RenderCinePlayer({
return;
}
const { volumeId, timePointIndex, numTimePoints, splittingTag } = dynamicInfo || {};
const { volumeId, dimensionGroupNumber, numDimensionGroups, splittingTag } = dynamicInfo || {};
const volume = cache.getVolume(volumeId, true);
volume.timePointIndex = timePointIndex;
volume.dimensionGroupNumber = dimensionGroupNumber;
setDynamicInfo({ volumeId, timePointIndex, numTimePoints, label: splittingTag });
setDynamicInfo({ volumeId, dimensionGroupNumber, numDimensionGroups, label: splittingTag });
}, []);
const updateDynamicInfo = useCallback(props => {
const { volumeId, timePointIndex } = props;
const { volumeId, dimensionGroupNumber } = props;
const volume = cache.getVolume(volumeId, true);
volume.timePointIndex = timePointIndex;
volume.dimensionGroupNumber = dimensionGroupNumber;
}, []);
return (
+6 -33
View File
@@ -1,3 +1,5 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
export const fourUp = {
id: 'fourUp',
locked: true,
@@ -46,17 +48,7 @@ export const fourUp = {
initialImageOptions: {
preset: 'middle',
},
syncGroups: [
{
type: 'voi',
id: 'mpr',
source: true,
target: true,
options: {
syncColormap: true,
},
},
],
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
@@ -72,6 +64,7 @@ export const fourUp = {
customViewportProps: {
hideOverlays: true,
},
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
@@ -94,17 +87,7 @@ export const fourUp = {
initialImageOptions: {
preset: 'middle',
},
syncGroups: [
{
type: 'voi',
id: 'mpr',
source: true,
target: true,
options: {
syncColormap: true,
},
},
],
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
@@ -120,17 +103,7 @@ export const fourUp = {
initialImageOptions: {
preset: 'middle',
},
syncGroups: [
{
type: 'voi',
id: 'mpr',
source: true,
target: true,
options: {
syncColormap: true,
},
},
],
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
+5 -33
View File
@@ -1,3 +1,5 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
export const main3D = {
id: 'main3D',
locked: true,
@@ -94,17 +96,7 @@ export const main3D = {
initialImageOptions: {
preset: 'middle',
},
syncGroups: [
{
type: 'voi',
id: 'mpr',
source: true,
target: true,
options: {
syncColormap: true,
},
},
],
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
@@ -120,17 +112,7 @@ export const main3D = {
initialImageOptions: {
preset: 'middle',
},
syncGroups: [
{
type: 'voi',
id: 'mpr',
source: true,
target: true,
options: {
syncColormap: true,
},
},
],
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
@@ -146,17 +128,7 @@ export const main3D = {
initialImageOptions: {
preset: 'middle',
},
syncGroups: [
{
type: 'voi',
id: 'mpr',
source: true,
target: true,
options: {
syncColormap: true,
},
},
],
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
+2 -2
View File
@@ -1,6 +1,6 @@
import { Types } from '@ohif/core';
const VOI_SYNC_GROUP = {
export const VOI_SYNC_GROUP = {
type: 'voi',
id: 'mpr',
source: true,
@@ -10,7 +10,7 @@ const VOI_SYNC_GROUP = {
},
};
const HYDRATE_SEG_SYNC_GROUP = {
export const HYDRATE_SEG_SYNC_GROUP = {
type: 'hydrateseg',
id: 'sameFORId',
source: true,
@@ -1,3 +1,5 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
export const mprAnd3DVolumeViewport = {
id: 'mprAnd3DVolumeViewport',
locked: true,
@@ -53,17 +55,7 @@ export const mprAnd3DVolumeViewport = {
initialImageOptions: {
preset: 'middle',
},
syncGroups: [
{
type: 'voi',
id: 'mpr',
source: true,
target: true,
options: {
syncColormap: true,
},
},
],
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
@@ -79,6 +71,7 @@ export const mprAnd3DVolumeViewport = {
customViewportProps: {
hideOverlays: true,
},
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
@@ -101,17 +94,7 @@ export const mprAnd3DVolumeViewport = {
initialImageOptions: {
preset: 'middle',
},
syncGroups: [
{
type: 'voi',
id: 'mpr',
source: true,
target: true,
options: {
syncColormap: true,
},
},
],
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
@@ -127,17 +110,7 @@ export const mprAnd3DVolumeViewport = {
initialImageOptions: {
preset: 'middle',
},
syncGroups: [
{
type: 'voi',
id: 'mpr',
source: true,
target: true,
options: {
syncColormap: true,
},
},
],
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
+3
View File
@@ -1,3 +1,5 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
export const only3D = {
id: 'only3D',
locked: true,
@@ -45,6 +47,7 @@ export const only3D = {
orientation: 'coronal',
customViewportProps: {
hideOverlays: true,
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
},
displaySets: [
+5 -33
View File
@@ -1,3 +1,5 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
export const primary3D = {
id: 'primary3D',
locked: true,
@@ -94,17 +96,7 @@ export const primary3D = {
initialImageOptions: {
preset: 'middle',
},
syncGroups: [
{
type: 'voi',
id: 'mpr',
source: true,
target: true,
options: {
syncColormap: true,
},
},
],
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
@@ -120,17 +112,7 @@ export const primary3D = {
initialImageOptions: {
preset: 'middle',
},
syncGroups: [
{
type: 'voi',
id: 'mpr',
source: true,
target: true,
options: {
syncColormap: true,
},
},
],
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
@@ -146,17 +128,7 @@ export const primary3D = {
initialImageOptions: {
preset: 'middle',
},
syncGroups: [
{
type: 'voi',
id: 'mpr',
source: true,
target: true,
options: {
syncColormap: true,
},
},
],
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
+5 -33
View File
@@ -1,3 +1,5 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
export const primaryAxial = {
id: 'primaryAxial',
locked: true,
@@ -66,17 +68,7 @@ export const primaryAxial = {
initialImageOptions: {
preset: 'middle',
},
syncGroups: [
{
type: 'voi',
id: 'mpr',
source: true,
target: true,
options: {
syncColormap: true,
},
},
],
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
@@ -92,17 +84,7 @@ export const primaryAxial = {
initialImageOptions: {
preset: 'middle',
},
syncGroups: [
{
type: 'voi',
id: 'mpr',
source: true,
target: true,
options: {
syncColormap: true,
},
},
],
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
@@ -118,17 +100,7 @@ export const primaryAxial = {
initialImageOptions: {
preset: 'middle',
},
syncGroups: [
{
type: 'voi',
id: 'mpr',
source: true,
target: true,
options: {
syncColormap: true,
},
},
],
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
@@ -1,22 +1,18 @@
import { useEffect, useState, memo } from 'react';
import { useEffect, useState, memo, useCallback } from 'react';
const ActiveViewportBehavior = memo(
({ servicesManager, viewportId }: withAppTypes<{ viewportId: string }>) => {
const { displaySetService, cineService, viewportGridService, customizationService } =
servicesManager.services;
const {
displaySetService,
cineService,
viewportGridService,
customizationService,
cornerstoneViewportService,
} = servicesManager.services;
const [activeViewportId, setActiveViewportId] = useState(viewportId);
useEffect(() => {
const subscription = viewportGridService.subscribe(
viewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED,
({ viewportId }) => setActiveViewportId(viewportId)
);
return () => subscription.unsubscribe();
}, [viewportId, viewportGridService]);
useEffect(() => {
const handleCineEnable = useCallback(() => {
if (cineService.isViewportCineClosed(activeViewportId)) {
return;
}
@@ -54,6 +50,32 @@ const ActiveViewportBehavior = memo(
customizationService,
]);
useEffect(() => {
const subscription = viewportGridService.subscribe(
viewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED,
({ viewportId }) => setActiveViewportId(viewportId)
);
return () => subscription.unsubscribe();
}, [viewportId, viewportGridService]);
useEffect(() => {
const subscription = cornerstoneViewportService.subscribe(
cornerstoneViewportService.EVENTS.VIEWPORT_DATA_CHANGED,
() => {
const activeViewportId = viewportGridService.getActiveViewportId();
setActiveViewportId(activeViewportId);
handleCineEnable();
}
);
return () => subscription.unsubscribe();
}, [viewportId, cornerstoneViewportService, viewportGridService, handleCineEnable]);
useEffect(() => {
handleCineEnable();
}, [handleCineEnable]);
return null;
},
arePropsEqual