From 301d3ab61a4a29851f51f905dc6a94d20f6eae6a Mon Sep 17 00:00:00 2001 From: Alireza Date: Fri, 4 Mar 2022 09:29:06 -0500 Subject: [PATCH] fix: remove the need for volumeUID to be passed in the configuration (#337) * fix: remove the need for volumeUID to be passed in the configuration * fix class methods --- .../src/RenderingEngine/VolumeViewport.ts | 10 +- .../src/types/IVolumeInput.ts | 2 +- .../src/tools/MIPJumpToClickTool.ts | 22 +--- .../src/tools/StackScrollTool.ts | 10 +- .../tools/StackScrollToolMouseWheelTool.ts | 3 +- .../src/tools/WindowLevelTool.ts | 2 +- .../src/tools/annotation/BidirectionalTool.ts | 11 +- .../src/tools/annotation/EllipticalRoiTool.ts | 13 +- .../src/tools/annotation/LengthTool.ts | 11 +- .../src/tools/annotation/PET/SUVPeakTool.ts | 5 +- .../src/tools/annotation/ProbeTool.ts | 13 +- .../src/tools/annotation/RectangleRoiTool.ts | 14 +-- .../src/tools/base/BaseAnnotationTool.ts | 20 +-- .../src/tools/base/BaseTool.ts | 59 +++++++++ .../tools/segmentation/CircleScissorsTool.ts | 15 --- .../RectangleRoiStartEndThreshold.ts | 16 ++- .../segmentation/RectangleRoiThreshold.ts | 6 +- .../tools/segmentation/SphereScissorsTool.ts | 15 --- .../stackScrollTool/scrollThroughStack.ts | 2 +- packages/demo/src/initToolGroups.js | 116 +++++------------- 20 files changed, 136 insertions(+), 229 deletions(-) diff --git a/packages/cornerstone-render/src/RenderingEngine/VolumeViewport.ts b/packages/cornerstone-render/src/RenderingEngine/VolumeViewport.ts index 20e406140..5758bdb2f 100644 --- a/packages/cornerstone-render/src/RenderingEngine/VolumeViewport.ts +++ b/packages/cornerstone-render/src/RenderingEngine/VolumeViewport.ts @@ -102,10 +102,16 @@ class VolumeViewport extends Viewport { // One actor per volume for (let i = 0; i < volumeInputArray.length; i++) { - const { volumeUID, slabThickness } = volumeInputArray[i] + const { volumeUID, slabThickness, actorUID } = volumeInputArray[i] const volumeActor = await createVolumeActor(volumeInputArray[i]) - volumeActors.push({ uid: volumeUID, volumeActor, slabThickness }) + // We cannot use only volumeUID since then we cannot have for instance more + // than one representation of the same volume (since actors would have the + // same name, and we don't allow that) AND We cannot use only any uid, since + // we rely on the volume in the cache for mapper. So we prefer actorUID if + // it is defined, otherwise we use volumeUID for the actor name. + const uid = actorUID || volumeUID + volumeActors.push({ uid, volumeActor, slabThickness }) if ( slabThickness !== undefined && diff --git a/packages/cornerstone-render/src/types/IVolumeInput.ts b/packages/cornerstone-render/src/types/IVolumeInput.ts index 47952a0e0..a7e6e91f5 100644 --- a/packages/cornerstone-render/src/types/IVolumeInput.ts +++ b/packages/cornerstone-render/src/types/IVolumeInput.ts @@ -8,7 +8,7 @@ type VolumeInputCallback = (params: { type IVolumeInput = { volumeUID: string // actorUID for segmentations, since two segmentations with the same volumeUID - // can have different represetnations + // can have different representations actorUID?: string visibility?: boolean callback?: VolumeInputCallback diff --git a/packages/cornerstone-tools/src/tools/MIPJumpToClickTool.ts b/packages/cornerstone-tools/src/tools/MIPJumpToClickTool.ts index ff5d4140e..14e0f036a 100644 --- a/packages/cornerstone-tools/src/tools/MIPJumpToClickTool.ts +++ b/packages/cornerstone-tools/src/tools/MIPJumpToClickTool.ts @@ -36,7 +36,7 @@ export default class MIPJumpToClickTool extends BaseTool { const { viewport, renderingEngine } = enabledElement // 2. Getting the target volume that is clicked on - const targetVolumeUID = this._getTargetVolumeUID(viewport as VolumeViewport) + const targetVolumeUID = this.getTargetUID(viewport as VolumeViewport) // 3. Criteria function to search for the point (maximum intensity) let maxIntensity = -Infinity @@ -75,24 +75,4 @@ export default class MIPJumpToClickTool extends BaseTool { jumpToWorld(viewport, brightestPoint) }) } - - /** - * Returns the volume UID in the viewport. It returns the first volume. - * @param viewport viewport - * @returns volume UID - */ - _getTargetVolumeUID = (viewport: VolumeViewport): string => { - if (this.configuration.volumeUID) { - return this.configuration.volumeUID - } - - const actors = viewport.getActors() - - if (!actors && !actors.length) { - // No stack to scroll through - return - } - - return actors[0].uid - } } diff --git a/packages/cornerstone-tools/src/tools/StackScrollTool.ts b/packages/cornerstone-tools/src/tools/StackScrollTool.ts index 5f4cc8f23..d1a6a14b6 100644 --- a/packages/cornerstone-tools/src/tools/StackScrollTool.ts +++ b/packages/cornerstone-tools/src/tools/StackScrollTool.ts @@ -1,3 +1,4 @@ +import { getEnabledElementByUIDs } from '@precisionmetrics/cornerstone-render' import { BaseTool } from './base' import { scrollThroughStack } from '../util/stackScrollTool' @@ -19,9 +20,14 @@ export default class StackScrollTool extends BaseTool { } _dragCallback(evt) { - const { deltaPoints } = evt.detail + const { deltaPoints, viewportUID, renderingEngineUID } = evt.detail const deltaFrames = deltaPoints.canvas[1] - const { volumeUID, invert } = this.configuration + const { viewport } = getEnabledElementByUIDs( + renderingEngineUID, + viewportUID + ) + const volumeUID = this.getTargetUID(viewport) + const { invert } = this.configuration scrollThroughStack(evt, deltaFrames, volumeUID, invert) } diff --git a/packages/cornerstone-tools/src/tools/StackScrollToolMouseWheelTool.ts b/packages/cornerstone-tools/src/tools/StackScrollToolMouseWheelTool.ts index 48bf1ab91..f0989e0d8 100644 --- a/packages/cornerstone-tools/src/tools/StackScrollToolMouseWheelTool.ts +++ b/packages/cornerstone-tools/src/tools/StackScrollToolMouseWheelTool.ts @@ -15,8 +15,7 @@ export default class StackScrollMouseWheelTool extends BaseTool { mouseWheelCallback(evt) { const { wheel } = evt.detail const { direction: deltaFrames } = wheel - - const { volumeUID, invert } = this.configuration + const { invert, volumeUID } = this.configuration scrollThroughStack(evt, deltaFrames, volumeUID, invert) } } diff --git a/packages/cornerstone-tools/src/tools/WindowLevelTool.ts b/packages/cornerstone-tools/src/tools/WindowLevelTool.ts index bba1fb958..5c8a72094 100644 --- a/packages/cornerstone-tools/src/tools/WindowLevelTool.ts +++ b/packages/cornerstone-tools/src/tools/WindowLevelTool.ts @@ -46,7 +46,7 @@ export default class WindowLevelTool extends BaseTool { let useDynamicRange = false if (viewport instanceof VolumeViewport) { - volumeUID = this.configuration.volumeUID + volumeUID = this.getTargetUID(viewport as VolumeViewport) ;({ volumeActor } = viewport.getActor(volumeUID)) rgbTransferFunction = volumeActor.getProperty().getRGBTransferFunction(0) viewportsContainingVolumeUID = getVolumeViewportsContainingVolumeUID( diff --git a/packages/cornerstone-tools/src/tools/annotation/BidirectionalTool.ts b/packages/cornerstone-tools/src/tools/annotation/BidirectionalTool.ts index 9faeeb038..ab256c11e 100644 --- a/packages/cornerstone-tools/src/tools/annotation/BidirectionalTool.ts +++ b/packages/cornerstone-tools/src/tools/annotation/BidirectionalTool.ts @@ -111,7 +111,7 @@ export default class BidirectionalTool extends BaseAnnotationTool { referencedImageId = viewport.getCurrentImageId && viewport.getCurrentImageId() } else { - const { volumeUID } = this.configuration + const volumeUID = this.getTargetUID(viewport) const imageVolume = getVolume(volumeUID) referencedImageId = getImageIdForTool( worldPos, @@ -972,14 +972,7 @@ export default class BidirectionalTool extends BaseAnnotationTool { } const { viewport } = enabledElement - let targetUID - if (viewport.type === VIEWPORT_TYPE.STACK) { - targetUID = this._getTargetStackUID(viewport) - } else if (viewport.type === VIEWPORT_TYPE.ORTHOGRAPHIC) { - targetUID = this._getTargetVolumeUID(viewport) - } else { - throw new Error(`Viewport Type not supported: ${viewport.type}`) - } + const targetUID = this.getTargetUID(viewport) const renderingEngine = viewport.getRenderingEngine() diff --git a/packages/cornerstone-tools/src/tools/annotation/EllipticalRoiTool.ts b/packages/cornerstone-tools/src/tools/annotation/EllipticalRoiTool.ts index 208178902..83a014c2c 100644 --- a/packages/cornerstone-tools/src/tools/annotation/EllipticalRoiTool.ts +++ b/packages/cornerstone-tools/src/tools/annotation/EllipticalRoiTool.ts @@ -126,7 +126,7 @@ export default class EllipticalRoiTool extends BaseAnnotationTool { referencedImageId = viewport.getCurrentImageId && viewport.getCurrentImageId() } else { - const { volumeUID } = this.configuration + const volumeUID = this.getTargetUID(viewport) const imageVolume = getVolume(volumeUID) referencedImageId = getImageIdForTool( worldPos, @@ -708,15 +708,8 @@ export default class EllipticalRoiTool extends BaseAnnotationTool { } const { viewport } = enabledElement + const targetUID = this.getTargetUID(viewport) - let targetUID - if (viewport instanceof StackViewport) { - targetUID = this._getTargetStackUID(viewport) - } else if (viewport instanceof VolumeViewport) { - targetUID = this._getTargetVolumeUID(viewport) - } else { - throw new Error(`Viewport Type not supported: ${viewport.type}`) - } const renderingEngine = viewport.getRenderingEngine() for (let i = 0; i < toolState.length; i++) { @@ -769,7 +762,7 @@ export default class EllipticalRoiTool extends BaseAnnotationTool { // at the referencedImageId const viewports = renderingEngine.getViewports() viewports.forEach((vp) => { - const stackTargetUID = this._getTargetStackUID(vp) + const stackTargetUID = this.getTargetUID(vp) // only delete the cachedStats for the stackedViewports if the tool // is dragged inside the volume and the stackViewports are not at the // referencedImageId for the tool diff --git a/packages/cornerstone-tools/src/tools/annotation/LengthTool.ts b/packages/cornerstone-tools/src/tools/annotation/LengthTool.ts index 2a0079d13..b0d2071f5 100644 --- a/packages/cornerstone-tools/src/tools/annotation/LengthTool.ts +++ b/packages/cornerstone-tools/src/tools/annotation/LengthTool.ts @@ -127,7 +127,7 @@ class LengthTool extends BaseAnnotationTool { referencedImageId = viewport.getCurrentImageId && viewport.getCurrentImageId() } else { - const { volumeUID } = this.configuration + const volumeUID = this.getTargetUID(viewport) const imageVolume = getVolume(volumeUID) referencedImageId = getImageIdForTool( worldPos, @@ -554,14 +554,7 @@ class LengthTool extends BaseAnnotationTool { } const { viewport } = enabledElement - let targetUID - if (viewport.type === VIEWPORT_TYPE.STACK) { - targetUID = this._getTargetStackUID(viewport) - } else if (viewport.type === VIEWPORT_TYPE.ORTHOGRAPHIC) { - targetUID = this._getTargetVolumeUID(viewport) - } else { - throw new Error(`Viewport Type not supported: ${viewport.type}`) - } + const targetUID = this.getTargetUID(viewport) const renderingEngine = viewport.getRenderingEngine() diff --git a/packages/cornerstone-tools/src/tools/annotation/PET/SUVPeakTool.ts b/packages/cornerstone-tools/src/tools/annotation/PET/SUVPeakTool.ts index c8f3df132..c78b82af6 100644 --- a/packages/cornerstone-tools/src/tools/annotation/PET/SUVPeakTool.ts +++ b/packages/cornerstone-tools/src/tools/annotation/PET/SUVPeakTool.ts @@ -145,7 +145,7 @@ export default class SUVPeakTool extends EllipticalRoiTool { referencedImageId = viewport.getCurrentImageId && viewport.getCurrentImageId() } else { - const { volumeUID } = this.configuration + const volumeUID = this.getTargetUID(viewport) const imageVolume = getVolume(volumeUID) referencedImageId = getImageIdForTool( worldPos, @@ -615,7 +615,8 @@ export default class SUVPeakTool extends EllipticalRoiTool { } // Todo: should this be inside the constructor? - const volume = getVolume(this.configuration.volumeUID) + const volumeUID = this.getTargetUID(viewport) + const volume = getVolume(volumeUID) const operationData = { points: data.handles.points, viewPlaneNormal, diff --git a/packages/cornerstone-tools/src/tools/annotation/ProbeTool.ts b/packages/cornerstone-tools/src/tools/annotation/ProbeTool.ts index 535236505..b2449529e 100644 --- a/packages/cornerstone-tools/src/tools/annotation/ProbeTool.ts +++ b/packages/cornerstone-tools/src/tools/annotation/ProbeTool.ts @@ -100,7 +100,7 @@ export default class ProbeTool extends BaseAnnotationTool { referencedImageId = viewport.getCurrentImageId && viewport.getCurrentImageId() } else { - const { volumeUID } = this.configuration + const volumeUID = this.getTargetUID(viewport) const imageVolume = getVolume(volumeUID) referencedImageId = getImageIdForTool( worldPos, @@ -354,14 +354,7 @@ export default class ProbeTool extends BaseAnnotationTool { const { viewport } = enabledElement - let targetUID - if (viewport instanceof StackViewport) { - targetUID = this._getTargetStackUID(viewport) - } else if (viewport instanceof VolumeViewport) { - targetUID = this._getTargetVolumeUID(viewport) - } else { - throw new Error(`Viewport Type not supported: ${viewport.type}`) - } + const targetUID = this.getTargetUID(viewport) const renderingEngine = viewport.getRenderingEngine() @@ -395,7 +388,7 @@ export default class ProbeTool extends BaseAnnotationTool { // at the referencedImageId const viewports = renderingEngine.getViewports() viewports.forEach((vp) => { - const stackTargetUID = this._getTargetStackUID(vp) + const stackTargetUID = this.getTargetUID(vp) // only delete the cachedStats for the stackedViewports if the tool // is dragged inside the volume and the stackViewports are not at the // referencedImageId for the tool diff --git a/packages/cornerstone-tools/src/tools/annotation/RectangleRoiTool.ts b/packages/cornerstone-tools/src/tools/annotation/RectangleRoiTool.ts index a6a6a615d..eeff4abf6 100644 --- a/packages/cornerstone-tools/src/tools/annotation/RectangleRoiTool.ts +++ b/packages/cornerstone-tools/src/tools/annotation/RectangleRoiTool.ts @@ -115,7 +115,7 @@ export default class RectangleRoiTool extends BaseAnnotationTool { referencedImageId = viewport.getCurrentImageId && viewport.getCurrentImageId() } else { - const { volumeUID } = this.configuration + const volumeUID = this.getTargetUID(viewport) const imageVolume = getVolume(volumeUID) referencedImageId = getImageIdForTool( worldPos, @@ -616,15 +616,7 @@ export default class RectangleRoiTool extends BaseAnnotationTool { } const { viewport } = enabledElement - - let targetUID - if (viewport instanceof StackViewport) { - targetUID = this._getTargetStackUID(viewport) - } else if (viewport instanceof VolumeViewport) { - targetUID = this._getTargetVolumeUID(viewport) - } else { - throw new Error(`Viewport Type not supported: ${viewport.type}`) - } + const targetUID = this.getTargetUID(viewport) const renderingEngine = viewport.getRenderingEngine() @@ -676,7 +668,7 @@ export default class RectangleRoiTool extends BaseAnnotationTool { // at the referencedImageId const viewports = renderingEngine.getViewports() viewports.forEach((vp) => { - const stackTargetUID = this._getTargetStackUID(vp) + const stackTargetUID = this.getTargetUID(vp) // only delete the cachedStats for the stackedViewports if the tool // is dragged inside the volume and the stackViewports are not at the // referencedImageId for the tool diff --git a/packages/cornerstone-tools/src/tools/base/BaseAnnotationTool.ts b/packages/cornerstone-tools/src/tools/base/BaseAnnotationTool.ts index fefaa3a8f..884129f6c 100644 --- a/packages/cornerstone-tools/src/tools/base/BaseAnnotationTool.ts +++ b/packages/cornerstone-tools/src/tools/base/BaseAnnotationTool.ts @@ -73,7 +73,7 @@ abstract class BaseAnnotationTool extends BaseTool { * @param {CustomEvent} evt The event. * @param {ToolSpecificToolData} toolData - The toolData selected. * @param {any} handle - The selected handle. - * @param {string} interactionType - The intraction type the handle was selected with. + * @param {string} interactionType - The interaction type the handle was selected with. */ public abstract handleSelectedCallback( evt, @@ -330,24 +330,6 @@ abstract class BaseAnnotationTool extends BaseTool { lineDash: this.getStyle(settings, 'textBox.link.lineDash', toolData), } } - - _getTargetStackUID(viewport) { - return `stackTarget:${viewport.uid}` - } - - _getTargetVolumeUID = (viewport) => { - if (this.configuration.volumeUID) { - return this.configuration.volumeUID - } - - const actors = viewport.getActors() - - if (!actors && !actors.length) { - return - } - - return actors[0].volumeActor.uid - } } export default BaseAnnotationTool diff --git a/packages/cornerstone-tools/src/tools/base/BaseTool.ts b/packages/cornerstone-tools/src/tools/base/BaseTool.ts index 742398f21..0c28958ba 100644 --- a/packages/cornerstone-tools/src/tools/base/BaseTool.ts +++ b/packages/cornerstone-tools/src/tools/base/BaseTool.ts @@ -1,3 +1,8 @@ +import { + StackViewport, + Types, + VolumeViewport, +} from '@precisionmetrics/cornerstone-render' import deepMerge from '../../util/deepMerge' import { ToolModes } from '../../enums' @@ -74,6 +79,60 @@ abstract class BaseTool { public setActiveStrategy(strategyName: string): void { this.setConfiguration({ activeStrategy: strategyName }) } + + /** + * Returns the volumeUID for the volume viewport. It will grabbed the volumeUID + * from the volumeUID if particularly specified in the tool configuration, or if + * not, the first actorUID in the viewport is returned as the volumeUID. NOTE: for + * segmentations, actorUID is not necessarily the volumeUID since the segmentation + * can have multiple representations, use SegmentationModule to get the volumeUID + * based on the actorUID. + * + * @param viewport - Volume viewport + * @returns the volumeUID for the viewport if specified in the tool configuration, + * or the first actorUID in the viewport if not. + */ + private getTargetVolumeUID(viewport: Types.IViewport): string | undefined { + if (!(viewport instanceof VolumeViewport)) { + throw new Error('getTargetVolumeUID: viewport must be a VolumeViewport') + } + + if (this.configuration.volumeUID) { + return this.configuration.volumeUID + } + + // If volume not specified, then return the actorUID for the + // default actor - first actor + const actors = viewport.getActors() + + if (!actors && !actors.length) { + return + } + + return actors[0].uid + } + + /** + * Get the target UID for the viewport which will be used to store the cached + * statistics scoped to that target in the toolState. + * For StackViewport, targetUID is the viewportUID, but for the volume viewport, + * the targetUID will be grabbed from the volumeUID if particularly specified + * in the tool configuration, or if not, the first actorUID in the viewport. + * + * @param viewport - viewport to get the targetUID for + * @returns targetUID + */ + protected getTargetUID(viewport: Types.IViewport): string | undefined { + if (viewport instanceof StackViewport) { + return `stackTarget:${viewport.uid}` + } else if (viewport instanceof VolumeViewport) { + return this.getTargetVolumeUID(viewport) + } else { + throw new Error( + 'getTargetUID: viewport must be a StackViewport or VolumeViewport' + ) + } + } } export default BaseTool diff --git a/packages/cornerstone-tools/src/tools/segmentation/CircleScissorsTool.ts b/packages/cornerstone-tools/src/tools/segmentation/CircleScissorsTool.ts index 84540fdcb..ac6519ade 100644 --- a/packages/cornerstone-tools/src/tools/segmentation/CircleScissorsTool.ts +++ b/packages/cornerstone-tools/src/tools/segmentation/CircleScissorsTool.ts @@ -324,19 +324,4 @@ export default class CircleScissorsTool extends BaseTool { } ) } - - _getTargetVolumeUID = (viewport) => { - if (this.configuration.volumeUID) { - return this.configuration.volumeUID - } - - const actors = viewport.getActors() - - if (!actors && !actors.length) { - // No stack to scroll through - return - } - - return actors[0].uid - } } diff --git a/packages/cornerstone-tools/src/tools/segmentation/RectangleRoiStartEndThreshold.ts b/packages/cornerstone-tools/src/tools/segmentation/RectangleRoiStartEndThreshold.ts index fc829300b..85bd4a959 100644 --- a/packages/cornerstone-tools/src/tools/segmentation/RectangleRoiStartEndThreshold.ts +++ b/packages/cornerstone-tools/src/tools/segmentation/RectangleRoiStartEndThreshold.ts @@ -122,11 +122,11 @@ export default class RectangleRoiStartEndThresholdTool extends RectangleRoiTool const camera = viewport.getCamera() const { viewPlaneNormal, viewUp } = camera - let referencedImageId, imageVolume + let referencedImageId, imageVolume, volumeUID if (viewport instanceof StackViewport) { throw new Error('Stack Viewport Not implemented') } else { - const { volumeUID } = this.configuration + volumeUID = this.getTargetUID(viewport) imageVolume = getVolume(volumeUID) referencedImageId = getImageIdForTool( worldPos, @@ -168,7 +168,7 @@ export default class RectangleRoiStartEndThresholdTool extends RectangleRoiTool FrameOfReferenceUID: viewport.getFrameOfReferenceUID(), referencedImageId, toolName: this.name, - volumeUID: this.configuration.volumeUID, + volumeUID, spacingInNormal, }, data: { @@ -298,10 +298,11 @@ export default class RectangleRoiStartEndThresholdTool extends RectangleRoiTool _calculateCachedStatsTool(toolData, enabledElement) { const data = toolData.data - const { viewportUID, renderingEngineUID } = enabledElement + const { viewportUID, renderingEngineUID, viewport } = enabledElement const { cachedStats } = data - const imageVolume = getVolume(this.configuration.volumeUID) + const volumeUID = this.getTargetUID(viewport) + const imageVolume = getVolume(volumeUID) // Todo: this shouldn't be here, this is a performance issue // Since we are extending the RectangleRoi class, we need to @@ -340,12 +341,9 @@ export default class RectangleRoiStartEndThresholdTool extends RectangleRoiTool // return // } - const { viewport, renderingEngine } = enabledElement + const { viewport } = enabledElement const sliceIndex = viewport.getCurrentImageIdIndex() - const { volumeUID } = this.configuration - const imageVolume = getVolume(volumeUID) - for (let i = 0; i < toolState.length; i++) { const toolData = toolState[i] as RectangleRoiStartEndThresholdToolData const settings = Settings.getObjectSettings( diff --git a/packages/cornerstone-tools/src/tools/segmentation/RectangleRoiThreshold.ts b/packages/cornerstone-tools/src/tools/segmentation/RectangleRoiThreshold.ts index 2faf7bc76..09021dcc1 100644 --- a/packages/cornerstone-tools/src/tools/segmentation/RectangleRoiThreshold.ts +++ b/packages/cornerstone-tools/src/tools/segmentation/RectangleRoiThreshold.ts @@ -83,12 +83,12 @@ export default class RectangleRoiThresholdTool extends RectangleRoiTool { const camera = viewport.getCamera() const { viewPlaneNormal, viewUp } = camera - let referencedImageId + let referencedImageId, volumeUID if (viewport instanceof StackViewport) { referencedImageId = viewport.getCurrentImageId && viewport.getCurrentImageId() } else { - const { volumeUID } = this.configuration + volumeUID = this.getTargetUID(viewport) const imageVolume = getVolume(volumeUID) referencedImageId = getImageIdForTool( worldPos, @@ -113,7 +113,7 @@ export default class RectangleRoiThresholdTool extends RectangleRoiTool { FrameOfReferenceUID: viewport.getFrameOfReferenceUID(), referencedImageId, toolName: this.name, - volumeUID: this.configuration.volumeUID, + volumeUID, }, data: { invalidated: true, diff --git a/packages/cornerstone-tools/src/tools/segmentation/SphereScissorsTool.ts b/packages/cornerstone-tools/src/tools/segmentation/SphereScissorsTool.ts index f5aabbc1f..b35546476 100644 --- a/packages/cornerstone-tools/src/tools/segmentation/SphereScissorsTool.ts +++ b/packages/cornerstone-tools/src/tools/segmentation/SphereScissorsTool.ts @@ -324,19 +324,4 @@ export default class SphereScissorsTool extends BaseTool { } ) } - - _getTargetVolumeUID = (viewport) => { - if (this.configuration.volumeUID) { - return this.configuration.volumeUID - } - - const actors = viewport.getActors() - - if (!actors && !actors.length) { - // No stack to scroll through - return - } - - return actors[0].uid - } } diff --git a/packages/cornerstone-tools/src/util/stackScrollTool/scrollThroughStack.ts b/packages/cornerstone-tools/src/util/stackScrollTool/scrollThroughStack.ts index ddfadc428..a15fb93e3 100644 --- a/packages/cornerstone-tools/src/util/stackScrollTool/scrollThroughStack.ts +++ b/packages/cornerstone-tools/src/util/stackScrollTool/scrollThroughStack.ts @@ -43,7 +43,7 @@ export default function scrollThroughStack( viewport.setImageIdIndex(newImageIdIndex) } else if (viewport instanceof VolumeViewport) { - // Stack scroll across highest resolution volume. + // If volumeUID is specified, scroll through that specific volume const { spacingInNormalDirection, imageVolume } = getTargetVolume( viewport, camera, diff --git a/packages/demo/src/initToolGroups.js b/packages/demo/src/initToolGroups.js index bddf2f882..97929d0c6 100644 --- a/packages/demo/src/initToolGroups.js +++ b/packages/demo/src/initToolGroups.js @@ -510,46 +510,24 @@ function addToolsToToolGroups({ // Set up CT Scene tools // @TODO: This kills the volumeUID and tool configuration - ctSceneToolGroup.addTool('RectangleScissor', { - configuration: { volumeUID: ctVolumeUID }, - }) - ctSceneToolGroup.addTool('RectangleRoiThreshold', { - configuration: { volumeUID: ctVolumeUID }, - }) + ctSceneToolGroup.addTool('RectangleScissor', {}) + ctSceneToolGroup.addTool('RectangleRoiThreshold', {}) ctSceneToolGroup.addTool('SegmentationDisplay') ctSceneToolGroup.setToolEnabled('SegmentationDisplay') - ctSceneToolGroup.addTool('RectangleRoiStartEndThreshold', { - configuration: { volumeUID: ctVolumeUID }, - }) - ctSceneToolGroup.addTool('CircleScissor', { - configuration: { volumeUID: ctVolumeUID }, - }) - ctSceneToolGroup.addTool('SphereScissor', { - configuration: { volumeUID: ctVolumeUID }, - }) - ctSceneToolGroup.addTool('WindowLevel', { - configuration: { volumeUID: ctVolumeUID }, - }) + ctSceneToolGroup.addTool('RectangleRoiStartEndThreshold', {}) + ctSceneToolGroup.addTool('CircleScissor', {}) + ctSceneToolGroup.addTool('SphereScissor', {}) + ctSceneToolGroup.addTool('WindowLevel', {}) ctSceneToolGroup.addTool('Length', {}) ctSceneToolGroup.addTool('Pan', {}) ctSceneToolGroup.addTool('Zoom', {}) ctSceneToolGroup.addTool('StackScrollMouseWheel', {}) - ctSceneToolGroup.addTool('Bidirectional', { - configuration: { volumeUID: ctVolumeUID }, - }) - ctSceneToolGroup.addTool('Length', { - configuration: { volumeUID: ctVolumeUID }, - }) - ctSceneToolGroup.addTool('Probe', { - configuration: { volumeUID: ctVolumeUID }, - }) - ctSceneToolGroup.addTool('RectangleRoi', { - configuration: { volumeUID: ctVolumeUID }, - }) - ctSceneToolGroup.addTool('EllipticalRoi', { - configuration: { volumeUID: ctVolumeUID }, - }) + ctSceneToolGroup.addTool('Bidirectional', {}) + ctSceneToolGroup.addTool('Length', {}) + ctSceneToolGroup.addTool('Probe', {}) + ctSceneToolGroup.addTool('RectangleRoi', {}) + ctSceneToolGroup.addTool('EllipticalRoi', {}) ctSceneToolGroup.addTool('Crosshairs', { configuration: { getReferenceLineColor, @@ -594,29 +572,17 @@ function addToolsToToolGroups({ // Set up CT Scene tools // @TODO: This kills the volumeUID and tool configuration - prostateSceneToolGroup.addTool('WindowLevel', { - configuration: { volumeUID: prostateVolumeUID }, - }) + prostateSceneToolGroup.addTool('WindowLevel', {}) prostateSceneToolGroup.addTool('Length', {}) prostateSceneToolGroup.addTool('Pan', {}) prostateSceneToolGroup.addTool('Zoom', {}) prostateSceneToolGroup.addTool('StackScrollMouseWheel', {}) - prostateSceneToolGroup.addTool('Bidirectional', { - configuration: { volumeUID: prostateVolumeUID }, - }) - prostateSceneToolGroup.addTool('Length', { - configuration: { volumeUID: prostateVolumeUID }, - }) - prostateSceneToolGroup.addTool('Probe', { - configuration: { volumeUID: prostateVolumeUID }, - }) - prostateSceneToolGroup.addTool('RectangleRoi', { - configuration: { volumeUID: prostateVolumeUID }, - }) - prostateSceneToolGroup.addTool('EllipticalRoi', { - configuration: { volumeUID: ctVolumeUID }, - }) + prostateSceneToolGroup.addTool('Bidirectional', {}) + prostateSceneToolGroup.addTool('Length', {}) + prostateSceneToolGroup.addTool('Probe', {}) + prostateSceneToolGroup.addTool('RectangleRoi', {}) + prostateSceneToolGroup.addTool('EllipticalRoi', {}) prostateSceneToolGroup.addTool('Crosshairs', { configuration: { getReferenceLineColor, @@ -659,44 +625,20 @@ function addToolsToToolGroups({ if (ptSceneToolGroup) { // Set up PT Scene tools - ptSceneToolGroup.addTool('RectangleScissor', { - configuration: { volumeUID: ptVolumeUID }, - }) - ptSceneToolGroup.addTool('RectangleRoiThreshold', { - configuration: { volumeUID: ptVolumeUID }, - }) + ptSceneToolGroup.addTool('RectangleScissor', {}) + ptSceneToolGroup.addTool('RectangleRoiThreshold', {}) ptSceneToolGroup.addTool('SegmentationDisplay') ptSceneToolGroup.setToolEnabled('SegmentationDisplay') - ptSceneToolGroup.addTool('RectangleRoiStartEndThreshold', { - configuration: { volumeUID: ptVolumeUID }, - }) - ptSceneToolGroup.addTool('CircleScissor', { - configuration: { volumeUID: ptVolumeUID }, - }) - ptSceneToolGroup.addTool('SphereScissor', { - configuration: { volumeUID: ptVolumeUID }, - }) - ptSceneToolGroup.addTool('ptSUVPeak', { - configuration: { volumeUID: ptVolumeUID }, - }) - ptSceneToolGroup.addTool('Bidirectional', { - configuration: { volumeUID: ptVolumeUID }, - }) - ptSceneToolGroup.addTool('Length', { - configuration: { volumeUID: ptVolumeUID }, - }) - ptSceneToolGroup.addTool('WindowLevel', { - configuration: { volumeUID: ptVolumeUID }, - }) - ptSceneToolGroup.addTool('Probe', { - configuration: { volumeUID: ptVolumeUID }, - }) - ptSceneToolGroup.addTool('RectangleRoi', { - configuration: { volumeUID: ptVolumeUID }, - }) - ptSceneToolGroup.addTool('EllipticalRoi', { - configuration: { volumeUID: ptVolumeUID }, - }) + ptSceneToolGroup.addTool('RectangleRoiStartEndThreshold', {}) + ptSceneToolGroup.addTool('CircleScissor', {}) + ptSceneToolGroup.addTool('SphereScissor', {}) + ptSceneToolGroup.addTool('ptSUVPeak', {}) + ptSceneToolGroup.addTool('Bidirectional', {}) + ptSceneToolGroup.addTool('Length', {}) + ptSceneToolGroup.addTool('WindowLevel', {}) + ptSceneToolGroup.addTool('Probe', {}) + ptSceneToolGroup.addTool('RectangleRoi', {}) + ptSceneToolGroup.addTool('EllipticalRoi', {}) ptSceneToolGroup.addTool('Crosshairs', { configuration: { getReferenceLineColor,