diff --git a/.gitattributes b/.gitattributes index 056e3cb90..5fcaab605 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ * text=auto eol=lf package-lock.json linguist-generated=true +patches/*.patch -whitespace diff --git a/package-lock.json b/package-lock.json index 242cf90ef..db7f994ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@itk-wasm/dicom": "^7.6.4", "@itk-wasm/image-io": "1.6.1", "@itk-wasm/morphological-contour-interpolation": "2.0.0", - "@kitware/vtk.js": "^36.2.0", + "@kitware/vtk.js": "^37.0.4", "@netlify/edge-functions": "^3.0.2", "@rollup/plugin-replace": "^6.0.3", "@sentry/vite-plugin": "^4.6.1", @@ -2636,9 +2636,9 @@ } }, "node_modules/@kitware/vtk.js": { - "version": "36.2.1", - "resolved": "https://registry.npmjs.org/@kitware/vtk.js/-/vtk.js-36.2.1.tgz", - "integrity": "sha512-u5V7jfYeve1WNXVl7bZbjp755t1/EMyiW2y0aQU7YZ7RteCfZ8mxk9jB3DTeo9pGcIsVr+E8SIQz2bXHHedPlg==", + "version": "37.0.4", + "resolved": "https://registry.npmjs.org/@kitware/vtk.js/-/vtk.js-37.0.4.tgz", + "integrity": "sha512-iBCeHRqiYXAQXkYXe8hoMijwgnweYaPVaZrNhyfL1TLR82bfmxiazfjirnixNksSJTpphU8q/7wX1G8SfNOiXA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -2646,9 +2646,8 @@ "commander": "9.2.0", "d3-scale": "4.0.2", "fast-deep-equal": "3.1.3", - "fflate": "0.7.3", + "fflate": "0.7.5", "gl-matrix": "3.4.3", - "globalthis": "1.0.3", "seedrandom": "3.0.5", "shelljs": "0.8.5", "spark-md5": "3.0.2", @@ -2662,7 +2661,7 @@ }, "peerDependencies": { "autoprefixer": "^10.4.7", - "wslink": ">=1.1.0 || ^2.0.0" + "wslink": ">=2.0.0" } }, "node_modules/@msgpack/msgpack": { @@ -11416,9 +11415,9 @@ } }, "node_modules/fflate": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.3.tgz", - "integrity": "sha512-0Zz1jOzJWERhyhsimS54VTqOteCNwRtIlh8isdL0AXLo0g7xNTfTL7oWrkmCnPhZGocKIkWHBistBrrpoNH3aw==", + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.5.tgz", + "integrity": "sha512-QieYf//cis6ywHNi5qW1+PXPQ4bC+XVJAtS4AXIML8P76GroEiOxm/oQtn1f02UkJY1+KsXMJcC+R2v/Eg4G3g==", "dev": true, "license": "MIT" }, @@ -12121,22 +12120,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", diff --git a/package.json b/package.json index b5d08518e..df82796ee 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "@itk-wasm/dicom": "^7.6.4", "@itk-wasm/image-io": "1.6.1", "@itk-wasm/morphological-contour-interpolation": "2.0.0", - "@kitware/vtk.js": "^36.2.0", + "@kitware/vtk.js": "^37.0.4", "@netlify/edge-functions": "^3.0.2", "@rollup/plugin-replace": "^6.0.3", "@sentry/vite-plugin": "^4.6.1", diff --git a/patches/@kitware+vtk.js+37.0.4.patch b/patches/@kitware+vtk.js+37.0.4.patch new file mode 100644 index 000000000..09a4dffed --- /dev/null +++ b/patches/@kitware+vtk.js+37.0.4.patch @@ -0,0 +1,68 @@ +diff --git a/node_modules/@kitware/vtk.js/Rendering/OpenGL/ImageMapper.js b/node_modules/@kitware/vtk.js/Rendering/OpenGL/ImageMapper.js +index 7defbee..70178df 100644 +--- a/node_modules/@kitware/vtk.js/Rendering/OpenGL/ImageMapper.js ++++ b/node_modules/@kitware/vtk.js/Rendering/OpenGL/ImageMapper.js +@@ -32,11 +32,16 @@ function splitStringOnEnter(inputString) { + } + function vtkOpenGLImageMapper(publicAPI, model) { + model.classHierarchy.push("vtkOpenGLImageMapper"); ++ function unregisterTextureResource(renderWindow, coreObject, texture) { ++ if (coreObject) renderWindow.unregisterGraphicsResourceUser(coreObject, publicAPI); ++ else texture?.releaseGraphicsResources(renderWindow); ++ } + function unregisterGraphicsResources(renderWindow) { + model.openGLTexture.releaseGraphicsResources(renderWindow); ++ model.tris.releaseGraphicsResources(renderWindow); ++ unregisterTextureResource(renderWindow, model._colorTransferFunc, model.colorTexture); ++ unregisterTextureResource(renderWindow, model._pwFunc, model.pwfTexture); + [ +- model._colorTransferFunc, +- model._pwFunc, + model._labelOutlineThicknessArray, + model._labelOutlineOpacity + ].forEach((coreObject) => renderWindow.unregisterGraphicsResourceUser(coreObject, publicAPI)); +@@ -567,6 +572,11 @@ function vtkOpenGLImageMapper(publicAPI, model) { + const firstColorTransferFunc = actorProperty.getRGBTransferFunction(); + const cTex = model._openGLRenderWindow.getGraphicsResourceForObject(firstColorTransferFunc); + if (!cTex?.oglObject?.getHandle() || cTex?.hash !== cfunToString) { ++ if (!firstColorTransferFunc) { ++ if (model._colorTransferFunc) model._openGLRenderWindow.unregisterGraphicsResourceUser(model._colorTransferFunc, publicAPI); ++ else model.colorTexture?.releaseGraphicsResources(model._openGLRenderWindow); ++ model._colorTransferFunc = null; ++ } + model.colorTexture = Texture_default.newInstance({ resizable: true }); + model.colorTexture.setOpenGLRenderWindow(model._openGLRenderWindow); + let cWidth = model.renderable.getColorTextureWidth(); +@@ -629,6 +639,11 @@ function vtkOpenGLImageMapper(publicAPI, model) { + const firstPwFunc = actorProperty.getPiecewiseFunction(); + const pwfTex = model._openGLRenderWindow.getGraphicsResourceForObject(firstPwFunc); + if (!pwfTex?.oglObject?.getHandle() || pwfTex?.hash !== pwfunToString) { ++ if (!firstPwFunc) { ++ if (model._pwFunc) model._openGLRenderWindow.unregisterGraphicsResourceUser(model._pwFunc, publicAPI); ++ else model.pwfTexture?.releaseGraphicsResources(model._openGLRenderWindow); ++ model._pwFunc = null; ++ } + let pwfWidth = model.renderable.getOpacityTextureWidth(); + if (pwfWidth <= 0) pwfWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE); + const pwfSize = pwfWidth * textureHeight; +diff --git a/node_modules/@kitware/vtk.js/Rendering/OpenGL/Texture.js b/node_modules/@kitware/vtk.js/Rendering/OpenGL/Texture.js +index 3563142..111214c 100644 +--- a/node_modules/@kitware/vtk.js/Rendering/OpenGL/Texture.js ++++ b/node_modules/@kitware/vtk.js/Rendering/OpenGL/Texture.js +@@ -182,7 +182,7 @@ function vtkOpenGLTexture(publicAPI, model) { + publicAPI.deactivate = () => { + if (model._openGLRenderWindow) model._openGLRenderWindow.deactivateTexture(publicAPI); + }; +- publicAPI.releaseGraphicsResources = (rwin) => { ++ publicAPI.releaseGraphicsResources = (rwin = model._openGLRenderWindow) => { + if (rwin && model.handle) { + rwin.activateTexture(publicAPI); + rwin.deactivateTexture(publicAPI); +@@ -863,6 +863,7 @@ function vtkOpenGLTexture(publicAPI, model) { + publicAPI.enableUseHalfFloat = (use) => { + model.enableUseHalfFloat = use; + }; ++ publicAPI.delete = macros_exports.chain(() => publicAPI.releaseGraphicsResources(), publicAPI.delete); + } + var DEFAULT_VALUES = { + _openGLRenderWindow: null, diff --git a/src/components/RenderingModule.vue b/src/components/RenderingModule.vue index 2180bc8af..7091a2a89 100644 --- a/src/components/RenderingModule.vue +++ b/src/components/RenderingModule.vue @@ -22,12 +22,13 @@ export default defineComponent({ const activeView = viewStore.getView(viewStore.activeView); if ( activeView?.type === '3D' && - activeView.dataID === currentImageID.value + activeView.dataID === currentImageID.value && + viewStore.visibleViews.includes(activeView) ) { return activeView.id; } - const any3DView = Object.values(viewStore.viewByID).find( + const any3DView = viewStore.visibleViews.find( (v) => v.type === '3D' && v.dataID === currentImageID.value ); return any3DView?.id; diff --git a/src/components/VolumeRendering.vue b/src/components/VolumeRendering.vue index 8a7184ddb..8ee168645 100644 --- a/src/components/VolumeRendering.vue +++ b/src/components/VolumeRendering.vue @@ -8,7 +8,6 @@ import { watchEffect, } from 'vue'; import { onKeyDown, onKeyUp } from '@vueuse/core'; -import { PresetNameList } from '@/src/vtk/ColorMaps'; import vtkPiecewiseWidget from '@/src/vtk/PiecewiseWidget'; import type { vtkSubscription } from '@kitware/vtk.js/interfaces'; import vtkColorMaps from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps'; @@ -25,11 +24,9 @@ import { getColorFunctionRangeFromPreset, getShiftedOpacityFromPreset, } from '@/src/utils/vtk-helpers'; -import { useVolumeThumbnailing } from '@/src/composables/useVolumeThumbnailing'; const WIDGET_WIDTH = 250; const WIDGET_HEIGHT = 150; -const THUMBNAIL_SIZE = 80; export default defineComponent({ name: 'VolumeRendering', @@ -182,6 +179,8 @@ export default defineComponent({ onBeforeUnmount(() => { pwfWidget.unbindMouseListeners(); pwfWidget.setContainer(null); + pwfWidget.delete(); + colorTransferFunc.delete(); }); watch( @@ -239,10 +238,6 @@ export default defineComponent({ { immediate: true } ); - // -- thumbnailing -- // - - const { currentThumbnails } = useVolumeThumbnailing(THUMBNAIL_SIZE); - // --- selection and updates --- // const selectedPreset = computed( @@ -335,7 +330,6 @@ export default defineComponent({ return { editorContainerRef, pwfEditorRef, - thumbnails: currentThumbnails, hasCurrentImage, preset: selectedPreset, fullMappingRange, @@ -348,8 +342,6 @@ export default defineComponent({ const step = Math.min(1, width / 256); return step > 1 ? Math.round(step) : step; }), - presetList: PresetNameList, - size: THUMBNAIL_SIZE, rangeShiftMin: computed(() => -fullMappingRangeWidth.value / 2), rangeShiftMax: computed(() => fullMappingRangeWidth.value / 2), rangeShift, diff --git a/src/components/tools/ScalarProbe.vue b/src/components/tools/ScalarProbe.vue index a3e317840..c962c82b1 100644 --- a/src/components/tools/ScalarProbe.vue +++ b/src/components/tools/ScalarProbe.vue @@ -1,5 +1,5 @@ diff --git a/src/components/vtk/VtkRenderWindowParent.vue b/src/components/vtk/VtkRenderWindowParent.vue index c4629c69d..ea64ef36d 100644 --- a/src/components/vtk/VtkRenderWindowParent.vue +++ b/src/components/vtk/VtkRenderWindowParent.vue @@ -1,8 +1,9 @@