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 @@