From dbf235d3c309417aa38f12075e5678e13a684616 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Mon, 24 Oct 2022 17:41:49 -0400 Subject: [PATCH] feat(createViewer): disable 2D interpolation if label image closes #610 --- doc/content/api/index.md | 22 +++++++---- .../VTKJS/Images/applyRenderedImage.js | 3 ++ src/createViewer.js | 39 ++++++++----------- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/doc/content/api/index.md b/doc/content/api/index.md index 1c794648d..b0f079aae 100644 --- a/doc/content/api/index.md +++ b/doc/content/api/index.md @@ -1,5 +1,4 @@ -title: API ---- +## title: API This documentation provides more detailed information about the viewer application programming interface (API). @@ -95,7 +94,7 @@ Select the layer identified by `name` in the user interface. ### setCroppingPlanes(croppingPlanes) -The croppingPlanes parameter is an array of plane defining objects. Example: `[ { normal: [1, 0, 0], origin: [1, 2, 3] }, ...]`. Maximum number of planes is 6. +The croppingPlanes parameter is an array of plane defining objects. Example: `[ { normal: [1, 0, 0], origin: [1, 2, 3] }, ...]`. Maximum number of planes is 6. ### getCroppingPlanes(): [ { normal: [number, number, number], origin: [number, number, number] }, ...] @@ -103,7 +102,7 @@ Returns array of plane objects. ### resetCroppingPlanes() -Sets cropping box to encompass all images and geometries +Sets cropping box to encompass all images and geometries ### setCroppingPlanesEnabled(enabled) @@ -118,9 +117,11 @@ Control visibility of croppingPlanes Set the image to be visualized. Can be an [itk.js Image](https://insightsoftwareconsortium.github.io/itk-js/api/Image.html) or a [scijs ndarray](http://scijs.net/packages/#scijs/ndarray) for JavaScript; for Python, it can be a [numpy](https://numpy.org) array. ### setPointSets(pointSets) + Set a set of points to be visualized. It can be an array of or a single imjoy-rpc encoded ndarray. The ndarray should be an array with the shape [x, 2] or [x, 3]. ### captureImage() + Take a screenshot for the current view and return a base64 encoded image string. ### setImageInterpolationEnabled(enabled) @@ -168,9 +169,9 @@ the volume rendering opacity transfer function and multi-component slice blendin ### getImagePiecewiseFunctionPoints(component, name) -Set/get the points defining the piecewise volume opacity transfer and multi-component -slice blending function. Parameter points is of type `[intensity: number, opacity:number][]` with -intensity and opacity values going from 0 to 1. The 0 to 1 intensity values are scaled between +Set/get the points defining the piecewise volume opacity transfer and multi-component +slice blending function. Parameter points is of type `[intensity: number, opacity:number][]` with +intensity and opacity values going from 0 to 1. The 0 to 1 intensity values are scaled between the component's range of intensity values. Example: If the intensity values for component 0 go from 100 to 200, `viewer.setImagePiecewiseFunctionPoints([[0, 0], [.5, 1]], 0)` puts a point at intensity 100 and another at intensity 150. @@ -210,6 +211,11 @@ Set/get the depth sampling distance in the volume rendering. Values range from 0 Set/get the volume rendering blend mode. Supported modes: 'Composite', 'Maximum', 'Minimum', 'Average'. +### setLabelImage(labelImageToLoad, layerImageName) + +Loads a label image and fuses with selected image or layerImageName. +setLabelImage disables 2D image interpolation. + ### setLabelImageLookupTable(lookupTable, name) ### getLabelImageLookupTable(name) @@ -239,4 +245,4 @@ string values. ### setImageScale(resolutionScale) -resolutionScale is a integer with 0 being the most detailed scale. \ No newline at end of file +resolutionScale is a integer with 0 being the most detailed scale. diff --git a/src/Rendering/VTKJS/Images/applyRenderedImage.js b/src/Rendering/VTKJS/Images/applyRenderedImage.js index 9fb0735aa..49d59be12 100644 --- a/src/Rendering/VTKJS/Images/applyRenderedImage.js +++ b/src/Rendering/VTKJS/Images/applyRenderedImage.js @@ -11,6 +11,7 @@ import { updateCroppingParametersFromImage, } from '../Main/croppingPlanes' import applyLookupTable from './applyLookupTable' +import toggleInterpolation from './toggleInterpolation' const ANNOTATION_DEFAULT = '
Index:${iIndex},${jIndex},${kIndex}
Position:${xPosition},${yPosition},${zPosition}
Value:${value}
Label:${annotation}
' @@ -99,6 +100,8 @@ function applyRenderedImage(context, { data: { name } }) { .querySelector('.js-se') annotationContainer.style.fontFamily = 'monospace' + toggleInterpolation(context, { data: name }) + const { widgetCroppingPlanes } = context.main const sliceActors = representationProxy.getActors() sliceActors.forEach((actor, actorIdx) => { diff --git a/src/createViewer.js b/src/createViewer.js index 74ca9d470..71eed3a8e 100644 --- a/src/createViewer.js +++ b/src/createViewer.js @@ -229,27 +229,6 @@ const createViewer = async ( context.service = service service.start() - let imageName = null - if (image) { - const multiscaleImage = await toMultiscaleSpatialImage(image) - imageName = multiscaleImage?.name ?? null - service.send({ type: 'ADD_IMAGE', data: multiscaleImage }) - } - - if (labelImage) { - const multiscaleLabelImage = await toMultiscaleSpatialImage( - labelImage, - true - ) - if (multiscaleLabelImage.name === 'Image') { - multiscaleLabelImage.name = 'LabelImage' - } - service.send({ - type: 'ADD_LABEL_IMAGE', - data: { imageName, labelImage: multiscaleLabelImage }, - }) - } - reaction( () => !!store.geometriesUI.geometries && store.geometriesUI.geometries.slice(), @@ -857,8 +836,7 @@ const createViewer = async ( return actorContext.colorMaps.get(componentIndex) } - publicAPI.setLabelImage = async labelImage => { - const imageName = context.images.selectedName + publicAPI.setLabelImage = async (labelImage, layerImageName) => { const multiscaleLabelImage = await toMultiscaleSpatialImage( labelImage, true @@ -866,10 +844,14 @@ const createViewer = async ( if (multiscaleLabelImage.name === 'Image') { multiscaleLabelImage.name = 'LabelImage' } + + const imageName = + layerImageName ?? context.images.selectedName ?? multiscaleLabelImage.name service.send({ type: 'ADD_LABEL_IMAGE', data: { imageName, labelImage: multiscaleLabelImage }, }) + publicAPI.setImageInterpolationEnabled(false, imageName) } publicAPI.getLabelImage = () => { @@ -1195,6 +1177,17 @@ const createViewer = async ( addKeyboardShortcuts(context.uiContainer, service) + let imageName = null + if (image) { + const multiscaleImage = await toMultiscaleSpatialImage(image) + imageName = multiscaleImage?.name ?? null + service.send({ type: 'ADD_IMAGE', data: multiscaleImage }) + } + + if (labelImage) { + publicAPI.setLabelImage(labelImage, imageName) + } + if (!use2D) { publicAPI.setRotateEnabled(rotate) }