From 792f463f9f1065af3a68df7cfde4259f1476f2f7 Mon Sep 17 00:00:00 2001 From: Ross Date: Tue, 20 May 2025 17:12:50 +0100 Subject: [PATCH] pre refactor to same rendering engine --- dicom-viewer/src/App.tsx | 118 +++++++++++++++++++++++---------------- 1 file changed, 71 insertions(+), 47 deletions(-) diff --git a/dicom-viewer/src/App.tsx b/dicom-viewer/src/App.tsx index 360eb42..115f724 100644 --- a/dicom-viewer/src/App.tsx +++ b/dicom-viewer/src/App.tsx @@ -11,6 +11,7 @@ import { init as dicomImageLoaderInit } from "@cornerstonejs/dicom-image-loader" import * as cornerstoneTools from '@cornerstonejs/tools'; import { StackScrollOutOfBoundsEvent } from 'core/src/types/EventTypes'; import { segmentation, Enums as csEnums } from '@cornerstonejs/tools'; +import { voi } from "@cornerstonejs/tools/utilities" const { MouseBindings, KeyboardBindings } = csToolsEnums; @@ -83,6 +84,10 @@ function App() { const viewportRefs = useRef>([]) const renderingEnginesRef = useRef>({}); + // Store the properties and scroll position of existing viewports before grid change + const prevViewportProps = useRef>({}); + const prevScrollIndices = useRef>({}); + // Helper to generate grid options const gridOptions = [] for (let rows = 1; rows <= 3; rows++) { @@ -219,27 +224,27 @@ function App() { }); }, []); - // Store the properties of existing viewports before grid change - const prevViewportProps = useRef>({}); - useEffect(() => { const setup = async () => { - // 1. Capture state of existing viewports before grid change - for (let i = 0; i < viewportGrid.rows * viewportGrid.cols; i++) { - const renderingEngineId = `renderingEngine_${i}`; - const viewportId = `CT_${i}`; - try { - const renderingEngine = renderingEnginesRef.current[renderingEngineId]; - if (renderingEngine) { - const viewport = renderingEngine.getViewport(viewportId); - if (viewport && typeof viewport.getProperties === "function") { - prevViewportProps.current[i] = viewport.getProperties(); - } + // 1. Save properties and scroll position for only the existing viewports + const prevCount = Object.keys(renderingEnginesRef.current).length; + for (let i = 0; i < prevCount; i++) { + const renderingEngineId = `renderingEngine_${i}`; + const viewportId = `CT_${i}`; + const renderingEngine = renderingEnginesRef.current[renderingEngineId]; + if (renderingEngine) { + const viewport = renderingEngine.getViewport(viewportId); + if (viewport) { + if (typeof viewport.getProperties === "function") { + console.log("Saving previous state for viewport", i, viewport.getProperties()) + prevViewportProps.current[i] = viewport.getProperties(); + } + if (typeof viewport.getCurrentImageIdIndex === "function") { + prevScrollIndices.current[i] = viewport.getCurrentImageIdIndex(); } - } catch (e) { - // Ignore if not found } } + } if (running.current) { if (loadedImageIds) { @@ -249,8 +254,11 @@ function App() { const element = viewportRefs.current[i]; if (!element) continue; - const renderingEngine = new RenderingEngine(renderingEngineId); - renderingEnginesRef.current[renderingEngineId] = renderingEngine; + let renderingEngine = renderingEnginesRef.current[renderingEngineId]; + if (!renderingEngine) { + renderingEngine = new RenderingEngine(renderingEngineId); + renderingEnginesRef.current[renderingEngineId] = renderingEngine; + } const viewportInput = { viewportId, type: Enums.ViewportType.STACK, @@ -264,32 +272,34 @@ function App() { const viewport = renderingEngine.getViewport(viewportId); viewport.setStack(loadedImageIds); -/* // Restore previous state for existing viewports only - if (prevViewportProps.current[i] && typeof viewport.setProperties === "function") { - viewport.setProperties(prevViewportProps.current[i]); - } */ + + renderingEngine.resize(true, true) cornerstoneTools.utilities.stackPrefetch.enable(viewport.element); - renderingEngine.resize(true, true) - console.log(i, viewport) + viewport.resize(); viewport.render(); + // Restore previous state for existing viewports only + if (prevViewportProps.current[i] && typeof viewport.setProperties === "function") { + console.log("Restoring properties for viewport", i, prevViewportProps.current[i]) + console.log(viewport) + viewport.setProperties(prevViewportProps.current[i]); + } + // Restore previous scroll position for existing viewports only + if ( + prevScrollIndices.current[i] !== undefined && + typeof viewport.setImageIdIndex === "function" + ) { + viewport.setImageIdIndex(prevScrollIndices.current[i]); + } + + updateOverlay(i, viewport); + // Attach overlay update for each viewport viewport.element.addEventListener(Enums.Events.IMAGE_RENDERED, () => updateOverlay(i, viewport)); // Initial overlay update updateOverlay(i, viewport); } - - /* // Resize and render all viewports to ensure correct canvas size - for (let i = 0; i < viewportGrid.rows * viewportGrid.cols; i++) { - const renderingEngineId = `renderingEngine_${i}`; - const viewportId = `CT_${i}`; - const renderingEngine = renderingEnginesRef.current[renderingEngineId]; - if (renderingEngine) { - const viewport = renderingEngine.getViewport(viewportId); - renderingEngine.resize(true, false) - } - } */ applyMouseToolBindings(); return; } @@ -325,14 +335,31 @@ function App() { const viewport = renderingEngine.getViewport(viewportId); viewport.setStack(imageIds); - // Restore previous state for existing viewports only - if (prevViewportProps.current[i] && typeof viewport.setProperties === "function") { +/* // Restore previous state for existing viewports only + if ( + prevViewportProps.current[i] && + typeof viewport.setProperties === "function" + ) { viewport.setProperties(prevViewportProps.current[i]); } + // Restore previous scroll position for existing viewports only + if ( + prevScrollIndices.current[i] !== undefined && + typeof viewport.setImageIdIndex === "function" + ) { + viewport.setImageIdIndex(prevScrollIndices.current[i]); + } */ cornerstoneTools.utilities.stackPrefetch.enable(viewport.element); - viewport.resize(); - viewport.render(); + + setTimeout(() => { + console.log("Resizing viewport", i); + renderingEngine.resize(false, false) + viewport.resetCameraForResize(); + viewport.render(); + }, 500); + + console.log(viewport) @@ -344,15 +371,12 @@ function App() { applyMouseToolBindings(); }; - setup(); -/* // Delay setup by 100ms (adjust as needed) - const timeout = setTimeout(() => { - setup(); + // Use requestAnimationFrame to ensure DOM is painted before setup + const raf = requestAnimationFrame(() => { + setup(); + }); - return () => clearTimeout(timeout); - }, 300); */ - - return; + return () => cancelAnimationFrame(raf); }, [elementRef, updateOverlay, viewportGrid, loadedImageIds]);