From 476b547d3b8ab4586a44495f15096037051a580e Mon Sep 17 00:00:00 2001 From: Jo-Byr Date: Thu, 16 Jul 2026 13:00:03 +0200 Subject: [PATCH] chore(InteractorStyleMPRSlice): fix recursion error in example Limit slice widget update in example to prevent recursion error between the controller and interactor style --- .../InteractorStyleMPRSlice/example/index.js | 61 +++++++++---------- .../Style/InteractorStyleMPRSlice/index.js | 4 ++ 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/Sources/Interaction/Style/InteractorStyleMPRSlice/example/index.js b/Sources/Interaction/Style/InteractorStyleMPRSlice/example/index.js index 13e59ad9217..f06a097c3a3 100644 --- a/Sources/Interaction/Style/InteractorStyleMPRSlice/example/index.js +++ b/Sources/Interaction/Style/InteractorStyleMPRSlice/example/index.js @@ -26,35 +26,6 @@ renderWindow.getInteractor().setInteractorStyle(istyle); global.fullScreen = fullScreenRenderWindow; global.renderWindow = renderWindow; -// ---------------------------------------------------------------------------- -// Volume rendering -// ---------------------------------------------------------------------------- - -const actor = vtkVolume.newInstance(); -const mapper = vtkVolumeMapper.newInstance(); -actor.setMapper(mapper); - -const reader = vtkHttpDataSetReader.newInstance({ - fetchGzip: true, -}); -reader - .setUrl(`${__BASE_PATH__}/data/volume/headsq.vti`, { loadData: true }) - .then(() => { - const data = reader.getOutputData(); - - mapper.setInputData(data); - - // set interactor style volume mapper after mapper sets input data - istyle.setVolumeMapper(mapper); - istyle.setSliceNormal(0, 0, 1); - - const range = istyle.getSliceRange(); - istyle.setSlice((range[0] + range[1]) / 2); - - renderer.addVolume(actor); - renderWindow.render(); - }); - // ---------------------------------------------------------------------------- // UI (lil-gui) // ---------------------------------------------------------------------------- @@ -95,5 +66,33 @@ function updateUI() { sliceCtrl.updateDisplay?.(); } -istyle.onModified(updateUI); -updateUI(); +// ---------------------------------------------------------------------------- +// Volume rendering +// ---------------------------------------------------------------------------- + +const actor = vtkVolume.newInstance(); +const mapper = vtkVolumeMapper.newInstance(); +actor.setMapper(mapper); + +const reader = vtkHttpDataSetReader.newInstance({ + fetchGzip: true, +}); +reader + .setUrl(`${__BASE_PATH__}/data/volume/headsq.vti`, { loadData: true }) + .then(() => { + const data = reader.getOutputData(); + + mapper.setInputData(data); + + // set interactor style volume mapper after mapper sets input data + istyle.setVolumeMapper(mapper); + istyle.setSliceNormal(0, 0, 1); + + const range = istyle.getSliceRange(); + istyle.setSlice((range[0] + range[1]) / 2); + + renderer.addVolume(actor); + renderWindow.render(); + istyle.onModified(updateUI); + updateUI(); + }); diff --git a/Sources/Interaction/Style/InteractorStyleMPRSlice/index.js b/Sources/Interaction/Style/InteractorStyleMPRSlice/index.js index d861374ec6d..8dfe3cb8897 100644 --- a/Sources/Interaction/Style/InteractorStyleMPRSlice/index.js +++ b/Sources/Interaction/Style/InteractorStyleMPRSlice/index.js @@ -137,6 +137,9 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) { }; publicAPI.setSlice = (slice) => { + if (publicAPI.getSlice() === slice) { + return false; + } const renderer = model._interactor.getCurrentRenderer(); const camera = renderer.getActiveCamera(); @@ -171,6 +174,7 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) { camera.setPosition(...newPos); camera.setFocalPoint(...slicePoint); } + return true; }; publicAPI.getSliceRange = () => {