diff --git a/bun.lock b/bun.lock index 1af119a26..7e925753d 100644 --- a/bun.lock +++ b/bun.lock @@ -147,12 +147,12 @@ "version": "3.12.0-beta.75", "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/adapters": "4.5.19", - "@cornerstonejs/ai": "4.5.19", - "@cornerstonejs/core": "4.5.19", - "@cornerstonejs/labelmap-interpolation": "4.5.19", - "@cornerstonejs/polymorphic-segmentation": "4.5.19", - "@cornerstonejs/tools": "4.5.19", + "@cornerstonejs/adapters": "4.5.20", + "@cornerstonejs/ai": "4.5.20", + "@cornerstonejs/core": "4.5.20", + "@cornerstonejs/labelmap-interpolation": "4.5.20", + "@cornerstonejs/polymorphic-segmentation": "4.5.20", + "@cornerstonejs/tools": "4.5.20", "@itk-wasm/morphological-contour-interpolation": "1.1.0", "@kitware/vtk.js": "32.12.0", "html2canvas": "1.4.1", @@ -169,7 +169,7 @@ "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjph": "2.4.7", - "@cornerstonejs/dicom-image-loader": "4.5.19", + "@cornerstonejs/dicom-image-loader": "4.5.20", "@ohif/core": "3.12.0-beta.75", "@ohif/ui": "3.12.0-beta.75", "dcmjs": "0.43.1", @@ -186,8 +186,8 @@ "version": "3.12.0-beta.75", "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/adapters": "4.5.19", - "@cornerstonejs/core": "4.5.19", + "@cornerstonejs/adapters": "4.5.20", + "@cornerstonejs/core": "4.5.20", "@kitware/vtk.js": "32.12.0", "react-color": "2.19.3", }, @@ -229,8 +229,8 @@ "version": "3.12.0-beta.75", "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/adapters": "4.5.19", - "@cornerstonejs/core": "4.5.19", + "@cornerstonejs/adapters": "4.5.20", + "@cornerstonejs/core": "4.5.20", "@kitware/vtk.js": "32.12.0", "react-color": "2.19.3", }, @@ -252,9 +252,9 @@ "version": "3.12.0-beta.75", "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/adapters": "4.5.19", - "@cornerstonejs/core": "4.5.19", - "@cornerstonejs/tools": "4.5.19", + "@cornerstonejs/adapters": "4.5.20", + "@cornerstonejs/core": "4.5.20", + "@cornerstonejs/tools": "4.5.20", "classnames": "2.5.1", }, "peerDependencies": { @@ -274,8 +274,8 @@ "version": "3.12.0-beta.75", "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/core": "4.5.19", - "@cornerstonejs/tools": "4.5.19", + "@cornerstonejs/core": "4.5.20", + "@cornerstonejs/tools": "4.5.20", "classnames": "2.5.1", }, "peerDependencies": { @@ -383,8 +383,8 @@ "xstate": "4.38.3", }, "peerDependencies": { - "@cornerstonejs/core": "4.5.19", - "@cornerstonejs/tools": "4.5.19", + "@cornerstonejs/core": "4.5.20", + "@cornerstonejs/tools": "4.5.20", "@ohif/core": "3.12.0-beta.75", "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.75", "@ohif/extension-default": "3.12.0-beta.75", @@ -438,13 +438,13 @@ "version": "3.12.0-beta.75", "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/core": "4.5.19", - "@cornerstonejs/tools": "4.5.19", + "@cornerstonejs/core": "4.5.20", + "@cornerstonejs/tools": "4.5.20", "@ohif/core": "3.12.0-beta.75", "@ohif/extension-cornerstone": "3.12.0-beta.75", "@ohif/extension-default": "3.12.0-beta.75", "@ohif/i18n": "3.12.0-beta.75", - "@ohif/ui-next": "3.12.0-beta.75", + "@ohif/ui-next": "3.12.0-beta.75" }, "devDependencies": { "@babel/core": "7.28.0", @@ -672,8 +672,8 @@ "version": "3.12.0-beta.75", "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/core": "4.5.19", - "@cornerstonejs/tools": "4.5.19", + "@cornerstonejs/core": "4.5.20", + "@cornerstonejs/tools": "4.5.20", "@ohif/core": "3.12.0-beta.75", "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.75", "@ohif/extension-ultrasound-pleura-bline": "3.12.0-beta.75", @@ -715,7 +715,7 @@ "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjph": "2.4.7", - "@cornerstonejs/dicom-image-loader": "4.5.19", + "@cornerstonejs/dicom-image-loader": "4.5.20", "@emotion/serialize": "1.3.3", "@ohif/core": "3.12.0-beta.75", "@ohif/extension-cornerstone": "3.12.0-beta.75", @@ -836,8 +836,8 @@ "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjph": "2.4.7", - "@cornerstonejs/core": "4.5.19", - "@cornerstonejs/dicom-image-loader": "4.5.19", + "@cornerstonejs/core": "4.5.20", + "@cornerstonejs/dicom-image-loader": "4.5.20", "@ohif/ui": "3.12.0-beta.75", "cornerstone-math": "0.1.9", "dicom-parser": "1.8.21", @@ -1229,9 +1229,9 @@ "@bcoe/v8-coverage": ["@bcoe/v8-coverage@0.2.3", "", {}, "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="], - "@cornerstonejs/adapters": ["@cornerstonejs/adapters@4.5.19", "", { "dependencies": { "@babel/runtime-corejs2": "7.26.10", "buffer": "6.0.3", "dcmjs": "0.43.1", "gl-matrix": "3.4.3", "ndarray": "1.0.19" }, "peerDependencies": { "@cornerstonejs/core": "4.5.19", "@cornerstonejs/tools": "4.5.19" } }, "sha512-9WGR8paIYt4trfaFfwrsNyOoFiBuR4lgeHwokyAUa/3f3goRlKPKtxmSGbF1rH6GDLqUvb00EAHl02G7teGZLQ=="], + "@cornerstonejs/adapters": ["@cornerstonejs/adapters@4.5.20", "", { "dependencies": { "@babel/runtime-corejs2": "7.26.10", "buffer": "6.0.3", "dcmjs": "0.43.1", "gl-matrix": "3.4.3", "ndarray": "1.0.19" }, "peerDependencies": { "@cornerstonejs/core": "4.5.20", "@cornerstonejs/tools": "4.5.20" } }, "sha512-VamRAnlWoNrb4dKx8UfZBgR3mssei88OMoSaNG9V6g+CZUfpMEuZrinTN7ksph0kZ6h8YgIdfDoSzweTpS7cNA=="], - "@cornerstonejs/ai": ["@cornerstonejs/ai@4.5.19", "", { "dependencies": { "@babel/runtime-corejs2": "7.26.10", "buffer": "6.0.3", "dcmjs": "0.43.1", "gl-matrix": "3.4.3", "lodash.clonedeep": "4.5.0", "ndarray": "1.0.19", "onnxruntime-common": "1.17.1", "onnxruntime-web": "1.17.1" }, "peerDependencies": { "@cornerstonejs/core": "4.5.19", "@cornerstonejs/tools": "4.5.19" } }, "sha512-IHZgu7enyOlJPvNhykglwvx3hncEU1OKY417BJviOlvHORDe0baKGJwkvoxdkXVBfk1W4/3/Z8Eo5jB6wWXjDg=="], + "@cornerstonejs/ai": ["@cornerstonejs/ai@4.5.20", "", { "dependencies": { "@babel/runtime-corejs2": "7.26.10", "buffer": "6.0.3", "dcmjs": "0.43.1", "gl-matrix": "3.4.3", "lodash.clonedeep": "4.5.0", "ndarray": "1.0.19", "onnxruntime-common": "1.17.1", "onnxruntime-web": "1.17.1" }, "peerDependencies": { "@cornerstonejs/core": "4.5.20", "@cornerstonejs/tools": "4.5.20" } }, "sha512-M+MumfAzEX2U5r0QRifYvYqH3xBf2qaqPNaMprHuzPG0Xh8NR9E4KvpZWdW8Wn04quTBO8O/nJ+H9deGlY0idA=="], "@cornerstonejs/calculate-suv": ["@cornerstonejs/calculate-suv@1.1.0", "", {}, "sha512-Q9XraiDJif9aMFArD2iEuDO/HXbcRVCqB7KfaHgDrdTTjgDFovS91Psbdim7crypRSvE6dh/+HKeFNHdvNkA6w=="], @@ -1243,15 +1243,15 @@ "@cornerstonejs/codec-openjph": ["@cornerstonejs/codec-openjph@2.4.7", "", {}, "sha512-qvP4q4JDib7mi9r7LqKOwqz7YZ8gjtDX4ZCezeYf8+eb7MBXCz5uXAMeVF3yz9Axw4XiIMdB/pqXkm8tqCl13w=="], - "@cornerstonejs/core": ["@cornerstonejs/core@4.5.19", "", { "dependencies": { "@kitware/vtk.js": "32.12.1", "comlink": "4.4.2", "gl-matrix": "3.4.3", "loglevel": "1.9.2" } }, "sha512-p2uCEgxul1eB5mgy03KYkAaJEtg6ebGIqI/zA7bT7bt6ow8J+LCNpya9YZd4th9KUg0+16qQqhSoVmeTszjZLQ=="], + "@cornerstonejs/core": ["@cornerstonejs/core@4.5.20", "", { "dependencies": { "@kitware/vtk.js": "32.12.1", "comlink": "4.4.2", "gl-matrix": "3.4.3", "loglevel": "1.9.2" } }, "sha512-AWI8GilT9JfCBJywnQwZ5xQZG4EQHujIb4J9VPqyJ/K0ShQ4b7l9kabZ30S6zkimeClntNVVa1Quas7gWPW2LQ=="], - "@cornerstonejs/dicom-image-loader": ["@cornerstonejs/dicom-image-loader@4.5.19", "", { "dependencies": { "@cornerstonejs/codec-charls": "1.2.3", "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-openjpeg": "1.2.4", "@cornerstonejs/codec-openjph": "2.4.7", "comlink": "4.4.2", "dicom-parser": "1.8.21", "jpeg-lossless-decoder-js": "2.1.2", "pako": "2.1.0", "uuid": "9.0.1" }, "peerDependencies": { "@cornerstonejs/core": "4.5.19" } }, "sha512-B4hPQHEsmlUlW70C+uBDhHctPsaCbI0RHOHi5Fhjwal3VQqrSwZ6gU6JT2I6ak7EdL0Lr916LFP5gLMGu6hxPg=="], + "@cornerstonejs/dicom-image-loader": ["@cornerstonejs/dicom-image-loader@4.5.20", "", { "dependencies": { "@cornerstonejs/codec-charls": "1.2.3", "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-openjpeg": "1.2.4", "@cornerstonejs/codec-openjph": "2.4.7", "comlink": "4.4.2", "dicom-parser": "1.8.21", "jpeg-lossless-decoder-js": "2.1.2", "pako": "2.1.0", "uuid": "9.0.1" }, "peerDependencies": { "@cornerstonejs/core": "4.5.20" } }, "sha512-eH4q4ERBlJJsJL9gRWEmCVR96VIxAYV3XIEs9PbRqMs4cfW4AjcupmwuCIbTAVP93LIDXxqN8f2lQXCDjQugjQ=="], - "@cornerstonejs/labelmap-interpolation": ["@cornerstonejs/labelmap-interpolation@4.5.19", "", { "dependencies": { "@itk-wasm/morphological-contour-interpolation": "1.1.0", "itk-wasm": "1.0.0-b.165" }, "peerDependencies": { "@cornerstonejs/core": "4.5.19", "@cornerstonejs/tools": "4.5.19", "@kitware/vtk.js": "32.12.1" } }, "sha512-YxBrrlx4SiBS4Vyswxi271ut97tP/22e67dmuAxROAq28JZslgyQec1bxja+qQlTPCX9CeFxvRTEr4B1T2/IVg=="], + "@cornerstonejs/labelmap-interpolation": ["@cornerstonejs/labelmap-interpolation@4.5.20", "", { "dependencies": { "@itk-wasm/morphological-contour-interpolation": "1.1.0", "itk-wasm": "1.0.0-b.165" }, "peerDependencies": { "@cornerstonejs/core": "4.5.20", "@cornerstonejs/tools": "4.5.20", "@kitware/vtk.js": "32.12.1" } }, "sha512-lbVKXloFJk1HFHtFKLSjbchilnE1bfnM/JYlr16HSvlgb1rPd7GPoZFfrn034oowNEfOLjqJ+C35EaaIjSOxxw=="], - "@cornerstonejs/polymorphic-segmentation": ["@cornerstonejs/polymorphic-segmentation@4.5.19", "", { "dependencies": { "@icr/polyseg-wasm": "0.4.0" }, "peerDependencies": { "@cornerstonejs/core": "4.5.19", "@cornerstonejs/tools": "4.5.19", "@kitware/vtk.js": "32.12.1" } }, "sha512-v/o+qQDHH4wKec9/adZQAX1j1MLYgqg0U5iHECK46Cn9NEPB0yK3bPPhiQLGPEUUMm202ETOynBnFtvHnpki3A=="], + "@cornerstonejs/polymorphic-segmentation": ["@cornerstonejs/polymorphic-segmentation@4.5.20", "", { "dependencies": { "@icr/polyseg-wasm": "0.4.0" }, "peerDependencies": { "@cornerstonejs/core": "4.5.20", "@cornerstonejs/tools": "4.5.20", "@kitware/vtk.js": "32.12.1" } }, "sha512-s4es71KDzsrMPchGm5B3lERIF/M+OHMtFZbXAzGcZ8KnZZkmX1j1G6vxakcW8IjXL4knkDuSkZxevFXWIKyMoA=="], - "@cornerstonejs/tools": ["@cornerstonejs/tools@4.5.19", "", { "dependencies": { "@types/offscreencanvas": "2019.7.3", "comlink": "4.4.2", "lodash.get": "4.4.2" }, "peerDependencies": { "@cornerstonejs/core": "4.5.19", "@kitware/vtk.js": "32.12.1", "@types/d3-array": "3.2.1", "@types/d3-interpolate": "3.0.4", "d3-array": "3.2.4", "d3-interpolate": "3.0.1", "gl-matrix": "3.4.3" } }, "sha512-XDb4ffPy/FmgSAClnlA563+D1PI3onqnRQ5XBrOIF4Mc7/2x34t/5LBCqixVb2yZ39W9M4BVuDM/VbHiIqE5kQ=="], + "@cornerstonejs/tools": ["@cornerstonejs/tools@4.5.20", "", { "dependencies": { "@types/offscreencanvas": "2019.7.3", "comlink": "4.4.2", "lodash.get": "4.4.2" }, "peerDependencies": { "@cornerstonejs/core": "4.5.20", "@kitware/vtk.js": "32.12.1", "@types/d3-array": "3.2.1", "@types/d3-interpolate": "3.0.4", "d3-array": "3.2.4", "d3-interpolate": "3.0.1", "gl-matrix": "3.4.3" } }, "sha512-FY2sxm7vPiCI1Vm1JsHeIYMi45686V8/RkRa47XDt/035B/v36pr81pyE9nl/jb7FJiHfzSyDeROJ8YoPVe9qQ=="], "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="], diff --git a/extensions/cornerstone-dicom-pmap/package.json b/extensions/cornerstone-dicom-pmap/package.json index d75f5d70f..8669954e5 100644 --- a/extensions/cornerstone-dicom-pmap/package.json +++ b/extensions/cornerstone-dicom-pmap/package.json @@ -46,8 +46,8 @@ }, "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/adapters": "4.5.19", - "@cornerstonejs/core": "4.5.19", + "@cornerstonejs/adapters": "4.5.20", + "@cornerstonejs/core": "4.5.20", "@kitware/vtk.js": "32.12.0", "react-color": "2.19.3" } diff --git a/extensions/cornerstone-dicom-seg/package.json b/extensions/cornerstone-dicom-seg/package.json index 1bd3202b4..22bc64a89 100644 --- a/extensions/cornerstone-dicom-seg/package.json +++ b/extensions/cornerstone-dicom-seg/package.json @@ -46,8 +46,8 @@ }, "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/adapters": "4.5.19", - "@cornerstonejs/core": "4.5.19", + "@cornerstonejs/adapters": "4.5.20", + "@cornerstonejs/core": "4.5.20", "@kitware/vtk.js": "32.12.0", "react-color": "2.19.3" } diff --git a/extensions/cornerstone-dicom-sr/package.json b/extensions/cornerstone-dicom-sr/package.json index 9ec1f9146..1efb3519b 100644 --- a/extensions/cornerstone-dicom-sr/package.json +++ b/extensions/cornerstone-dicom-sr/package.json @@ -46,9 +46,9 @@ }, "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/adapters": "4.5.19", - "@cornerstonejs/core": "4.5.19", - "@cornerstonejs/tools": "4.5.19", + "@cornerstonejs/adapters": "4.5.20", + "@cornerstonejs/core": "4.5.20", + "@cornerstonejs/tools": "4.5.20", "classnames": "2.5.1" } } diff --git a/extensions/cornerstone-dynamic-volume/package.json b/extensions/cornerstone-dynamic-volume/package.json index 64e0a6911..4318f4b05 100644 --- a/extensions/cornerstone-dynamic-volume/package.json +++ b/extensions/cornerstone-dynamic-volume/package.json @@ -42,8 +42,8 @@ }, "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/core": "4.5.19", - "@cornerstonejs/tools": "4.5.19", + "@cornerstonejs/core": "4.5.20", + "@cornerstonejs/tools": "4.5.20", "classnames": "2.5.1" } } diff --git a/extensions/cornerstone/package.json b/extensions/cornerstone/package.json index 95541f108..d65fec8ee 100644 --- a/extensions/cornerstone/package.json +++ b/extensions/cornerstone/package.json @@ -40,7 +40,7 @@ "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjph": "2.4.7", - "@cornerstonejs/dicom-image-loader": "4.5.19", + "@cornerstonejs/dicom-image-loader": "4.5.20", "@ohif/core": "3.12.0-beta.76", "@ohif/ui": "3.12.0-beta.76", "dcmjs": "0.43.1", @@ -53,12 +53,12 @@ }, "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/adapters": "4.5.19", - "@cornerstonejs/ai": "4.5.19", - "@cornerstonejs/core": "4.5.19", - "@cornerstonejs/labelmap-interpolation": "4.5.19", - "@cornerstonejs/polymorphic-segmentation": "4.5.19", - "@cornerstonejs/tools": "4.5.19", + "@cornerstonejs/adapters": "4.5.20", + "@cornerstonejs/ai": "4.5.20", + "@cornerstonejs/core": "4.5.20", + "@cornerstonejs/labelmap-interpolation": "4.5.20", + "@cornerstonejs/polymorphic-segmentation": "4.5.20", + "@cornerstonejs/tools": "4.5.20", "@itk-wasm/morphological-contour-interpolation": "1.1.0", "@kitware/vtk.js": "32.12.0", "html2canvas": "1.4.1", diff --git a/extensions/cornerstone/src/commandsModule.ts b/extensions/cornerstone/src/commandsModule.ts index 5c45dc5b9..5006535d1 100644 --- a/extensions/cornerstone/src/commandsModule.ts +++ b/extensions/cornerstone/src/commandsModule.ts @@ -236,16 +236,28 @@ function commandsModule({ return; } + const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId); + + if (!viewport) { + return; + } + if (displaySet.isOverlayDisplaySet) { // update the previously stored segmentationPresentation with the new viewportId // presentation so that when we put the referencedDisplaySet back in the viewport // it will have the correct segmentation representation hydrated + + const segmentationType = + // Todo: check if PMAP modality should be handled such as SEG + displaySet.Modality !== 'SEG' + ? SegmentationRepresentations.Contour + : viewport.type === CoreEnums.ViewportType.VOLUME_3D + ? SegmentationRepresentations.Surface + : SegmentationRepresentations.Labelmap; + commandsManager.runCommand('updateStoredSegmentationPresentation', { displaySet, - type: - displaySet.Modality === 'SEG' - ? SegmentationRepresentations.Labelmap - : SegmentationRepresentations.Contour, + type: segmentationType, }); } diff --git a/extensions/cornerstone/src/hooks/useViewportRendering.tsx b/extensions/cornerstone/src/hooks/useViewportRendering.tsx index 49af2299e..08538623e 100644 --- a/extensions/cornerstone/src/hooks/useViewportRendering.tsx +++ b/extensions/cornerstone/src/hooks/useViewportRendering.tsx @@ -682,7 +682,7 @@ export function useViewportRendering( const actorEntries = viewport.getActors(); const actorEntry = actorEntries?.find(entry => - entry.referencedId.includes(activeDisplaySetInstanceUID) + entry.referencedId?.includes(activeDisplaySetInstanceUID) ); if (!actorEntry) { diff --git a/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts b/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts index 319817ee9..42ea9b2e3 100644 --- a/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts +++ b/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts @@ -714,7 +714,7 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi // is being used to navigate to the initial view position for measurement // navigation and other navigation forcing specific views. let initialImageIndexToUse = - presentations?.positionPresentation?.initialImageIndex ?? initialImageIndex; + presentations?.positionPresentation?.initialImageIndex ?? (initialImageIndex as number); const { rotation, flipHorizontal, displayArea } = viewportInfo.getViewportOptions(); @@ -933,6 +933,10 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi const displaySet = displaySetService.getDisplaySetByUID(displaySetUIDs[0]); const displaySetModality = displaySet?.Modality; + // seems like a hack but we need the actor to be ready first before + // we set the properties + const timeoutViewportCallback = (callback: () => void) => setTimeout(callback, 0); + // filter overlay display sets (e.g. segmentation) since they will get handled below via the segmentation service const filteredVolumeInputArray = volumeInputArray .map((volumeInput, index) => { @@ -984,12 +988,21 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi const backgroundDisplaySet = displaySetService.getDisplaySetsBy( displaySet => !displaySet.isOverlayDisplaySet && - displaySet.images.some(image => image.imageId === sampleImageId) + displaySet.images?.some(image => image.imageId === sampleImageId) ); if (backgroundDisplaySet.length !== 1) { throw new Error('Background display set not found'); } + + if (viewport.type === csEnums.ViewportType.VOLUME_3D) { + timeoutViewportCallback(() => { + viewportGridService.setDisplaySetsForViewport({ + viewportId: viewport.id, + displaySetInstanceUIDs: [backgroundDisplaySet[0].displaySetInstanceUID], + }); + }); + } } }); } @@ -1006,15 +1019,13 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi viewport.render(); volumesProperties.forEach(({ properties, volumeId }) => { - setTimeout(() => { - // seems like a hack but we need the actor to be ready first before - // we set the properties + timeoutViewportCallback(() => { viewport.setProperties(properties, volumeId); viewport.render(); - }, 0); + }); }); - this.setPresentations(viewport.id, presentations, viewportInfo); + this.setPresentations(viewport.id, presentations); if (!presentations.positionPresentation) { const imageIndex = this._getInitialImageIndexForViewport(viewportInfo); diff --git a/extensions/cornerstone/src/utils/hydrationUtils.test.ts b/extensions/cornerstone/src/utils/hydrationUtils.test.ts index e961d8676..abf52ac19 100644 --- a/extensions/cornerstone/src/utils/hydrationUtils.test.ts +++ b/extensions/cornerstone/src/utils/hydrationUtils.test.ts @@ -70,43 +70,6 @@ describe('getUpdatedViewportsForSegmentation', () => { expect(result).toEqual(mockUpdatedViewports); }); - it('should filter out volume3d viewports', () => { - const mockUpdatedViewports = [ - { - viewportOptions: { - viewportType: 'stack', - }, - }, - { - viewportOptions: { - viewportType: 'volume3d', - }, - }, - { - viewportOptions: { - viewportType: 'volume', - }, - }, - ]; - - mockHangingProtocolService.getViewportsRequireUpdate.mockReturnValue(mockUpdatedViewports); - - const result = getUpdatedViewportsForSegmentation(defaultParameters); - - expect(result).toEqual([ - { - viewportOptions: { - viewportType: 'stack', - }, - }, - { - viewportOptions: { - viewportType: 'volume', - }, - }, - ]); - }); - it('should handle viewports without viewportOptions', () => { const mockUpdatedViewports = [ { @@ -255,70 +218,22 @@ describe('getUpdatedViewportsForSegmentation', () => { it('should handle getViewportsRequireUpdate returning null', () => { mockHangingProtocolService.getViewportsRequireUpdate.mockReturnValue(null); - expect(() => getUpdatedViewportsForSegmentation(defaultParameters)).toThrow(); + expect(getUpdatedViewportsForSegmentation(defaultParameters)).toEqual(null); }); it('should handle mixed viewport types including volume3d', () => { const mockUpdatedViewports = [ - { - viewportOptions: { - viewportType: 'stack', - }, - }, - { - viewportOptions: { - viewportType: 'volume3d', - }, - }, - { - viewportOptions: { - viewportType: 'volume3d', - }, - }, - { - viewportOptions: { - viewportType: 'orthogonal', - }, - }, + { viewportOptions: { viewportType: 'stack' } }, + { viewportOptions: { viewportType: 'volume3d' } }, + { viewportOptions: { viewportType: 'volume3d' } }, + { viewportOptions: { viewportType: 'orthogonal' } }, ]; mockHangingProtocolService.getViewportsRequireUpdate.mockReturnValue(mockUpdatedViewports); const result = getUpdatedViewportsForSegmentation(defaultParameters); - expect(result).toEqual([ - { - viewportOptions: { - viewportType: 'stack', - }, - }, - { - viewportOptions: { - viewportType: 'orthogonal', - }, - }, - ]); - }); - - it('should handle all volume3d viewports', () => { - const mockUpdatedViewports = [ - { - viewportOptions: { - viewportType: 'volume3d', - }, - }, - { - viewportOptions: { - viewportType: 'volume3d', - }, - }, - ]; - - mockHangingProtocolService.getViewportsRequireUpdate.mockReturnValue(mockUpdatedViewports); - - const result = getUpdatedViewportsForSegmentation(defaultParameters); - - expect(result).toEqual([]); + expect(result).toEqual(mockUpdatedViewports); }); it('should handle viewports with undefined viewportType', () => { @@ -328,6 +243,11 @@ describe('getUpdatedViewportsForSegmentation', () => { viewportType: undefined, }, }, + { + viewportOptions: { + viewportType: 'volume3d', + }, + }, { viewportOptions: { someOtherProperty: 'value', diff --git a/extensions/cornerstone/src/utils/hydrationUtils.ts b/extensions/cornerstone/src/utils/hydrationUtils.ts index fd5f6120b..c1a9715b2 100644 --- a/extensions/cornerstone/src/utils/hydrationUtils.ts +++ b/extensions/cornerstone/src/utils/hydrationUtils.ts @@ -16,7 +16,7 @@ function getUpdatedViewportsForSegmentation({ isHangingProtocolLayout ); - return updatedViewports.filter(v => v.viewportOptions?.viewportType !== 'volume3d'); + return updatedViewports; } const getTargetViewport = ({ viewportId, viewportGridService }) => { diff --git a/extensions/cornerstone/src/utils/interleaveCenterLoader.ts b/extensions/cornerstone/src/utils/interleaveCenterLoader.ts index 413a6a843..b31ed5927 100644 --- a/extensions/cornerstone/src/utils/interleaveCenterLoader.ts +++ b/extensions/cornerstone/src/utils/interleaveCenterLoader.ts @@ -84,7 +84,7 @@ export default function interleaveCenterLoader({ // the imageIds and save them in AllRequests for later use const AllRequests = []; volumes.forEach(volume => { - const requests = volume.getImageLoadRequests(); + const requests = volume.getImageLoadRequests?.() ?? []; if (!requests.length || !requests[0] || !requests[0].imageId) { return; diff --git a/extensions/cornerstone/src/utils/interleaveTopToBottom.ts b/extensions/cornerstone/src/utils/interleaveTopToBottom.ts index 72078d4f8..419f734a1 100644 --- a/extensions/cornerstone/src/utils/interleaveTopToBottom.ts +++ b/extensions/cornerstone/src/utils/interleaveTopToBottom.ts @@ -83,7 +83,7 @@ export default function interleaveTopToBottom({ // the imageIds and save them in AllRequests for later use const AllRequests = []; volumes.forEach(volume => { - const requests = volume.getImageLoadRequests(); + const requests = volume.getImageLoadRequests?.() ?? []; if (!requests?.[0]?.imageId) { return; diff --git a/extensions/cornerstone/src/utils/transitions.test.ts b/extensions/cornerstone/src/utils/transitions.test.ts index c86efcdf3..65e5a1f61 100644 --- a/extensions/cornerstone/src/utils/transitions.test.ts +++ b/extensions/cornerstone/src/utils/transitions.test.ts @@ -348,20 +348,4 @@ describe('Transitions Module', () => { }); }); }); - - describe('Performance Validation', () => { - it('should handle many rapid calls without issues', () => { - const startTime = performance.now(); - - for (let i = 0; i < 1000; i++) { - const t = i / 1000; - linear(t); - easeInOut(t, 0.1); - ease(t, 0.2, 1.5); - } - - const endTime = performance.now(); - expect(endTime - startTime).toBeLessThan(10); - }); - }); }); diff --git a/extensions/measurement-tracking/package.json b/extensions/measurement-tracking/package.json index f03b8affd..93fb1424e 100644 --- a/extensions/measurement-tracking/package.json +++ b/extensions/measurement-tracking/package.json @@ -32,8 +32,8 @@ "start": "yarn run dev" }, "peerDependencies": { - "@cornerstonejs/core": "4.5.19", - "@cornerstonejs/tools": "4.5.19", + "@cornerstonejs/core": "4.5.20", + "@cornerstonejs/tools": "4.5.20", "@ohif/core": "3.12.0-beta.76", "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.76", "@ohif/extension-default": "3.12.0-beta.76", diff --git a/extensions/usAnnotation/package.json b/extensions/usAnnotation/package.json index 988f938b4..2cee5db7e 100644 --- a/extensions/usAnnotation/package.json +++ b/extensions/usAnnotation/package.json @@ -42,8 +42,8 @@ }, "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/core": "4.5.19", - "@cornerstonejs/tools": "4.5.19", + "@cornerstonejs/core": "4.5.20", + "@cornerstonejs/tools": "4.5.20", "@ohif/core": "3.12.0-beta.76", "@ohif/extension-cornerstone": "3.12.0-beta.76", "@ohif/extension-default": "3.12.0-beta.76", diff --git a/modes/usAnnotation/package.json b/modes/usAnnotation/package.json index 0741817cf..afd185765 100644 --- a/modes/usAnnotation/package.json +++ b/modes/usAnnotation/package.json @@ -34,8 +34,8 @@ }, "dependencies": { "@babel/runtime": "7.28.2", - "@cornerstonejs/core": "4.5.19", - "@cornerstonejs/tools": "4.5.19", + "@cornerstonejs/core": "4.5.20", + "@cornerstonejs/tools": "4.5.20", "@ohif/core": "3.12.0-beta.76", "@ohif/extension-cornerstone-dicom-sr": "3.12.0-beta.76", "@ohif/extension-ultrasound-pleura-bline": "3.12.0-beta.76", diff --git a/platform/app/package.json b/platform/app/package.json index 21d359c51..81d9e42c2 100644 --- a/platform/app/package.json +++ b/platform/app/package.json @@ -53,7 +53,7 @@ "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjph": "2.4.7", - "@cornerstonejs/dicom-image-loader": "4.5.19", + "@cornerstonejs/dicom-image-loader": "4.5.20", "@emotion/serialize": "1.3.3", "@ohif/core": "3.12.0-beta.76", "@ohif/extension-cornerstone": "3.12.0-beta.76", diff --git a/platform/core/package.json b/platform/core/package.json index 52923fe09..b7204d76e 100644 --- a/platform/core/package.json +++ b/platform/core/package.json @@ -37,8 +37,8 @@ "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjph": "2.4.7", - "@cornerstonejs/core": "4.5.19", - "@cornerstonejs/dicom-image-loader": "4.5.19", + "@cornerstonejs/core": "4.5.20", + "@cornerstonejs/dicom-image-loader": "4.5.20", "@ohif/ui": "3.12.0-beta.76", "cornerstone-math": "0.1.9", "dicom-parser": "1.8.21" diff --git a/tests/SEGHydrationFrom3DFourUp.spec.ts b/tests/SEGHydrationFrom3DFourUp.spec.ts new file mode 100644 index 000000000..b604350f6 --- /dev/null +++ b/tests/SEGHydrationFrom3DFourUp.spec.ts @@ -0,0 +1,49 @@ +import { test } from 'playwright-test-coverage'; +import { + visitStudy, + checkForScreenshot, + screenShotPaths, + reduce3DViewportSize, + attemptAction, +} from './utils'; + +test.beforeEach(async ({ page }) => { + const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.1706.8374.643249677828306008300337414785'; + const mode = 'viewer'; + await visitStudy(page, studyInstanceUID, mode, 2000); +}); + +test.describe('3D four up SEG hydration', async () => { + test('should properly hydrate SEG from 3D four up layout', async ({ page }) => { + await page.getByTestId('Layout').click(); + await page.getByTestId('3D four up').click(); + + await attemptAction(() => reduce3DViewportSize(page), 10, 100); + + await page.waitForTimeout(5000); + + await checkForScreenshot( + page, + page, + screenShotPaths.segHydrationFrom3DFourUp.threeDFourUpBeforeSEG + ); + + await page.getByTestId('study-browser-thumbnail-no-image').dblclick(); + + await page.waitForTimeout(5000); + await checkForScreenshot( + page, + page, + screenShotPaths.segHydrationFrom3DFourUp.threeDFourUpAfterSEG + ); + + await page.getByTestId('yes-hydrate-btn').click(); + + await page.waitForTimeout(5000); + await checkForScreenshot( + page, + page, + screenShotPaths.segHydrationFrom3DFourUp.threeDFourUpAfterSegHydrated + ); + }); +}); diff --git a/tests/screenshots/chromium/SEGHydrationFrom3DFourUp.spec.ts/threeDFourUpAfterSEG.png b/tests/screenshots/chromium/SEGHydrationFrom3DFourUp.spec.ts/threeDFourUpAfterSEG.png new file mode 100644 index 000000000..d38d4d663 Binary files /dev/null and b/tests/screenshots/chromium/SEGHydrationFrom3DFourUp.spec.ts/threeDFourUpAfterSEG.png differ diff --git a/tests/screenshots/chromium/SEGHydrationFrom3DFourUp.spec.ts/threeDFourUpAfterSegHydrated.png b/tests/screenshots/chromium/SEGHydrationFrom3DFourUp.spec.ts/threeDFourUpAfterSegHydrated.png new file mode 100644 index 000000000..2fd58ecf4 Binary files /dev/null and b/tests/screenshots/chromium/SEGHydrationFrom3DFourUp.spec.ts/threeDFourUpAfterSegHydrated.png differ diff --git a/tests/screenshots/chromium/SEGHydrationFrom3DFourUp.spec.ts/threeDFourUpBeforeSEG.png b/tests/screenshots/chromium/SEGHydrationFrom3DFourUp.spec.ts/threeDFourUpBeforeSEG.png new file mode 100644 index 000000000..eeb5727c2 Binary files /dev/null and b/tests/screenshots/chromium/SEGHydrationFrom3DFourUp.spec.ts/threeDFourUpBeforeSEG.png differ diff --git a/tests/utils/screenShotPaths.ts b/tests/utils/screenShotPaths.ts index 5c005d468..82b395e56 100644 --- a/tests/utils/screenShotPaths.ts +++ b/tests/utils/screenShotPaths.ts @@ -127,6 +127,11 @@ const screenShotPaths = { mprAfterSegHydrated: 'mprAfterSegHydrated.png', mprAfterSegHydratedAfterLayoutChange: 'mprAfterSegHydratedAfterLayoutChange.png', }, + segHydrationFrom3DFourUp: { + threeDFourUpBeforeSEG: 'threeDFourUpBeforeSEG.png', + threeDFourUpAfterSEG: 'threeDFourUpAfterSEG.png', + threeDFourUpAfterSegHydrated: 'threeDFourUpAfterSegHydrated.png', + }, segNoHydrationThenMPR: { segNoHydrationPreMPR: 'segNoHydrationPreMpr.png', segNoHydrationPostMPR: 'segNoHydrationPostMpr.png', diff --git a/yarn.lock b/yarn.lock index eeb8c2de4..7d86dc202 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1280,10 +1280,10 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@cornerstonejs/adapters@4.5.19": - version "4.5.19" - resolved "https://registry.yarnpkg.com/@cornerstonejs/adapters/-/adapters-4.5.19.tgz#706fd90e59d54762b319b97ea582de2b2ba0f0f9" - integrity sha512-9WGR8paIYt4trfaFfwrsNyOoFiBuR4lgeHwokyAUa/3f3goRlKPKtxmSGbF1rH6GDLqUvb00EAHl02G7teGZLQ== +"@cornerstonejs/adapters@4.5.20": + version "4.5.20" + resolved "https://registry.yarnpkg.com/@cornerstonejs/adapters/-/adapters-4.5.20.tgz#3ed39349f8843babf7fbe56b40eb7b0264894780" + integrity sha512-VamRAnlWoNrb4dKx8UfZBgR3mssei88OMoSaNG9V6g+CZUfpMEuZrinTN7ksph0kZ6h8YgIdfDoSzweTpS7cNA== dependencies: "@babel/runtime-corejs2" "7.26.10" buffer "6.0.3" @@ -1291,10 +1291,10 @@ gl-matrix "3.4.3" ndarray "1.0.19" -"@cornerstonejs/ai@4.5.19": - version "4.5.19" - resolved "https://registry.yarnpkg.com/@cornerstonejs/ai/-/ai-4.5.19.tgz#db5a1ad4dd6b5742029289cc33a633f832774869" - integrity sha512-IHZgu7enyOlJPvNhykglwvx3hncEU1OKY417BJviOlvHORDe0baKGJwkvoxdkXVBfk1W4/3/Z8Eo5jB6wWXjDg== +"@cornerstonejs/ai@4.5.20": + version "4.5.20" + resolved "https://registry.yarnpkg.com/@cornerstonejs/ai/-/ai-4.5.20.tgz#69fde3dc9a61f115cfa4cc2d0dcfa5841ed1113d" + integrity sha512-M+MumfAzEX2U5r0QRifYvYqH3xBf2qaqPNaMprHuzPG0Xh8NR9E4KvpZWdW8Wn04quTBO8O/nJ+H9deGlY0idA== dependencies: "@babel/runtime-corejs2" "7.26.10" buffer "6.0.3" @@ -1330,20 +1330,20 @@ resolved "https://registry.yarnpkg.com/@cornerstonejs/codec-openjph/-/codec-openjph-2.4.7.tgz#784394d05d8cf735640e9c3baa206535ee8e0376" integrity sha512-qvP4q4JDib7mi9r7LqKOwqz7YZ8gjtDX4ZCezeYf8+eb7MBXCz5uXAMeVF3yz9Axw4XiIMdB/pqXkm8tqCl13w== -"@cornerstonejs/core@4.5.19": - version "4.5.19" - resolved "https://registry.yarnpkg.com/@cornerstonejs/core/-/core-4.5.19.tgz#4fbde277b97a80de1b2612e8eacf8f15c3d777db" - integrity sha512-p2uCEgxul1eB5mgy03KYkAaJEtg6ebGIqI/zA7bT7bt6ow8J+LCNpya9YZd4th9KUg0+16qQqhSoVmeTszjZLQ== +"@cornerstonejs/core@4.5.20": + version "4.5.20" + resolved "https://registry.yarnpkg.com/@cornerstonejs/core/-/core-4.5.20.tgz#02c89300bf32629ecc5e3deb9053f5ec4118f9f8" + integrity sha512-AWI8GilT9JfCBJywnQwZ5xQZG4EQHujIb4J9VPqyJ/K0ShQ4b7l9kabZ30S6zkimeClntNVVa1Quas7gWPW2LQ== dependencies: "@kitware/vtk.js" "32.12.1" comlink "4.4.2" gl-matrix "3.4.3" loglevel "1.9.2" -"@cornerstonejs/dicom-image-loader@4.5.19": - version "4.5.19" - resolved "https://registry.yarnpkg.com/@cornerstonejs/dicom-image-loader/-/dicom-image-loader-4.5.19.tgz#2678daf66a479ae53504c9d21d02ab1af53b87ee" - integrity sha512-B4hPQHEsmlUlW70C+uBDhHctPsaCbI0RHOHi5Fhjwal3VQqrSwZ6gU6JT2I6ak7EdL0Lr916LFP5gLMGu6hxPg== +"@cornerstonejs/dicom-image-loader@4.5.20": + version "4.5.20" + resolved "https://registry.yarnpkg.com/@cornerstonejs/dicom-image-loader/-/dicom-image-loader-4.5.20.tgz#be0e640fc546512bda8d43bd6276a666f3de5dda" + integrity sha512-eH4q4ERBlJJsJL9gRWEmCVR96VIxAYV3XIEs9PbRqMs4cfW4AjcupmwuCIbTAVP93LIDXxqN8f2lQXCDjQugjQ== dependencies: "@cornerstonejs/codec-charls" "1.2.3" "@cornerstonejs/codec-libjpeg-turbo-8bit" "1.2.2" @@ -1355,25 +1355,25 @@ pako "2.1.0" uuid "9.0.1" -"@cornerstonejs/labelmap-interpolation@4.5.19": - version "4.5.19" - resolved "https://registry.yarnpkg.com/@cornerstonejs/labelmap-interpolation/-/labelmap-interpolation-4.5.19.tgz#f6f3152f8e74af2400d2f2cef2d846e96bafc30a" - integrity sha512-YxBrrlx4SiBS4Vyswxi271ut97tP/22e67dmuAxROAq28JZslgyQec1bxja+qQlTPCX9CeFxvRTEr4B1T2/IVg== +"@cornerstonejs/labelmap-interpolation@4.5.20": + version "4.5.20" + resolved "https://registry.yarnpkg.com/@cornerstonejs/labelmap-interpolation/-/labelmap-interpolation-4.5.20.tgz#e8962f04bc566175369a7cd78c685cc2c2df488b" + integrity sha512-lbVKXloFJk1HFHtFKLSjbchilnE1bfnM/JYlr16HSvlgb1rPd7GPoZFfrn034oowNEfOLjqJ+C35EaaIjSOxxw== dependencies: "@itk-wasm/morphological-contour-interpolation" "1.1.0" itk-wasm "1.0.0-b.165" -"@cornerstonejs/polymorphic-segmentation@4.5.19": - version "4.5.19" - resolved "https://registry.yarnpkg.com/@cornerstonejs/polymorphic-segmentation/-/polymorphic-segmentation-4.5.19.tgz#3e059ef21a339f2ee2bec231e86e32148dbad00a" - integrity sha512-v/o+qQDHH4wKec9/adZQAX1j1MLYgqg0U5iHECK46Cn9NEPB0yK3bPPhiQLGPEUUMm202ETOynBnFtvHnpki3A== +"@cornerstonejs/polymorphic-segmentation@4.5.20": + version "4.5.20" + resolved "https://registry.yarnpkg.com/@cornerstonejs/polymorphic-segmentation/-/polymorphic-segmentation-4.5.20.tgz#8fb0eec12f51457c140f93343f94ba870d0fe10c" + integrity sha512-s4es71KDzsrMPchGm5B3lERIF/M+OHMtFZbXAzGcZ8KnZZkmX1j1G6vxakcW8IjXL4knkDuSkZxevFXWIKyMoA== dependencies: "@icr/polyseg-wasm" "0.4.0" -"@cornerstonejs/tools@4.5.19": - version "4.5.19" - resolved "https://registry.yarnpkg.com/@cornerstonejs/tools/-/tools-4.5.19.tgz#c77f4516d6311fe64a5830332d4c4729083458fa" - integrity sha512-XDb4ffPy/FmgSAClnlA563+D1PI3onqnRQ5XBrOIF4Mc7/2x34t/5LBCqixVb2yZ39W9M4BVuDM/VbHiIqE5kQ== +"@cornerstonejs/tools@4.5.20": + version "4.5.20" + resolved "https://registry.yarnpkg.com/@cornerstonejs/tools/-/tools-4.5.20.tgz#4e6f2d0dc2ecbee84b1d2d3108abaf9081b2c1f6" + integrity sha512-FY2sxm7vPiCI1Vm1JsHeIYMi45686V8/RkRa47XDt/035B/v36pr81pyE9nl/jb7FJiHfzSyDeROJ8YoPVe9qQ== dependencies: "@types/offscreencanvas" "2019.7.3" comlink "4.4.2"