diff --git a/src/Context/LayersMachineContext.js b/src/Context/LayersMachineContext.js index 03a30881..240eb112 100644 --- a/src/Context/LayersMachineContext.js +++ b/src/Context/LayersMachineContext.js @@ -8,8 +8,8 @@ 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 + // Draw bounding boxes around images + imageBBoxes = new Map() } export default LayersMachineContext diff --git a/src/Rendering/Images/createImageRenderingActor.js b/src/Rendering/Images/createImageRenderingActor.js index ad7531e0..e8afc7a6 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 a56522b1..bc4e52aa 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 37bb32d9..d33ad02c 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 966bf7b4..566f89c0 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 c064c3ff..00000000 --- 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/vtk/ItkVtkViewProxy.js b/src/Rendering/VTKJS/vtk/ItkVtkViewProxy.js index e090f0c4..4a2e2264 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,10 +950,11 @@ function ItkVtkViewProxy(publicAPI, model) { } } - publicAPI.setEnableBBox = enable => { - if (enable != model.enableLabelBBox) { - model.enableLabelBBox = enable - model.labelBBoxGridActor.setVisibility(enable) + publicAPI.setEnableBBox = (name, enable) => { + const data = model.layerBBoxes.get(name) + if (data && enable != data.enabled) { + data.enabled = enable + data.actor.setVisibility(enable) publicAPI.modified() if (!model.renderWindow.getInteractor().isAnimating()) { model.renderWindow.render() @@ -1082,7 +1075,29 @@ 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 = { + enabled: false, + 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 +1106,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 9e6f9bd4..27a05e1d 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 cac46bf8..453a78e6 100644 --- a/src/UI/Layers/createLayersUIMachine.js +++ b/src/UI/Layers/createLayersUIMachine.js @@ -32,6 +32,7 @@ function spawnLayerRenderingActor(options) { actorContext.type = 'image' layers.actorContext.set(name, actorContext) layers.lastAddedData = { name, data: event.data } + layers.imageBBoxes.set(name, false) layers.layerUIActors.set( name, spawn( @@ -55,6 +56,7 @@ function spawnLayerRenderingActor(options) { actorContext.type = 'labelImage' layers.actorContext.set(name, actorContext) layers.lastAddedData = { name, data: event.data } + layers.imageBBoxes.set(name, false) layers.layerUIActors.set( name, spawn( diff --git a/src/UI/reference-ui/src/Layers/createLayerInterface.js b/src/UI/reference-ui/src/Layers/createLayerInterface.js index 04ba2a3c..ac13f595 100644 --- a/src/UI/reference-ui/src/Layers/createLayerInterface.js +++ b/src/UI/reference-ui/src/Layers/createLayerInterface.js @@ -73,28 +73,27 @@ 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 }, }) - } + const checked = context.layers.imageBBoxes.get(name) + layerBBoxButtonInput.checked = checked + }) const icon = makeHtml(``) icon.layer = layer diff --git a/src/createViewerMachine.js b/src/createViewerMachine.js index a900a48b..1d4d9222 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')], }, },