From 21965650d64a333d7d27a61fb9182b44b5463821 Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Mon, 29 May 2023 11:40:19 -0400 Subject: [PATCH] feat(layerboundingbox): generalize label bounding box for all layers --- src/Context/LayerActorContext.js | 3 ++ src/Context/LayersMachineContext.js | 3 -- .../Images/createImageRenderingActor.js | 4 +- .../Images/createImagesRenderingMachine.js | 6 +-- .../VTKJS/Images/applyRenderedImage.js | 5 ++ .../Images/imagesRenderingMachineOptions.js | 4 +- src/Rendering/VTKJS/Images/toggleLabelBBox.js | 7 --- src/Rendering/VTKJS/Images/toggleLayerBBox.js | 9 ++++ src/Rendering/VTKJS/vtk/ItkVtkViewProxy.js | 49 +++++++++++-------- src/Rendering/createRenderingMachine.js | 2 +- src/UI/Layers/createLayersUIMachine.js | 2 + .../src/Layers/createLayerInterface.js | 44 +++++++++-------- src/createViewerMachine.js | 2 +- 13 files changed, 78 insertions(+), 62 deletions(-) delete mode 100644 src/Rendering/VTKJS/Images/toggleLabelBBox.js create mode 100644 src/Rendering/VTKJS/Images/toggleLayerBBox.js diff --git a/src/Context/LayerActorContext.js b/src/Context/LayerActorContext.js index 796985700..5af75e11b 100644 --- a/src/Context/LayerActorContext.js +++ b/src/Context/LayerActorContext.js @@ -7,6 +7,9 @@ class LayerActorContext { // img element icon for the layer or null icon = null + + // Boolean indicating whether the dataset bounding box is visible + bbox = false } export default LayerActorContext diff --git a/src/Context/LayersMachineContext.js b/src/Context/LayersMachineContext.js index 03a308816..309feb3cd 100644 --- a/src/Context/LayersMachineContext.js +++ b/src/Context/LayersMachineContext.js @@ -7,9 +7,6 @@ class LayersMachineContext { // A { name, data } object, queued for creation of the data's actor lastAddedData = null - - // Draw bounding boxes around image and label (if loaded) - labelBBoxEnabled = false } export default LayersMachineContext diff --git a/src/Rendering/Images/createImageRenderingActor.js b/src/Rendering/Images/createImageRenderingActor.js index ad7531e03..e8afc7a60 100644 --- a/src/Rendering/Images/createImageRenderingActor.js +++ b/src/Rendering/Images/createImageRenderingActor.js @@ -534,8 +534,8 @@ const eventResponses = { ANIMATE_IMAGE_MIX: { actions: applyAnimateImageMix, }, - TOGGLE_LABEL_BBOX: { - actions: 'toggleLabelBBox', + TOGGLE_LAYER_BBOX: { + actions: 'toggleLayerBBox', }, } diff --git a/src/Rendering/Images/createImagesRenderingMachine.js b/src/Rendering/Images/createImagesRenderingMachine.js index a56522b17..bc4e52aaa 100644 --- a/src/Rendering/Images/createImagesRenderingMachine.js +++ b/src/Rendering/Images/createImagesRenderingMachine.js @@ -148,11 +148,6 @@ function createImagesRenderingMachine(options, context) { to: (c, e) => `imageRenderingActor-${e.data}`, }), }, - TOGGLE_LABEL_BBOX: { - actions: send((_, e) => e, { - to: c => `imageRenderingActor-${c.images.selectedName}`, - }), - }, ...makeTransitions( [ 'IMAGE_GRADIENT_OPACITY_CHANGED', @@ -169,6 +164,7 @@ function createImagesRenderingMachine(options, context) { 'WINDOW_LEVEL_TOGGLED', 'IMAGE_COLOR_RANGE_RESET', 'ANIMATE_IMAGE_MIX', + 'TOGGLE_LAYER_BBOX', ], { actions: forwardToNamedActor } ), diff --git a/src/Rendering/VTKJS/Images/applyRenderedImage.js b/src/Rendering/VTKJS/Images/applyRenderedImage.js index 37bb32d94..d33ad02cd 100644 --- a/src/Rendering/VTKJS/Images/applyRenderedImage.js +++ b/src/Rendering/VTKJS/Images/applyRenderedImage.js @@ -393,8 +393,13 @@ function applyRenderedImage(context, { data: { name } }) { // call after representations are created updateCroppingParametersFromImage(context, actorContext.fusedImage) + context.itkVtkView.updateLabelBoundingBox( + name, + actorContext.image.getWorldBounds(actorContext.loadedScale) + ) if (actorContext.labelImage) { context.itkVtkView.updateLabelBoundingBox( + actorContext.labelImageName, actorContext.labelImage.getWorldBounds(actorContext.loadedScale) ) } diff --git a/src/Rendering/VTKJS/Images/imagesRenderingMachineOptions.js b/src/Rendering/VTKJS/Images/imagesRenderingMachineOptions.js index 966bf7b4b..566f89c04 100644 --- a/src/Rendering/VTKJS/Images/imagesRenderingMachineOptions.js +++ b/src/Rendering/VTKJS/Images/imagesRenderingMachineOptions.js @@ -1,6 +1,6 @@ import createImageRenderer from './createImageRenderer' import toggleLayerVisibility from './toggleLayerVisibility' -import toggleLabelBBox from './toggleLabelBBox' +import toggleLayerBBox from './toggleLayerBBox' import applyComponentVisibility from './applyComponentVisibility' import updateRenderedImage from './updateRenderedImage' import updateHistogram from './updateHistogram' @@ -100,7 +100,7 @@ const imagesRenderingMachineOptions = { applySelectedLabel, applyCinematicChanged, - toggleLabelBBox, + toggleLayerBBox, }, guards: { diff --git a/src/Rendering/VTKJS/Images/toggleLabelBBox.js b/src/Rendering/VTKJS/Images/toggleLabelBBox.js deleted file mode 100644 index c064c3ffa..000000000 --- a/src/Rendering/VTKJS/Images/toggleLabelBBox.js +++ /dev/null @@ -1,7 +0,0 @@ -function toggleLabelBBox(context, event) { - context.layers.labelBBoxEnabled = !context.layers.labelBBoxEnabled - context.itkVtkView.setEnableBBox(context.layers.labelBBoxEnabled) - context.service.send('RENDER') -} - -export default toggleLabelBBox diff --git a/src/Rendering/VTKJS/Images/toggleLayerBBox.js b/src/Rendering/VTKJS/Images/toggleLayerBBox.js new file mode 100644 index 000000000..911ae1708 --- /dev/null +++ b/src/Rendering/VTKJS/Images/toggleLayerBBox.js @@ -0,0 +1,9 @@ +function toggleLayerBBox(context, event) { + const name = event.data.layerName + const actorContext = context.layers.actorContext.get(name) + actorContext.bbox = !actorContext.bbox + context.itkVtkView.setEnableBBox(name, actorContext.bbox) + context.service.send('RENDER') +} + +export default toggleLayerBBox diff --git a/src/Rendering/VTKJS/vtk/ItkVtkViewProxy.js b/src/Rendering/VTKJS/vtk/ItkVtkViewProxy.js index e090f0c4b..44eed4f4f 100644 --- a/src/Rendering/VTKJS/vtk/ItkVtkViewProxy.js +++ b/src/Rendering/VTKJS/vtk/ItkVtkViewProxy.js @@ -704,15 +704,7 @@ function ItkVtkViewProxy(publicAPI, model) { model.axesCircleRadius = 4 model.axesTextOffset = 14 - model.enableLabelBBox = false - model.labelBBoxPolyData = vtkPolyData.newInstance() - model.labelBBoxMapper = vtkMapper.newInstance() - model.labelBBoxMapper.setInputData(model.labelBBoxPolyData) - model.labelBBoxGridActor = vtkActor.newInstance() - model.labelBBoxGridActor.setMapper(model.labelBBoxMapper) - model.labelBBoxGridActor.getProperty().setColor([1.0, 0.0, 0.0]) - model.labelBBoxGridActor.setVisibility(false) - model.renderer.addActor(model.labelBBoxGridActor) + model.layerBBoxes = new Map() // API ---------------------------------------------------------------------- publicAPI.updateDataProbeSize = updateDataProbeSize @@ -958,14 +950,10 @@ function ItkVtkViewProxy(publicAPI, model) { } } - publicAPI.setEnableBBox = enable => { - if (enable != model.enableLabelBBox) { - model.enableLabelBBox = enable - model.labelBBoxGridActor.setVisibility(enable) - publicAPI.modified() - if (!model.renderWindow.getInteractor().isAnimating()) { - model.renderWindow.render() - } + publicAPI.setEnableBBox = (name, enable) => { + const data = model.layerBBoxes.get(name) + if (data.actor.getVisibility() !== enable) { + data.actor.setVisibility(enable) } } @@ -1082,7 +1070,28 @@ function ItkVtkViewProxy(publicAPI, model) { publicAPI.renderLater() } - publicAPI.updateLabelBoundingBox = bounds => { + publicAPI.createLayerBoundingBox = name => { + const labelBBoxPolyData = vtkPolyData.newInstance() + const labelBBoxMapper = vtkMapper.newInstance() + labelBBoxMapper.setInputData(labelBBoxPolyData) + const labelBBoxGridActor = vtkActor.newInstance() + labelBBoxGridActor.setMapper(labelBBoxMapper) + labelBBoxGridActor.getProperty().setColor([1.0, 0.0, 0.0]) + labelBBoxGridActor.setVisibility(false) + const data = { + polyData: labelBBoxPolyData, + actor: labelBBoxGridActor, + } + model.layerBBoxes.set(name, data) + model.renderer.addActor(data.actor) + } + + publicAPI.updateLabelBoundingBox = (name, bounds) => { + if (!model.layerBBoxes.has(name)) { + publicAPI.createLayerBoundingBox(name) + } + + const data = model.layerBBoxes.get(name) let points = vtkPoints.newInstance() for (let i = 0; i < 2; i++) { for (let j = 2; j < 4; j++) { @@ -1091,14 +1100,14 @@ function ItkVtkViewProxy(publicAPI, model) { } } } - model.labelBBoxPolyData.setPoints(points) + data.polyData.setPoints(points) let lines = vtkCellArray.newInstance() lines.insertNextCell([0, 1, 3, 2, 0]) lines.insertNextCell([4, 5, 7, 6, 4]) lines.insertNextCell([0, 4, 6, 2]) lines.insertNextCell([1, 5, 7, 3]) - model.labelBBoxPolyData.setLines(lines) + data.polyData.setLines(lines) } } diff --git a/src/Rendering/createRenderingMachine.js b/src/Rendering/createRenderingMachine.js index 9e6f9bd4f..27a05e1d6 100644 --- a/src/Rendering/createRenderingMachine.js +++ b/src/Rendering/createRenderingMachine.js @@ -263,7 +263,7 @@ const createRenderingMachine = (options, context) => { IMAGE_COLOR_RANGE_RESET: { actions: forwardTo('images'), }, - TOGGLE_LABEL_BBOX: { + TOGGLE_LAYER_BBOX: { actions: forwardTo('images'), }, }, diff --git a/src/UI/Layers/createLayersUIMachine.js b/src/UI/Layers/createLayersUIMachine.js index cac46bf82..52d358cdc 100644 --- a/src/UI/Layers/createLayersUIMachine.js +++ b/src/UI/Layers/createLayersUIMachine.js @@ -30,6 +30,7 @@ function spawnLayerRenderingActor(options) { const actorContext = layers.actorContext.get(name) ?? new LayerActorContext() actorContext.type = 'image' + actorContext.bbox = false layers.actorContext.set(name, actorContext) layers.lastAddedData = { name, data: event.data } layers.layerUIActors.set( @@ -53,6 +54,7 @@ function spawnLayerRenderingActor(options) { const actorContext = layers.actorContext.get(name) ?? new LayerActorContext() actorContext.type = 'labelImage' + actorContext.bbox = false layers.actorContext.set(name, actorContext) layers.lastAddedData = { name, data: event.data } layers.layerUIActors.set( diff --git a/src/UI/reference-ui/src/Layers/createLayerInterface.js b/src/UI/reference-ui/src/Layers/createLayerInterface.js index 04ba2a3c5..b1283ae1c 100644 --- a/src/UI/reference-ui/src/Layers/createLayerInterface.js +++ b/src/UI/reference-ui/src/Layers/createLayerInterface.js @@ -73,28 +73,30 @@ function createLayerEntry(context, name, layer) { layer.spinner = spinner - if (layer.type === 'labelImage') { - const labelBBoxButton = document.createElement('div') - labelBBoxButton.innerHTML = `` - const labelBBoxButtonInput = labelBBoxButton.children[0] - const labelBBoxLabel = labelBBoxButton.children[1] - labelBBoxButton.style.height = '23px' - applyContrastSensitiveStyleToElement( - context, - 'invertibleButton', - labelBBoxLabel - ) - imageIcons.appendChild(labelBBoxButton) - labelBBoxButton.addEventListener('click', event => { - event.preventDefault() - event.stopPropagation() - context.service.send({ - type: 'TOGGLE_LABEL_BBOX', - data: layer.imageActorContext.labelImageName, - }) - labelBBoxButtonInput.checked = context.layers.labelBBoxEnabled + const layerBBoxButton = document.createElement('div') + layerBBoxButton.innerHTML = `` + const layerBBoxButtonInput = layerBBoxButton.children[0] + const layerBBoxLabel = layerBBoxButton.children[1] + layerBBoxButton.style.height = '23px' + applyContrastSensitiveStyleToElement( + context, + 'invertibleButton', + layerBBoxLabel + ) + imageIcons.appendChild(layerBBoxButton) + layerBBoxButton.addEventListener('click', event => { + event.preventDefault() + event.stopPropagation() + context.service.send({ + type: 'TOGGLE_LAYER_BBOX', + data: { + name: context.images.selectedName, + layerName: name, + }, }) - } + const actorContext = context.layers.layerUIActors.get(name) + layerBBoxButtonInput.checked = actorContext.bbox + }) const icon = makeHtml(``) icon.layer = layer diff --git a/src/createViewerMachine.js b/src/createViewerMachine.js index a900a48b5..1d4d92228 100644 --- a/src/createViewerMachine.js +++ b/src/createViewerMachine.js @@ -359,7 +359,7 @@ const createViewerMachine = (options, context, eventEmitterCallback) => { IMAGE_COLOR_RANGE_RESET: { actions: [forwardTo('ui'), forwardTo('rendering')], }, - TOGGLE_LABEL_BBOX: { + TOGGLE_LAYER_BBOX: { actions: [forwardTo('ui'), forwardTo('rendering')], }, },