From 757379636d2656f4fe6b6006be7f33a19b95b2ba Mon Sep 17 00:00:00 2001 From: Alireza Date: Mon, 6 Jun 2022 15:15:34 -0400 Subject: [PATCH 01/10] feat: remove unnecessary triggerEvents for annotation rendered --- packages/tools/src/tools/CrosshairsTool.ts | 16 +++++---- .../tools/src/tools/annotation/AngleTool.ts | 26 +++++++++------ .../src/tools/annotation/ArrowAnnotateTool.ts | 13 +++++--- .../src/tools/annotation/BidirectionalTool.ts | 13 +++++--- .../src/tools/annotation/DragProbeTool.ts | 11 +++++-- .../src/tools/annotation/EllipticalROITool.ts | 13 +++++--- .../tools/src/tools/annotation/LengthTool.ts | 13 +++++--- .../tools/annotation/PlanarFreehandROITool.ts | 12 ++++--- .../tools/src/tools/annotation/ProbeTool.ts | 13 +++++--- .../src/tools/annotation/RectangleROITool.ts | 13 +++++--- .../tools/segmentation/CircleScissorsTool.ts | 12 ++++--- .../RectangleROIStartEndThresholdTool.ts | 11 +++++-- .../segmentation/RectangleROIThresholdTool.ts | 13 +++++--- .../segmentation/RectangleScissorsTool.ts | 11 +++++-- .../tools/segmentation/SphereScissorsTool.ts | 13 +++++--- .../src/utilities/triggerAnnotationRender.ts | 33 ++++++++++--------- 16 files changed, 155 insertions(+), 81 deletions(-) diff --git a/packages/tools/src/tools/CrosshairsTool.ts b/packages/tools/src/tools/CrosshairsTool.ts index d4c827f752..3a4c072639 100644 --- a/packages/tools/src/tools/CrosshairsTool.ts +++ b/packages/tools/src/tools/CrosshairsTool.ts @@ -669,7 +669,8 @@ export default class CrosshairsTool extends AnnotationTool { renderAnnotation = ( enabledElement: Types.IEnabledElement, svgDrawingHelper: any - ): void => { + ): boolean => { + let renderStatus = false; const { viewport, renderingEngine } = enabledElement; const { element } = viewport; const annotations = getAnnotations(element, this.getToolName()); @@ -681,7 +682,7 @@ export default class CrosshairsTool extends AnnotationTool { const viewportAnnotation = filteredToolAnnotations[0]; if (!annotations || !viewportAnnotation || !viewportAnnotation.data) { // No annotations yet, and didn't just create it as we likely don't have a FrameOfReference/any data loaded yet. - return; + return renderStatus; } const annotationUID = viewportAnnotation.annotationUID; @@ -1288,17 +1289,18 @@ export default class CrosshairsTool extends AnnotationTool { } }); + renderStatus = true; + // Save new handles points in annotation data.handles.rotationPoints = newRtpoints; data.handles.slabThicknessPoints = newStpoints; - // render a circle to pin point the viewport color - // TODO: This should not be part of the tool, and definitely not part of the renderAnnotation loop - if (!this.configuration.viewportIndicators) { - return; + return renderStatus; } + // render a circle to pin point the viewport color + // TODO: This should not be part of the tool, and definitely not part of the renderAnnotation loop const referenceColorCoordinates = [ sWidth * 0.95, sHeight * 0.05, @@ -1314,6 +1316,8 @@ export default class CrosshairsTool extends AnnotationTool { circleRadius, { color, fill: color } ); + + return renderStatus; }; _autoPanViewportIfNecessary( diff --git a/packages/tools/src/tools/annotation/AngleTool.ts b/packages/tools/src/tools/annotation/AngleTool.ts index dfa3a868f9..e41363fc5e 100644 --- a/packages/tools/src/tools/annotation/AngleTool.ts +++ b/packages/tools/src/tools/annotation/AngleTool.ts @@ -523,7 +523,9 @@ class AngleTool extends AnnotationTool { renderAnnotation = ( enabledElement: Types.IEnabledElement, svgDrawingHelper: any - ): void => { + ): boolean => { + let renderStatus = false; + const { viewport } = enabledElement; const { element } = viewport; @@ -531,7 +533,7 @@ class AngleTool extends AnnotationTool { // Todo: We don't need this anymore, filtering happens in triggerAnnotationRender if (!annotations?.length) { - return; + return renderStatus; } annotations = this.filterInteractableAnnotationsForElement( @@ -540,7 +542,7 @@ class AngleTool extends AnnotationTool { ); if (!annotations?.length) { - return; + return renderStatus; } const targetId = this.getTargetId(viewport); @@ -592,6 +594,12 @@ class AngleTool extends AnnotationTool { activeHandleCanvasCoords = [canvasCoordinates[activeHandleIndex]]; } + // If rendering engine has been destroyed while rendering + if (!viewport.getRenderingEngine()) { + console.warn('Rendering Engine has been destroyed'); + return renderStatus; + } + if (activeHandleCanvasCoords) { const handleGroupUID = '0'; @@ -622,9 +630,11 @@ class AngleTool extends AnnotationTool { } ); + renderStatus = true; + // Don't add textBox until annotation has 3 anchor points (actually 4 because of the center point) if (canvasCoordinates.length !== 3) { - return; + return renderStatus; } lineUID = '2'; @@ -642,12 +652,6 @@ class AngleTool extends AnnotationTool { } ); - // If rendering engine has been destroyed while rendering - if (!viewport.getRenderingEngine()) { - console.warn('Rendering Engine has been destroyed'); - return; - } - if (!data.cachedStats[targetId]?.angle) { continue; } @@ -686,6 +690,8 @@ class AngleTool extends AnnotationTool { bottomRight: viewport.canvasToWorld([left + width, top + height]), }; } + + return renderStatus; }; // text line for the current active length annotation diff --git a/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts b/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts index 3878a0a8ba..fbe7ed3620 100644 --- a/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts +++ b/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts @@ -564,7 +564,8 @@ class ArrowAnnotateTool extends AnnotationTool { renderAnnotation = ( enabledElement: Types.IEnabledElement, svgDrawingHelper: any - ): void => { + ): boolean => { + let renderStatus = false; const { viewport } = enabledElement; const { element } = viewport; @@ -572,7 +573,7 @@ class ArrowAnnotateTool extends AnnotationTool { // Todo: We don't need this anymore, filtering happens in triggerAnnotationRender if (!annotations?.length) { - return; + return renderStatus; } annotations = this.filterInteractableAnnotationsForElement( @@ -581,7 +582,7 @@ class ArrowAnnotateTool extends AnnotationTool { ); if (!annotations?.length) { - return; + return renderStatus; } const styleSpecifier: StyleSpecifier = { @@ -660,10 +661,12 @@ class ArrowAnnotateTool extends AnnotationTool { ); } + renderStatus = true; + // If rendering engine has been destroyed while rendering if (!viewport.getRenderingEngine()) { console.warn('Rendering Engine has been destroyed'); - return; + return renderStatus; } if (!text) { @@ -703,6 +706,8 @@ class ArrowAnnotateTool extends AnnotationTool { bottomRight: viewport.canvasToWorld([left + width, top + height]), }; } + + return renderStatus; }; _isInsideVolume(index1, index2, dimensions) { diff --git a/packages/tools/src/tools/annotation/BidirectionalTool.ts b/packages/tools/src/tools/annotation/BidirectionalTool.ts index 065ff8de90..af821d6af0 100644 --- a/packages/tools/src/tools/annotation/BidirectionalTool.ts +++ b/packages/tools/src/tools/annotation/BidirectionalTool.ts @@ -952,13 +952,14 @@ export default class BidirectionalTool extends AnnotationTool { renderAnnotation = ( enabledElement: Types.IEnabledElement, svgDrawingHelper: any - ): void => { + ): boolean => { + let renderStatus = true; const { viewport } = enabledElement; const { element } = viewport; let annotations = getAnnotations(viewport.element, this.getToolName()); if (!annotations?.length) { - return; + return renderStatus; } annotations = this.filterInteractableAnnotationsForElement( @@ -967,7 +968,7 @@ export default class BidirectionalTool extends AnnotationTool { ); if (!annotations?.length) { - return; + return renderStatus; } const targetId = this.getTargetId(viewport); @@ -1010,7 +1011,7 @@ export default class BidirectionalTool extends AnnotationTool { // If rendering engine has been destroyed while rendering if (!viewport.getRenderingEngine()) { console.warn('Rendering Engine has been destroyed'); - return; + return renderStatus; } let activeHandleCanvasCoords; @@ -1070,6 +1071,8 @@ export default class BidirectionalTool extends AnnotationTool { } ); + renderStatus = true; + const textLines = this._getTextLines(data, targetId); if (!textLines || textLines.length === 0) { @@ -1109,6 +1112,8 @@ export default class BidirectionalTool extends AnnotationTool { bottomRight: viewport.canvasToWorld([left + width, top + height]), }; } + + return renderStatus; }; _movingLongAxisWouldPutItThroughShortAxis = ( diff --git a/packages/tools/src/tools/annotation/DragProbeTool.ts b/packages/tools/src/tools/annotation/DragProbeTool.ts index 05ffc3fa81..5a1ab27906 100644 --- a/packages/tools/src/tools/annotation/DragProbeTool.ts +++ b/packages/tools/src/tools/annotation/DragProbeTool.ts @@ -106,11 +106,12 @@ export default class DragProbeTool extends ProbeTool { renderAnnotation = ( enabledElement: Types.IEnabledElement, svgDrawingHelper: any - ): void => { + ): boolean => { + let renderStatus = false; const { viewport } = enabledElement; if (!this.editData) { - return; + return renderStatus; } const targetId = this.getTargetId(viewport); @@ -147,7 +148,7 @@ export default class DragProbeTool extends ProbeTool { // If rendering engine has been destroyed while rendering if (!viewport.getRenderingEngine()) { console.warn('Rendering Engine has been destroyed'); - return; + return renderStatus; } const handleGroupUID = '0'; @@ -160,6 +161,8 @@ export default class DragProbeTool extends ProbeTool { { color } ); + renderStatus = true; + const textLines = this._getTextLines(data, targetId); if (textLines) { const textCanvasCoordinates = [ @@ -177,5 +180,7 @@ export default class DragProbeTool extends ProbeTool { this.getLinkedTextBoxStyle(styleSpecifier, annotation) ); } + + return renderStatus; }; } diff --git a/packages/tools/src/tools/annotation/EllipticalROITool.ts b/packages/tools/src/tools/annotation/EllipticalROITool.ts index d67f30edad..945b7ad383 100644 --- a/packages/tools/src/tools/annotation/EllipticalROITool.ts +++ b/packages/tools/src/tools/annotation/EllipticalROITool.ts @@ -705,14 +705,15 @@ export default class EllipticalROITool extends AnnotationTool { renderAnnotation = ( enabledElement: Types.IEnabledElement, svgDrawingHelper: any - ): void => { + ): boolean => { + let renderStatus = false; const { viewport } = enabledElement; const { element } = viewport; let annotations = getAnnotations(element, this.getToolName()); if (!annotations?.length) { - return; + return renderStatus; } annotations = this.filterInteractableAnnotationsForElement( @@ -721,7 +722,7 @@ export default class EllipticalROITool extends AnnotationTool { ); if (!annotations?.length) { - return; + return renderStatus; } const targetId = this.getTargetId(viewport); @@ -812,7 +813,7 @@ export default class EllipticalROITool extends AnnotationTool { // If rendering engine has been destroyed while rendering if (!viewport.getRenderingEngine()) { console.warn('Rendering Engine has been destroyed'); - return; + return renderStatus; } let activeHandleCanvasCoords; @@ -857,6 +858,8 @@ export default class EllipticalROITool extends AnnotationTool { } ); + renderStatus = true; + const textLines = this._getTextLines(data, targetId); if (!textLines || textLines.length === 0) { continue; @@ -897,6 +900,8 @@ export default class EllipticalROITool extends AnnotationTool { bottomRight: viewport.canvasToWorld([left + width, top + height]), }; } + + return renderStatus; }; _getTextLines = (data, targetId) => { diff --git a/packages/tools/src/tools/annotation/LengthTool.ts b/packages/tools/src/tools/annotation/LengthTool.ts index 256e5788fe..a47f25ba67 100644 --- a/packages/tools/src/tools/annotation/LengthTool.ts +++ b/packages/tools/src/tools/annotation/LengthTool.ts @@ -528,7 +528,8 @@ class LengthTool extends AnnotationTool { renderAnnotation = ( enabledElement: Types.IEnabledElement, svgDrawingHelper: any - ): void => { + ): boolean => { + let renderStatus = false; const { viewport } = enabledElement; const { element } = viewport; @@ -536,7 +537,7 @@ class LengthTool extends AnnotationTool { // Todo: We don't need this anymore, filtering happens in triggerAnnotationRender if (!annotations?.length) { - return; + return renderStatus; } annotations = this.filterInteractableAnnotationsForElement( @@ -545,7 +546,7 @@ class LengthTool extends AnnotationTool { ); if (!annotations?.length) { - return; + return renderStatus; } const targetId = this.getTargetId(viewport); @@ -631,10 +632,12 @@ class LengthTool extends AnnotationTool { } ); + renderStatus = true; + // If rendering engine has been destroyed while rendering if (!viewport.getRenderingEngine()) { console.warn('Rendering Engine has been destroyed'); - return; + return renderStatus; } const textLines = this._getTextLines(data, targetId); @@ -672,6 +675,8 @@ class LengthTool extends AnnotationTool { bottomRight: viewport.canvasToWorld([left + width, top + height]), }; } + + return renderStatus; }; // text line for the current active length annotation diff --git a/packages/tools/src/tools/annotation/PlanarFreehandROITool.ts b/packages/tools/src/tools/annotation/PlanarFreehandROITool.ts index 03a7959a42..392d7547d2 100644 --- a/packages/tools/src/tools/annotation/PlanarFreehandROITool.ts +++ b/packages/tools/src/tools/annotation/PlanarFreehandROITool.ts @@ -504,7 +504,8 @@ class PlanarFreehandROITool extends AnnotationTool { renderAnnotation = ( enabledElement: Types.IEnabledElement, svgDrawingHelper: any - ): void => { + ): boolean => { + const renderStatus = false; const { viewport } = enabledElement; const { element } = viewport; @@ -514,7 +515,7 @@ class PlanarFreehandROITool extends AnnotationTool { // Todo: We don't need this anymore, filtering happens in triggerAnnotationRender if (!annotations?.length) { - return; + return renderStatus; } annotations = this.filterInteractableAnnotationsForElement( @@ -523,7 +524,7 @@ class PlanarFreehandROITool extends AnnotationTool { ) as PlanarFreehandROIAnnotation[]; if (!annotations?.length) { - return; + return renderStatus; } const isDrawing = this.isDrawing; @@ -537,7 +538,7 @@ class PlanarFreehandROITool extends AnnotationTool { this.renderContour(enabledElement, svgDrawingHelper, annotation) ); - return; + return renderStatus; } // One of the annotations will need special rendering treatment, render all @@ -574,6 +575,9 @@ class PlanarFreehandROITool extends AnnotationTool { this.renderContour(enabledElement, svgDrawingHelper, annotation); } }); + + // Todo: return boolean flag for each rendering route in the planar tool. + return true; }; } diff --git a/packages/tools/src/tools/annotation/ProbeTool.ts b/packages/tools/src/tools/annotation/ProbeTool.ts index 52c8b3728c..8eae8b2bcb 100644 --- a/packages/tools/src/tools/annotation/ProbeTool.ts +++ b/packages/tools/src/tools/annotation/ProbeTool.ts @@ -396,14 +396,15 @@ export default class ProbeTool extends AnnotationTool { renderAnnotation = ( enabledElement: Types.IEnabledElement, svgDrawingHelper: any - ): void => { + ): boolean => { + let renderStatus = false; const { viewport } = enabledElement; const { element } = viewport; let annotations = getAnnotations(element, this.getToolName()); if (!annotations?.length) { - return; + return renderStatus; } annotations = this.filterInteractableAnnotationsForElement( @@ -412,7 +413,7 @@ export default class ProbeTool extends AnnotationTool { ); if (!annotations?.length) { - return; + return renderStatus; } const targetId = this.getTargetId(viewport); @@ -485,7 +486,7 @@ export default class ProbeTool extends AnnotationTool { // If rendering engine has been destroyed while rendering if (!viewport.getRenderingEngine()) { console.warn('Rendering Engine has been destroyed'); - return; + return renderStatus; } const handleGroupUID = '0'; @@ -498,6 +499,8 @@ export default class ProbeTool extends AnnotationTool { { color } ); + renderStatus = true; + const textLines = this._getTextLines(data, targetId); if (textLines) { const textCanvasCoordinates = [ @@ -516,6 +519,8 @@ export default class ProbeTool extends AnnotationTool { ); } } + + return renderStatus; }; _getTextLines(data, targetId) { diff --git a/packages/tools/src/tools/annotation/RectangleROITool.ts b/packages/tools/src/tools/annotation/RectangleROITool.ts index 4077d67b32..b88c5fbdad 100644 --- a/packages/tools/src/tools/annotation/RectangleROITool.ts +++ b/packages/tools/src/tools/annotation/RectangleROITool.ts @@ -604,14 +604,15 @@ export default class RectangleROITool extends AnnotationTool { renderAnnotation = ( enabledElement: Types.IEnabledElement, svgDrawingHelper: any - ): void => { + ): boolean => { + let renderStatus = false; const { viewport } = enabledElement; const { element } = viewport; let annotations = getAnnotations(element, this.getToolName()); if (!annotations?.length) { - return; + return renderStatus; } annotations = this.filterInteractableAnnotationsForElement( @@ -620,7 +621,7 @@ export default class RectangleROITool extends AnnotationTool { ); if (!annotations?.length) { - return; + return renderStatus; } const targetId = this.getTargetId(viewport); @@ -710,7 +711,7 @@ export default class RectangleROITool extends AnnotationTool { // If rendering engine has been destroyed while rendering if (!viewport.getRenderingEngine()) { console.warn('Rendering Engine has been destroyed'); - return; + return renderStatus; } let activeHandleCanvasCoords; @@ -756,6 +757,8 @@ export default class RectangleROITool extends AnnotationTool { } ); + renderStatus = true; + const textLines = this._getTextLines(data, targetId); if (!textLines || textLines.length === 0) { continue; @@ -793,6 +796,8 @@ export default class RectangleROITool extends AnnotationTool { bottomRight: viewport.canvasToWorld([left + width, top + height]), }; } + + return renderStatus; }; _getRectangleImageCoordinates = ( diff --git a/packages/tools/src/tools/segmentation/CircleScissorsTool.ts b/packages/tools/src/tools/segmentation/CircleScissorsTool.ts index 9cba5bf0be..65c60e5b2a 100644 --- a/packages/tools/src/tools/segmentation/CircleScissorsTool.ts +++ b/packages/tools/src/tools/segmentation/CircleScissorsTool.ts @@ -299,16 +299,17 @@ export default class CircleScissorsTool extends BaseTool { renderAnnotation = ( enabledElement: Types.IEnabledElement, svgDrawingHelper: any - ): void => { + ): boolean => { + let renderStatus = false; if (!this.editData) { - return; + return renderStatus; } const { viewport } = enabledElement; const { viewportIdsToRender } = this.editData; if (!viewportIdsToRender.includes(viewport.id)) { - return; + return renderStatus; } const { annotation } = this.editData; @@ -336,7 +337,7 @@ export default class CircleScissorsTool extends BaseTool { // If rendering engine has been destroyed while rendering if (!viewport.getRenderingEngine()) { console.warn('Rendering Engine has been destroyed'); - return; + return renderStatus; } const circleUID = '0'; @@ -350,5 +351,8 @@ export default class CircleScissorsTool extends BaseTool { color, } ); + + renderStatus = true; + return renderStatus; }; } diff --git a/packages/tools/src/tools/segmentation/RectangleROIStartEndThresholdTool.ts b/packages/tools/src/tools/segmentation/RectangleROIStartEndThresholdTool.ts index c51d8efe9d..6d3dd6d572 100644 --- a/packages/tools/src/tools/segmentation/RectangleROIStartEndThresholdTool.ts +++ b/packages/tools/src/tools/segmentation/RectangleROIStartEndThresholdTool.ts @@ -297,14 +297,15 @@ export default class RectangleROIStartEndThresholdTool extends RectangleROITool renderAnnotation = ( enabledElement: Types.IEnabledElement, svgDrawingHelper: any - ): void => { + ): boolean => { + let renderStatus = false; const annotations = getAnnotations( enabledElement.viewport.element, this.getToolName() ); if (!annotations?.length) { - return; + return renderStatus; } const { viewport } = enabledElement; @@ -358,7 +359,7 @@ export default class RectangleROIStartEndThresholdTool extends RectangleROITool // If rendering engine has been destroyed while rendering if (!viewport.getRenderingEngine()) { console.warn('Rendering Engine has been destroyed'); - return; + return renderStatus; } let activeHandleCanvasCoords; @@ -410,7 +411,11 @@ export default class RectangleROIStartEndThresholdTool extends RectangleROITool lineWidth, } ); + + renderStatus = true; } + + return renderStatus; }; _getEndSliceIndex( diff --git a/packages/tools/src/tools/segmentation/RectangleROIThresholdTool.ts b/packages/tools/src/tools/segmentation/RectangleROIThresholdTool.ts index 792915f93e..adb97c26cc 100644 --- a/packages/tools/src/tools/segmentation/RectangleROIThresholdTool.ts +++ b/packages/tools/src/tools/segmentation/RectangleROIThresholdTool.ts @@ -165,13 +165,14 @@ export default class RectangleROIThresholdTool extends RectangleROITool { renderAnnotation = ( enabledElement: Types.IEnabledElement, svgDrawingHelper: any - ): void => { + ): boolean => { + let renderStatus = false; const { viewport, renderingEngineId } = enabledElement; const { element } = viewport; let annotations = getAnnotations(element, this.getToolName()); if (!annotations?.length) { - return; + return renderStatus; } annotations = this.filterInteractableAnnotationsForElement( @@ -180,7 +181,7 @@ export default class RectangleROIThresholdTool extends RectangleROITool { ); if (!annotations?.length) { - return; + return renderStatus; } const styleSpecifier: StyleSpecifier = { @@ -204,7 +205,7 @@ export default class RectangleROIThresholdTool extends RectangleROITool { // If rendering engine has been destroyed while rendering if (!viewport.getRenderingEngine()) { console.warn('Rendering Engine has been destroyed'); - return; + return renderStatus; } // Todo: This is not correct way to add the event trigger, @@ -262,6 +263,10 @@ export default class RectangleROIThresholdTool extends RectangleROITool { lineWidth, } ); + + renderStatus = true; } + + return renderStatus; }; } diff --git a/packages/tools/src/tools/segmentation/RectangleScissorsTool.ts b/packages/tools/src/tools/segmentation/RectangleScissorsTool.ts index e04fbfda17..111bbaa97f 100644 --- a/packages/tools/src/tools/segmentation/RectangleScissorsTool.ts +++ b/packages/tools/src/tools/segmentation/RectangleScissorsTool.ts @@ -334,9 +334,10 @@ export default class RectangleScissorsTool extends BaseTool { renderAnnotation = ( enabledElement: Types.IEnabledElement, svgDrawingHelper: any - ): void => { + ): boolean => { + let renderStatus = false; if (!this.editData) { - return; + return renderStatus; } const { viewport } = enabledElement; @@ -354,7 +355,7 @@ export default class RectangleScissorsTool extends BaseTool { // If rendering engine has been destroyed while rendering if (!viewport.getRenderingEngine()) { console.warn('Rendering Engine has been destroyed'); - return; + return renderStatus; } const rectangleUID = '0'; @@ -368,5 +369,9 @@ export default class RectangleScissorsTool extends BaseTool { color, } ); + + renderStatus = true; + + return renderStatus; }; } diff --git a/packages/tools/src/tools/segmentation/SphereScissorsTool.ts b/packages/tools/src/tools/segmentation/SphereScissorsTool.ts index 4ee1b5f3ee..8e341a75a0 100644 --- a/packages/tools/src/tools/segmentation/SphereScissorsTool.ts +++ b/packages/tools/src/tools/segmentation/SphereScissorsTool.ts @@ -300,16 +300,17 @@ export default class SphereScissorsTool extends BaseTool { renderAnnotation = ( enabledElement: Types.IEnabledElement, svgDrawingHelper: any - ): void => { + ): boolean => { + let renderStatus = false; if (!this.editData) { - return; + return renderStatus; } const { viewport } = enabledElement; const { viewportIdsToRender } = this.editData; if (!viewportIdsToRender.includes(viewport.id)) { - return; + return renderStatus; } const { annotation } = this.editData; @@ -337,7 +338,7 @@ export default class SphereScissorsTool extends BaseTool { // If rendering engine has been destroyed while rendering if (!viewport.getRenderingEngine()) { console.warn('Rendering Engine has been destroyed'); - return; + return renderStatus; } const circleUID = '0'; @@ -351,5 +352,9 @@ export default class SphereScissorsTool extends BaseTool { color, } ); + + renderStatus = true; + + return renderStatus; }; } diff --git a/packages/tools/src/utilities/triggerAnnotationRender.ts b/packages/tools/src/utilities/triggerAnnotationRender.ts index 2651008c6d..288fa9d662 100644 --- a/packages/tools/src/utilities/triggerAnnotationRender.ts +++ b/packages/tools/src/utilities/triggerAnnotationRender.ts @@ -6,8 +6,8 @@ import { import { Events, ToolModes } from '../enums'; import { draw as drawSvg } from '../drawingSvg'; import getToolsWithModesForElement from './getToolsWithModesForElement'; -import SegmentationDisplayTool from '../tools/displayTools/SegmentationDisplayTool'; import { AnnotationRenderedEventDetail } from '../types/EventTypes'; +import { getAnnotations } from '../stateManagement'; const { Active, Passive, Enabled } = ToolModes; @@ -159,27 +159,28 @@ class AnnotationRenderingEngine { viewportId, }; - // const enabledToolsWithAnnotations = enabledTools.filter((tool) => { - // const annotations = getAnnotations(element, (tool.constructor as typeof BaseTool).toolName) - // return annotations && annotations.length - // }) + const enabledToolsWithAnnotations = enabledTools.filter((tool) => { + const annotations = getAnnotations(element, tool.getToolName()); + return annotations && annotations.length; + }); drawSvg(element, (svgDrawingHelper) => { + let anyRendered = false; const handleDrawSvg = (tool) => { - // Todo: we should not have the need to check tool if it is instance - // of SegmentationDisplayTool, but right now SegmentationScissors - // are instance of BaseTool and we cannot simply check if tool is - // instance of AnnotationTool - if ( - !(tool instanceof SegmentationDisplayTool) && - tool.renderAnnotation - ) { - tool.renderAnnotation(enabledElement, svgDrawingHelper); - triggerEvent(element, Events.ANNOTATION_RENDERED, { ...eventDetail }); + if (tool.renderAnnotation) { + const rendered = tool.renderAnnotation( + enabledElement, + svgDrawingHelper + ); + anyRendered = anyRendered || rendered; } }; - enabledTools.forEach(handleDrawSvg); + enabledToolsWithAnnotations.forEach(handleDrawSvg); + + if (anyRendered) { + triggerEvent(element, Events.ANNOTATION_RENDERED, { ...eventDetail }); + } }); } From d1e57c98350cff707ea4868e3c6b749d00cfade1 Mon Sep 17 00:00:00 2001 From: Alireza Date: Mon, 6 Jun 2022 15:22:31 -0400 Subject: [PATCH 02/10] fix: do not trigger event for stack cache --- .../core/src/RenderingEngine/StackViewport.ts | 36 +++++++++++-------- .../core/src/types/StackViewportProperties.ts | 2 ++ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/packages/core/src/RenderingEngine/StackViewport.ts b/packages/core/src/RenderingEngine/StackViewport.ts index bdf3d4657b..8b86e1dc44 100644 --- a/packages/core/src/RenderingEngine/StackViewport.ts +++ b/packages/core/src/RenderingEngine/StackViewport.ts @@ -524,16 +524,19 @@ class StackViewport extends Viewport implements IStackViewport { * @param interpolationType - Changes the interpolation type (1:linear, 0: nearest) * @param rotation - image rotation in degrees */ - public setProperties({ - voiRange, - invert, - interpolationType, - rotation, - }: StackViewportProperties = {}): void { + public setProperties( + { + voiRange, + invert, + interpolationType, + rotation, + suppressEvents, + }: StackViewportProperties = { suppressEvents: false } + ) { // if voi is not applied for the first time, run the setVOI function // which will apply the default voi if (typeof voiRange !== 'undefined' || !this.voiApplied) { - this.setVOI(voiRange); + this.setVOI(voiRange, suppressEvents); } if (typeof invert !== 'undefined') { @@ -625,6 +628,7 @@ class StackViewport extends Viewport implements IStackViewport { rotation: this.rotation, interpolationType: this.interpolationType, invert: this.invert, + suppressEvents: true, }); } @@ -742,13 +746,13 @@ class StackViewport extends Viewport implements IStackViewport { this.flipVertical = viewport.vflip; } - private setVOI(voiRange: VOIRange): void { + private setVOI(voiRange: VOIRange, suppressEvents?: boolean): void { if (this.useCPURendering) { - this.setVOICPU(voiRange); + this.setVOICPU(voiRange, suppressEvents); return; } - this.setVOIGPU(voiRange); + this.setVOIGPU(voiRange, suppressEvents); } private setRotation(rotationCache: number, rotation: number): void { @@ -873,7 +877,7 @@ class StackViewport extends Viewport implements IStackViewport { this.invert = invert; } - private setVOICPU(voiRange: VOIRange): void { + private setVOICPU(voiRange: VOIRange, suppressEvents?: boolean): void { const { viewport, image } = this._cpuFallbackEnabledElement; if (!viewport || !image) { @@ -917,10 +921,12 @@ class StackViewport extends Viewport implements IStackViewport { range: voiRange, }; - triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail); + if (!suppressEvents) { + triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail); + } } - private setVOIGPU(voiRange: VOIRange): void { + private setVOIGPU(voiRange: VOIRange, suppressEvents?: boolean): void { const defaultActor = this.getDefaultActor(); if (!defaultActor) { return; @@ -951,7 +957,9 @@ class StackViewport extends Viewport implements IStackViewport { range: voiRange, }; - triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail); + if (!suppressEvents) { + triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail); + } } /** diff --git a/packages/core/src/types/StackViewportProperties.ts b/packages/core/src/types/StackViewportProperties.ts index b6e8dcd240..3a32e51bf9 100644 --- a/packages/core/src/types/StackViewportProperties.ts +++ b/packages/core/src/types/StackViewportProperties.ts @@ -13,6 +13,8 @@ type StackViewportProperties = { interpolationType?: InterpolationType; /** image rotation */ rotation?: number; + /** suppress events (optional) */ + suppressEvents?: boolean; }; export default StackViewportProperties; From c2f6eff5db2fd0abb22e093964a77cc1e9a9aece Mon Sep 17 00:00:00 2001 From: Alireza Date: Tue, 7 Jun 2022 08:50:57 -0400 Subject: [PATCH 03/10] fix: zoom tool for cpu rendered images --- packages/tools/src/tools/ZoomTool.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/tools/src/tools/ZoomTool.ts b/packages/tools/src/tools/ZoomTool.ts index ff85e0800f..9ed4876e46 100644 --- a/packages/tools/src/tools/ZoomTool.ts +++ b/packages/tools/src/tools/ZoomTool.ts @@ -144,6 +144,19 @@ export default class ZoomTool extends BaseTool { ) as Types.Point3; } + const customViewport = + Object.getPrototypeOf(viewport).constructor.useCustomRenderingPipeline; + + // If it is a custom viewport, we can't rely on parallel scale physical + // values to determine if the threshold is exceeded. + if (customViewport) { + viewport.setCamera({ + parallelScale: newParallelScale, + }); + + return; + } + const { parallelScale: cappedParallelScale, thresholdExceeded } = this._getCappedParallelScale(viewport, newParallelScale); @@ -189,7 +202,10 @@ export default class ZoomTool extends BaseTool { viewport.setCamera({ position, focalPoint }); }; - _getCappedParallelScale = (viewport, parallelScale) => { + _getCappedParallelScale = ( + viewport: Types.IStackViewport | Types.IVolumeViewport, + parallelScale: number + ): { parallelScale: number; thresholdExceeded: boolean } => { const imageData = viewport.getImageData(); if (!imageData) { From 9e43d39f22cca0c179a5c4e804d582e0dca38694 Mon Sep 17 00:00:00 2001 From: Alireza Date: Tue, 7 Jun 2022 09:17:33 -0400 Subject: [PATCH 04/10] update api --- common/reviews/api/core.api.md | 3 +- .../api/streaming-image-volume-loader.api.md | 1 + common/reviews/api/tools.api.md | 35 ++++++++++--------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/common/reviews/api/core.api.md b/common/reviews/api/core.api.md index 33c7669141..7ad63cfc7e 100644 --- a/common/reviews/api/core.api.md +++ b/common/reviews/api/core.api.md @@ -1696,7 +1696,7 @@ export class StackViewport extends Viewport implements IStackViewport { // (undocumented) setImageIdIndex(imageIdIndex: number): Promise; // (undocumented) - setProperties({ voiRange, invert, interpolationType, rotation, }?: StackViewportProperties): void; + setProperties({ voiRange, invert, interpolationType, rotation, suppressEvents, }?: StackViewportProperties): void; // (undocumented) setStack(imageIds: Array, currentImageIdIndex?: number): Promise; // (undocumented) @@ -1724,6 +1724,7 @@ type StackViewportProperties = { invert?: boolean; interpolationType?: InterpolationType; rotation?: number; + suppressEvents?: boolean; }; // @public (undocumented) diff --git a/common/reviews/api/streaming-image-volume-loader.api.md b/common/reviews/api/streaming-image-volume-loader.api.md index 07f7f94f35..d4bfaa2576 100644 --- a/common/reviews/api/streaming-image-volume-loader.api.md +++ b/common/reviews/api/streaming-image-volume-loader.api.md @@ -1109,6 +1109,7 @@ type StackViewportProperties = { invert?: boolean; interpolationType?: InterpolationType; rotation?: number; + suppressEvents?: boolean; }; // @public (undocumented) diff --git a/common/reviews/api/tools.api.md b/common/reviews/api/tools.api.md index fa1d89ae23..8e12cd07d1 100644 --- a/common/reviews/api/tools.api.md +++ b/common/reviews/api/tools.api.md @@ -140,7 +140,7 @@ export class AngleTool extends AnnotationTool { // (undocumented) _mouseUpCallback: (evt: EventTypes_2.MouseUpEventType | EventTypes_2.MouseClickEventType) => void; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => void; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -391,7 +391,7 @@ export class ArrowAnnotateTool extends AnnotationTool { // (undocumented) _mouseUpCallback: (evt: EventTypes_2.MouseUpEventType | EventTypes_2.MouseClickEventType) => void; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => void; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -535,7 +535,7 @@ export class BidirectionalTool extends AnnotationTool { // (undocumented) preventHandleOutsideImage: boolean; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => void; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -647,7 +647,7 @@ export class CircleScissorsTool extends BaseTool { // (undocumented) preMouseDownCallback: (evt: EventTypes_2.MouseDownActivateEventType) => boolean; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => void; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; // (undocumented) static toolName: string; } @@ -1085,7 +1085,7 @@ export class CrosshairsTool extends AnnotationTool { // (undocumented) _pointNearTool(element: any, annotation: any, canvasCoords: any, proximity: any): boolean; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => void; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; // (undocumented) setSlabThickness(viewport: any, slabThickness: any): void; // (undocumented) @@ -1195,7 +1195,7 @@ export class DragProbeTool extends ProbeTool { // (undocumented) postMouseDownCallback: (evt: EventTypes_2.MouseDownActivateEventType) => ProbeAnnotation; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => void; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; // (undocumented) static toolName: string; // (undocumented) @@ -1374,7 +1374,7 @@ export class EllipticalROITool extends AnnotationTool { // (undocumented) _pointInEllipseCanvas(ellipse: any, location: Types_2.Point2): boolean; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => void; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -2554,7 +2554,7 @@ export class LengthTool extends AnnotationTool { // (undocumented) _mouseUpCallback: (evt: EventTypes_2.MouseUpEventType | EventTypes_2.MouseClickEventType) => void; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => void; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -2904,7 +2904,7 @@ export class PlanarFreehandROITool extends AnnotationTool { // (undocumented) mouseDragCallback: any; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => void; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -3044,7 +3044,7 @@ export class ProbeTool extends AnnotationTool { // (undocumented) _mouseUpCallback: (evt: EventTypes_2.MouseUpEventType | EventTypes_2.MouseClickEventType) => void; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => void; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; // (undocumented) static toolName: string; // (undocumented) @@ -3192,7 +3192,7 @@ export class RectangleROIStartEndThresholdTool extends RectangleROITool { // (undocumented) isHandleOutsideImage: boolean; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => void; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -3267,7 +3267,7 @@ export class RectangleROIThresholdTool extends RectangleROITool { // (undocumented) isHandleOutsideImage: boolean; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => void; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -3327,7 +3327,7 @@ export class RectangleROITool extends AnnotationTool { // (undocumented) _mouseUpCallback: (evt: EventTypes_2.MouseUpEventType | EventTypes_2.MouseClickEventType) => void; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => void; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -3374,7 +3374,7 @@ export class RectangleScissorsTool extends BaseTool { // (undocumented) preMouseDownCallback: (evt: EventTypes_2.MouseDownActivateEventType) => boolean; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => void; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -3696,7 +3696,7 @@ export class SphereScissorsTool extends BaseTool { // (undocumented) preMouseDownCallback: (evt: EventTypes_2.MouseDownActivateEventType) => true; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => void; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; // (undocumented) static toolName: string; } @@ -3776,6 +3776,7 @@ type StackViewportProperties = { invert?: boolean; interpolationType?: InterpolationType; rotation?: number; + suppressEvents?: boolean; }; // @public (undocumented) @@ -4370,8 +4371,8 @@ export class ZoomTool extends BaseTool { // (undocumented) _dragPerspectiveProjection: (evt: any, camera: any) => void; // (undocumented) - _getCappedParallelScale: (viewport: any, parallelScale: any) => { - parallelScale: any; + _getCappedParallelScale: (viewport: Types_2.IStackViewport | Types_2.IVolumeViewport, parallelScale: number) => { + parallelScale: number; thresholdExceeded: boolean; }; // (undocumented) From 2beb697fc30016f234b79a46582e70472a083e2b Mon Sep 17 00:00:00 2001 From: Alireza Date: Wed, 8 Jun 2022 12:23:34 -0400 Subject: [PATCH 05/10] apply review comments --- .../core/src/RenderingEngine/StackViewport.ts | 23 ++++++----- .../examples/stackAnnotationTools/index.ts | 5 +++ packages/tools/src/tools/CrosshairsTool.ts | 38 +++++++++---------- .../src/utilities/triggerAnnotationRender.ts | 18 +++++---- 4 files changed, 47 insertions(+), 37 deletions(-) diff --git a/packages/core/src/RenderingEngine/StackViewport.ts b/packages/core/src/RenderingEngine/StackViewport.ts index 8b86e1dc44..9e148fc2d5 100644 --- a/packages/core/src/RenderingEngine/StackViewport.ts +++ b/packages/core/src/RenderingEngine/StackViewport.ts @@ -530,9 +530,9 @@ class StackViewport extends Viewport implements IStackViewport { invert, interpolationType, rotation, - suppressEvents, - }: StackViewportProperties = { suppressEvents: false } - ) { + }: StackViewportProperties = {}, + suppressEvents = false + ): void { // if voi is not applied for the first time, run the setVOI function // which will apply the default voi if (typeof voiRange !== 'undefined' || !this.voiApplied) { @@ -623,13 +623,16 @@ class StackViewport extends Viewport implements IStackViewport { } private _setPropertiesFromCache(): void { - this.setProperties({ - voiRange: this.voiRange, - rotation: this.rotation, - interpolationType: this.interpolationType, - invert: this.invert, - suppressEvents: true, - }); + const suppressEvents = true; + this.setProperties( + { + voiRange: this.voiRange, + rotation: this.rotation, + interpolationType: this.interpolationType, + invert: this.invert, + }, + suppressEvents + ); } private getCameraCPU(): Partial { diff --git a/packages/tools/examples/stackAnnotationTools/index.ts b/packages/tools/examples/stackAnnotationTools/index.ts index 57abbedb09..92a48a66b5 100644 --- a/packages/tools/examples/stackAnnotationTools/index.ts +++ b/packages/tools/examples/stackAnnotationTools/index.ts @@ -20,6 +20,7 @@ const { BidirectionalTool, AngleTool, ToolGroupManager, + ArrowAnnotateTool, Enums: csToolsEnums, } = cornerstoneTools; @@ -59,6 +60,7 @@ const toolsNames = [ EllipticalROITool.toolName, BidirectionalTool.toolName, AngleTool.toolName, + ArrowAnnotateTool.toolName, ]; let selectedToolName = toolsNames[0]; @@ -98,6 +100,7 @@ async function run() { cornerstoneTools.addTool(EllipticalROITool); cornerstoneTools.addTool(BidirectionalTool); cornerstoneTools.addTool(AngleTool); + cornerstoneTools.addTool(ArrowAnnotateTool); // Define a tool group, which defines how mouse events map to tool commands for // Any viewport using the group @@ -110,6 +113,7 @@ async function run() { toolGroup.addTool(EllipticalROITool.toolName); toolGroup.addTool(BidirectionalTool.toolName); toolGroup.addTool(AngleTool.toolName); + toolGroup.addTool(ArrowAnnotateTool.toolName); // Set the initial state of the tools, here we set one tool active on left click. // This means left click will draw that tool. @@ -127,6 +131,7 @@ async function run() { toolGroup.setToolPassive(EllipticalROITool.toolName); toolGroup.setToolPassive(BidirectionalTool.toolName); toolGroup.setToolPassive(AngleTool.toolName); + toolGroup.setToolPassive(ArrowAnnotateTool.toolName); // Get Cornerstone imageIds and fetch metadata into RAM const imageIds = await createImageIdsAndCacheMetaData({ diff --git a/packages/tools/src/tools/CrosshairsTool.ts b/packages/tools/src/tools/CrosshairsTool.ts index 3a4c072639..dd8ded5acb 100644 --- a/packages/tools/src/tools/CrosshairsTool.ts +++ b/packages/tools/src/tools/CrosshairsTool.ts @@ -1295,28 +1295,26 @@ export default class CrosshairsTool extends AnnotationTool { data.handles.rotationPoints = newRtpoints; data.handles.slabThicknessPoints = newStpoints; - if (!this.configuration.viewportIndicators) { - return renderStatus; + if (this.configuration.viewportIndicators) { + // render a circle to pin point the viewport color + // TODO: This should not be part of the tool, and definitely not part of the renderAnnotation loop + const referenceColorCoordinates = [ + sWidth * 0.95, + sHeight * 0.05, + ] as Types.Point2; + const circleRadius = canvasDiagonalLength * 0.01; + + const circleUID = '0'; + drawCircleSvg( + svgDrawingHelper, + annotationUID, + circleUID, + referenceColorCoordinates, + circleRadius, + { color, fill: color } + ); } - // render a circle to pin point the viewport color - // TODO: This should not be part of the tool, and definitely not part of the renderAnnotation loop - const referenceColorCoordinates = [ - sWidth * 0.95, - sHeight * 0.05, - ] as Types.Point2; - const circleRadius = canvasDiagonalLength * 0.01; - - const circleUID = '0'; - drawCircleSvg( - svgDrawingHelper, - annotationUID, - circleUID, - referenceColorCoordinates, - circleRadius, - { color, fill: color } - ); - return renderStatus; }; diff --git a/packages/tools/src/utilities/triggerAnnotationRender.ts b/packages/tools/src/utilities/triggerAnnotationRender.ts index 288fa9d662..d85d4a6751 100644 --- a/packages/tools/src/utilities/triggerAnnotationRender.ts +++ b/packages/tools/src/utilities/triggerAnnotationRender.ts @@ -7,8 +7,6 @@ import { Events, ToolModes } from '../enums'; import { draw as drawSvg } from '../drawingSvg'; import getToolsWithModesForElement from './getToolsWithModesForElement'; import { AnnotationRenderedEventDetail } from '../types/EventTypes'; -import { getAnnotations } from '../stateManagement'; - const { Active, Passive, Enabled } = ToolModes; /** @@ -159,10 +157,10 @@ class AnnotationRenderingEngine { viewportId, }; - const enabledToolsWithAnnotations = enabledTools.filter((tool) => { - const annotations = getAnnotations(element, tool.getToolName()); - return annotations && annotations.length; - }); + // const enabledToolsWithAnnotations = enabledTools.filter((tool) => { + // const annotations = getAnnotations(element, tool.getToolName()); + // return annotations && annotations.length; + // }); drawSvg(element, (svgDrawingHelper) => { let anyRendered = false; @@ -176,7 +174,13 @@ class AnnotationRenderingEngine { } }; - enabledToolsWithAnnotations.forEach(handleDrawSvg); + /** + * We should be able to filter tools that don't have annotations, but + * currently some of tools have renderAnnotation method BUT + * don't keep annotation in the state, so if we do so, the tool will not be + * rendered. + */ + enabledTools.forEach(handleDrawSvg); if (anyRendered) { triggerEvent(element, Events.ANNOTATION_RENDERED, { ...eventDetail }); From 46030b331ba1b67c726d2030ead6111dfb7ce8db Mon Sep 17 00:00:00 2001 From: Alireza Date: Thu, 9 Jun 2022 14:19:24 -0400 Subject: [PATCH 06/10] fix: consistent camera CPU api --- .../core/src/RenderingEngine/StackViewport.ts | 97 +++++++++++++------ .../helpers/cpuFallback/drawImageSync.ts | 1 - .../helpers/createVolumeActor.ts | 2 +- packages/core/src/metaData.ts | 2 +- .../core/src/types/CPUFallbackViewport.ts | 2 + packages/core/src/types/ICamera.ts | 6 +- .../src/helpers/autoLoad.ts | 3 +- packages/tools/src/tools/ZoomTool.ts | 87 ++++++----------- 8 files changed, 110 insertions(+), 90 deletions(-) diff --git a/packages/core/src/RenderingEngine/StackViewport.ts b/packages/core/src/RenderingEngine/StackViewport.ts index 9e148fc2d5..c93e18f7c3 100644 --- a/packages/core/src/RenderingEngine/StackViewport.ts +++ b/packages/core/src/RenderingEngine/StackViewport.ts @@ -636,7 +636,7 @@ class StackViewport extends Viewport implements IStackViewport { } private getCameraCPU(): Partial { - const { metadata, viewport } = this._cpuFallbackEnabledElement; + const { metadata, viewport, image } = this._cpuFallbackEnabledElement; const { direction } = metadata; // focalPoint and position of CPU camera is just a placeholder since @@ -659,11 +659,22 @@ class StackViewport extends Viewport implements IStackViewport { ) as Float32Array; } + const canvasCenter: Point2 = [ + this.element.clientWidth / 2, + this.element.clientHeight / 2, + ]; + + // Focal point is the center of the canvas in world coordinate by design + const canvasCenterWorld = this.canvasToWorld(canvasCenter); + return { parallelProjection: true, - focalPoint: [0, 0, 0], + focalPoint: canvasCenterWorld, position: [0, 0, 0], - parallelScale: viewport.scale, + parallelScale: image + ? (image.width * image.columnPixelSpacing) / viewport.scale + : 1, + scale: viewport.scale, viewPlaneNormal: [ viewPlaneNormal[0], viewPlaneNormal[1], @@ -674,57 +685,76 @@ class StackViewport extends Viewport implements IStackViewport { } private setCameraCPU(cameraInterface: ICamera): void { - const { viewport } = this._cpuFallbackEnabledElement; + const { viewport, image } = this._cpuFallbackEnabledElement; const previousCamera = this.getCameraCPU(); - const { focalPoint, viewUp, parallelScale, flipHorizontal, flipVertical } = - cameraInterface; + const { + focalPoint, + viewUp, + parallelScale, + scale, + flipHorizontal, + flipVertical, + } = cameraInterface; if (focalPoint) { - const focalPointCanvas = this.worldToCanvasCPU( - cameraInterface.focalPoint + const focalPointCanvas = this.worldToCanvasCPU(focalPoint); + const focalPointPixel = canvasToPixel( + this._cpuFallbackEnabledElement, + focalPointCanvas ); - const previousFocalPointCanvas = this.worldToCanvasCPU( + + const prevFocalPointCanvas = this.worldToCanvasCPU( previousCamera.focalPoint ); + const prevFocalPointPixel = canvasToPixel( + this._cpuFallbackEnabledElement, + prevFocalPointCanvas + ); - const deltaCanvas = vec2.create(); - + const deltaPixel = vec2.create(); vec2.subtract( - deltaCanvas, - vec2.fromValues( - previousFocalPointCanvas[0], - previousFocalPointCanvas[1] - ), - vec2.fromValues(focalPointCanvas[0], focalPointCanvas[1]) + deltaPixel, + vec2.fromValues(focalPointPixel[0], focalPointPixel[1]), + vec2.fromValues(prevFocalPointPixel[0], prevFocalPointPixel[1]) ); - viewport.translation.x += deltaCanvas[0] / previousCamera.parallelScale; - viewport.translation.y += deltaCanvas[1] / previousCamera.parallelScale; + viewport.translation.x -= deltaPixel[0]; + viewport.translation.y -= deltaPixel[1]; } - // If manipulating scale - if (parallelScale && previousCamera.parallelScale !== parallelScale) { - // Note: as parallel scale is defined differently to the GPU version, - // We instead need to find the difference and move the camera in - // the other direction in this adapter. + if (parallelScale) { + // We need to convert he parallelScale which has a physical meaning for + // camera scale factor to scale (since CPU works with scale) + const { columnPixelSpacing } = image; + const scale = (image.width * columnPixelSpacing) / parallelScale; - const diff = previousCamera.parallelScale - parallelScale; + viewport.scale = scale; + viewport.parallelScale = parallelScale; + } - viewport.scale += diff; // parallelScale; //viewport.scale < 0.1 ? 0.1 : viewport.scale; + if (scale) { + viewport.scale = scale; + viewport.parallelScale = (image.width * image.columnPixelSpacing) / scale; } if (flipHorizontal || flipVertical) { this.setFlipCPU({ flipHorizontal, flipVertical }); } + // re-calculate the transforms + this._cpuFallbackEnabledElement.transform = calculateTransform( + this._cpuFallbackEnabledElement + ); + const updatedCamera = { ...previousCamera, focalPoint, viewUp, - parallelScale, flipHorizontal, flipVertical, + parallelScale: viewport.parallelScale, + scale: viewport.scale, }; const eventDetail: EventTypes.CameraModifiedEventDetail = { @@ -1784,6 +1814,19 @@ class StackViewport extends Viewport implements IStackViewport { } resetCamera(this._cpuFallbackEnabledElement, resetPan, resetZoom); + + const { scale } = this._cpuFallbackEnabledElement.viewport; + + // canvas center is the focal point + const { clientWidth, clientHeight } = this.element; + const center: Point2 = [clientWidth / 2, clientHeight / 2]; + + const centerWorld = this.canvasToWorldCPU(center); + + this.setCameraCPU({ + focalPoint: centerWorld, + scale, + }); } private resetCameraGPU(resetPan, resetZoom): boolean { diff --git a/packages/core/src/RenderingEngine/helpers/cpuFallback/drawImageSync.ts b/packages/core/src/RenderingEngine/helpers/cpuFallback/drawImageSync.ts index 5c8bc9c5c6..b9def4e363 100644 --- a/packages/core/src/RenderingEngine/helpers/cpuFallback/drawImageSync.ts +++ b/packages/core/src/RenderingEngine/helpers/cpuFallback/drawImageSync.ts @@ -15,7 +15,6 @@ export default function ( invalidated: boolean ): void { const image = enabledElement.image; - const canvas = enabledElement.canvas; // Check if enabledElement can be redrawn if (!enabledElement.canvas || !enabledElement.image) { diff --git a/packages/core/src/RenderingEngine/helpers/createVolumeActor.ts b/packages/core/src/RenderingEngine/helpers/createVolumeActor.ts index 4ce2a5f7a2..a3c7d37001 100644 --- a/packages/core/src/RenderingEngine/helpers/createVolumeActor.ts +++ b/packages/core/src/RenderingEngine/helpers/createVolumeActor.ts @@ -11,7 +11,7 @@ import setDefaultVolumeVOI from './setDefaultVolumeVOI'; interface createVolumeActorInterface { volumeId: string; - callback?: ({ volumeActor: any, volumeId: string }) => void; + callback?: ({ volumeActor: VolumeActor, volumeId: string }) => void; blendMode?: BlendModes; } diff --git a/packages/core/src/metaData.ts b/packages/core/src/metaData.ts index 034401d530..c31eb4e312 100644 --- a/packages/core/src/metaData.ts +++ b/packages/core/src/metaData.ts @@ -70,7 +70,7 @@ export function removeAllProviders(): void { * @returns The metadata retrieved from the metadata store * @category MetaData */ -function getMetaData(type: string, imageId: string): any { +function getMetaData(type: string, imageId: string): unknown { // Invoke each provider in priority order until one returns something for (let i = 0; i < providers.length; i++) { const result = providers[i].provider(type, imageId); diff --git a/packages/core/src/types/CPUFallbackViewport.ts b/packages/core/src/types/CPUFallbackViewport.ts index b8070ce9f4..6619e11699 100644 --- a/packages/core/src/types/CPUFallbackViewport.ts +++ b/packages/core/src/types/CPUFallbackViewport.ts @@ -4,6 +4,8 @@ import CPUFallbackLUT from './CPUFallbackLUT'; type CPUFallbackViewport = { scale?: number; + parallelScale?: number; + focalPoint?: number[]; translation?: { x: number; y: number; diff --git a/packages/core/src/types/ICamera.ts b/packages/core/src/types/ICamera.ts index beb6b2200e..981c0760a8 100644 --- a/packages/core/src/types/ICamera.ts +++ b/packages/core/src/types/ICamera.ts @@ -1,4 +1,3 @@ -import Point2 from './Point2'; import Point3 from './Point3'; /** @@ -12,6 +11,11 @@ interface ICamera { parallelProjection?: boolean; /** Camera parallel scale - used for parallel projection zoom, smaller values zoom in */ parallelScale?: number; + /** + * Scale factor for the camera, it is the ratio of how much an image pixel takes + * up one screen pixel + */ + scale?: number; /** Camera position */ position?: Point3; /** Camera view angle - 90 degrees is orthographic */ diff --git a/packages/streaming-image-volume-loader/src/helpers/autoLoad.ts b/packages/streaming-image-volume-loader/src/helpers/autoLoad.ts index 7a2686e7ac..dd3d74d92a 100644 --- a/packages/streaming-image-volume-loader/src/helpers/autoLoad.ts +++ b/packages/streaming-image-volume-loader/src/helpers/autoLoad.ts @@ -1,9 +1,10 @@ import { getRenderingEngines, utilities } from '@cornerstonejs/core'; +import type { Types } from '@cornerstonejs/core'; //import type { Types } from '@cornerstonejs/core' type RenderingEngineAndViewportIds = { - renderingEngine: any | undefined; //Types.IRenderingEngine | undefined + renderingEngine: Types.IRenderingEngine | undefined; //Types.IRenderingEngine | undefined viewportIds: Array; }; diff --git a/packages/tools/src/tools/ZoomTool.ts b/packages/tools/src/tools/ZoomTool.ts index 9ed4876e46..811c0ee713 100644 --- a/packages/tools/src/tools/ZoomTool.ts +++ b/packages/tools/src/tools/ZoomTool.ts @@ -16,8 +16,6 @@ export default class ZoomTool extends BaseTool { mouseDragCallback: () => void; initialMousePosWorld: Types.Point3; dirVec: Types.Point3; - minZoomScale = 0.1; - maxZoomScale = 10; // Apparently TS says super _must_ be the first call? This seems a bit opinionated. constructor( @@ -27,6 +25,8 @@ export default class ZoomTool extends BaseTool { configuration: { // whether zoom to the center of the image OR zoom to the mouse position zoomToCenter: false, + minZoomScale: 0.1, + maxZoomScale: 30, }, } ) { @@ -83,9 +83,9 @@ export default class ZoomTool extends BaseTool { const camera = viewport.getCamera(); if (camera.parallelProjection) { - this._dragParallelProjection(evt, camera); + this._dragParallelProjection(evt, viewport, camera); } else { - this._dragPerspectiveProjection(evt, camera); + this._dragPerspectiveProjection(evt, viewport, camera); } viewport.render(); @@ -93,20 +93,19 @@ export default class ZoomTool extends BaseTool { _dragParallelProjection = ( evt: EventTypes.MouseDragEventType, + viewport: Types.IStackViewport | Types.IVolumeViewport, camera: Types.ICamera - ) => { + ): void => { const { element, deltaPoints } = evt.detail; - const enabledElement = getEnabledElement(element); - const { viewport } = enabledElement; - const size = [element.clientWidth, element.clientHeight]; + const size = [element.clientWidth, element.clientHeight]; const { parallelScale, focalPoint, position } = camera; const zoomScale = 1.5 / size[1]; const deltaY = deltaPoints.canvas[1]; const k = deltaY * zoomScale; - let newParallelScale = (1.0 - k) * parallelScale; + let parallelScaleToSet = (1.0 - k) * parallelScale; let focalPointToSet = focalPoint; let positionToSet = position; @@ -121,13 +120,14 @@ export default class ZoomTool extends BaseTool { focalPoint, this.initialMousePosWorld ); + // const initialYDistanceBetweenInitialAndFocalPoint; // we need to move in the direction of the vector between the focal point // and the initial mouse position by some amount until ultimately we // reach the mouse position at the focal point - const zoomScale = 10 / size[1]; + const zoomScale = 5 / size[1]; const k = deltaY * zoomScale; - newParallelScale = (1.0 - k) * parallelScale; + parallelScaleToSet = (1.0 - k) * parallelScale; positionToSet = vec3.scaleAndAdd( vec3.create(), @@ -144,21 +144,26 @@ export default class ZoomTool extends BaseTool { ) as Types.Point3; } - const customViewport = - Object.getPrototypeOf(viewport).constructor.useCustomRenderingPipeline; + // If it is a regular GPU accelerated viewport, then parallel scale + // has a physical meaning and we can use that to determine the threshold + const imageData = viewport.getImageData(); - // If it is a custom viewport, we can't rely on parallel scale physical - // values to determine if the threshold is exceeded. - if (customViewport) { - viewport.setCamera({ - parallelScale: newParallelScale, - }); + const { dimensions, spacing } = imageData; + const { minZoomScale, maxZoomScale } = this.configuration; - return; - } + const t = dimensions[0] * spacing[0]; + const scale = t / parallelScaleToSet; - const { parallelScale: cappedParallelScale, thresholdExceeded } = - this._getCappedParallelScale(viewport, newParallelScale); + let cappedParallelScale = parallelScaleToSet; + let thresholdExceeded = false; + + if (scale < minZoomScale) { + cappedParallelScale = t / minZoomScale; + thresholdExceeded = true; + } else if (scale >= maxZoomScale) { + cappedParallelScale = t / maxZoomScale; + thresholdExceeded = true; + } viewport.setCamera({ parallelScale: cappedParallelScale, @@ -167,10 +172,8 @@ export default class ZoomTool extends BaseTool { }); }; - _dragPerspectiveProjection = (evt, camera) => { + _dragPerspectiveProjection = (evt, viewport, camera) => { const { element, deltaPoints } = evt.detail; - const enabledElement = getEnabledElement(element); - const { viewport } = enabledElement; const size = [element.clientWidth, element.clientHeight]; const { position, focalPoint, viewPlaneNormal } = camera; @@ -201,36 +204,4 @@ export default class ZoomTool extends BaseTool { viewport.setCamera({ position, focalPoint }); }; - - _getCappedParallelScale = ( - viewport: Types.IStackViewport | Types.IVolumeViewport, - parallelScale: number - ): { parallelScale: number; thresholdExceeded: boolean } => { - const imageData = viewport.getImageData(); - - if (!imageData) { - return; - } - - const { dimensions, spacing } = imageData; - - const t = dimensions[0] * spacing[0]; - const scale = t / parallelScale; - - let newParallelScale = parallelScale; - let thresholdExceeded = false; - - if (scale < this.minZoomScale) { - newParallelScale = t / this.minZoomScale; - thresholdExceeded = true; - } else if (scale > this.maxZoomScale) { - newParallelScale = t / this.maxZoomScale; - thresholdExceeded = true; - } - - return { - parallelScale: newParallelScale, - thresholdExceeded, - }; - }; } From 27db4e8fb4d18db85c5d176e2b4094453ec07504 Mon Sep 17 00:00:00 2001 From: Alireza Date: Thu, 9 Jun 2022 15:06:52 -0400 Subject: [PATCH 07/10] feat: fix various type definitions --- common/reviews/api/core.api.md | 6 +- .../api/streaming-image-volume-loader.api.md | 3 + common/reviews/api/tools.api.md | 81 ++++++++++--------- packages/core/src/metaData.ts | 2 +- .../tools/src/drawingSvg/clearByToolType.ts | 4 +- packages/tools/src/drawingSvg/draw.ts | 2 +- packages/tools/src/drawingSvg/drawArrow.ts | 3 +- packages/tools/src/drawingSvg/drawCircle.ts | 9 ++- packages/tools/src/drawingSvg/drawEllipse.ts | 9 ++- packages/tools/src/drawingSvg/drawHandles.ts | 9 ++- packages/tools/src/drawingSvg/drawLine.ts | 9 ++- packages/tools/src/drawingSvg/drawLink.ts | 4 +- .../tools/src/drawingSvg/drawLinkedTextBox.ts | 3 +- packages/tools/src/drawingSvg/drawPolyline.ts | 9 ++- packages/tools/src/drawingSvg/drawRect.ts | 9 ++- packages/tools/src/drawingSvg/drawTextBox.ts | 13 +-- .../src/drawingSvg/getSvgDrawingHelper.ts | 21 +++-- packages/tools/src/tools/CrosshairsTool.ts | 3 +- .../tools/src/tools/annotation/AngleTool.ts | 3 +- .../src/tools/annotation/ArrowAnnotateTool.ts | 3 +- .../src/tools/annotation/BidirectionalTool.ts | 3 +- .../src/tools/annotation/DragProbeTool.ts | 9 ++- .../src/tools/annotation/EllipticalROITool.ts | 3 +- .../tools/src/tools/annotation/LengthTool.ts | 3 +- .../tools/annotation/PlanarFreehandROITool.ts | 11 +-- .../tools/src/tools/annotation/ProbeTool.ts | 3 +- .../src/tools/annotation/RectangleROITool.ts | 3 +- .../planarFreehandROITool/renderMethods.ts | 13 +-- .../tools/src/tools/base/AnnotationTool.ts | 3 +- .../tools/src/tools/segmentation/BrushTool.ts | 9 ++- .../tools/segmentation/CircleScissorsTool.ts | 9 ++- .../RectangleROIStartEndThresholdTool.ts | 9 ++- .../segmentation/RectangleROIThresholdTool.ts | 9 ++- .../segmentation/RectangleScissorsTool.ts | 9 ++- .../tools/segmentation/SphereScissorsTool.ts | 9 ++- packages/tools/src/types/SVGDrawingHelper.ts | 10 +++ packages/tools/src/types/index.ts | 2 + 37 files changed, 199 insertions(+), 123 deletions(-) create mode 100644 packages/tools/src/types/SVGDrawingHelper.ts diff --git a/common/reviews/api/core.api.md b/common/reviews/api/core.api.md index 7ad63cfc7e..9044a4ca9e 100644 --- a/common/reviews/api/core.api.md +++ b/common/reviews/api/core.api.md @@ -295,6 +295,8 @@ interface CPUFallbackTransform { // @public (undocumented) type CPUFallbackViewport = { scale?: number; + parallelScale?: number; + focalPoint?: number[]; translation?: { x: number; y: number; @@ -654,6 +656,8 @@ interface ICamera { // (undocumented) position?: Point3; // (undocumented) + scale?: number; + // (undocumented) viewAngle?: number; // (undocumented) viewPlaneNormal?: Point3; @@ -1696,7 +1700,7 @@ export class StackViewport extends Viewport implements IStackViewport { // (undocumented) setImageIdIndex(imageIdIndex: number): Promise; // (undocumented) - setProperties({ voiRange, invert, interpolationType, rotation, suppressEvents, }?: StackViewportProperties): void; + setProperties({ voiRange, invert, interpolationType, rotation, }?: StackViewportProperties, suppressEvents?: boolean): void; // (undocumented) setStack(imageIds: Array, currentImageIdIndex?: number): Promise; // (undocumented) diff --git a/common/reviews/api/streaming-image-volume-loader.api.md b/common/reviews/api/streaming-image-volume-loader.api.md index d4bfaa2576..f4a57ed062 100644 --- a/common/reviews/api/streaming-image-volume-loader.api.md +++ b/common/reviews/api/streaming-image-volume-loader.api.md @@ -263,6 +263,8 @@ interface CPUFallbackTransform { // @public (undocumented) type CPUFallbackViewport = { scale?: number; + parallelScale?: number; + focalPoint?: number[]; translation?: { x: number; y: number; @@ -503,6 +505,7 @@ interface ICamera { parallelProjection?: boolean; parallelScale?: number; position?: Point3; + scale?: number; viewAngle?: number; viewPlaneNormal?: Point3; viewUp?: Point3; diff --git a/common/reviews/api/tools.api.md b/common/reviews/api/tools.api.md index 8e12cd07d1..c15f9f0478 100644 --- a/common/reviews/api/tools.api.md +++ b/common/reviews/api/tools.api.md @@ -140,7 +140,7 @@ export class AngleTool extends AnnotationTool { // (undocumented) _mouseUpCallback: (evt: EventTypes_2.MouseUpEventType | EventTypes_2.MouseClickEventType) => void; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -329,7 +329,7 @@ export abstract class AnnotationTool extends BaseTool { // (undocumented) onImageSpacingCalibrated: (evt: Types_2.EventTypes.ImageSpacingCalibratedEvent) => void; // (undocumented) - abstract renderAnnotation(enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any): any; + abstract renderAnnotation(enabledElement: Types_2.IEnabledElement, svgDrawingHelper: SVGDrawingHelper): any; // (undocumented) static toolName: string; // (undocumented) @@ -391,7 +391,7 @@ export class ArrowAnnotateTool extends AnnotationTool { // (undocumented) _mouseUpCallback: (evt: EventTypes_2.MouseUpEventType | EventTypes_2.MouseClickEventType) => void; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -535,7 +535,7 @@ export class BidirectionalTool extends AnnotationTool { // (undocumented) preventHandleOutsideImage: boolean; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -564,7 +564,7 @@ export class BrushTool extends BaseTool { // (undocumented) preMouseDownCallback: (evt: EventTypes_2.MouseDownActivateEventType) => boolean; // (undocumented) - renderAnnotation(enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any): void; + renderAnnotation(enabledElement: Types_2.IEnabledElement, svgDrawingHelper: SVGDrawingHelper): void; // (undocumented) static toolName: string; } @@ -647,7 +647,7 @@ export class CircleScissorsTool extends BaseTool { // (undocumented) preMouseDownCallback: (evt: EventTypes_2.MouseDownActivateEventType) => boolean; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean; // (undocumented) static toolName: string; } @@ -911,6 +911,8 @@ interface CPUFallbackTransform { // @public (undocumented) type CPUFallbackViewport = { scale?: number; + parallelScale?: number; + focalPoint?: number[]; translation?: { x: number; y: number; @@ -1085,7 +1087,7 @@ export class CrosshairsTool extends AnnotationTool { // (undocumented) _pointNearTool(element: any, annotation: any, canvasCoords: any, proximity: any): boolean; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean; // (undocumented) setSlabThickness(viewport: any, slabThickness: any): void; // (undocumented) @@ -1195,7 +1197,7 @@ export class DragProbeTool extends ProbeTool { // (undocumented) postMouseDownCallback: (evt: EventTypes_2.MouseDownActivateEventType) => ProbeAnnotation; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean; // (undocumented) static toolName: string; // (undocumented) @@ -1206,16 +1208,16 @@ export class DragProbeTool extends ProbeTool { function draw(element: HTMLDivElement, fn: (svgDrawingElement: any) => any): void; // @public (undocumented) -function drawArrow(svgDrawingHelper: any, annotationUID: string, arrowUID: string, start: Types_2.Point2, end: Types_2.Point2, options?: {}): void; +function drawArrow(svgDrawingHelper: SVGDrawingHelper, annotationUID: string, arrowUID: string, start: Types_2.Point2, end: Types_2.Point2, options?: {}): void; // @public (undocumented) -function drawCircle(svgDrawingHelper: any, annotationUID: string, circleUID: string, center: Types_2.Point2, radius: number, options?: {}): void; +function drawCircle(svgDrawingHelper: SVGDrawingHelper, annotationUID: string, circleUID: string, center: Types_2.Point2, radius: number, options?: {}): void; // @public (undocumented) -function drawEllipse(svgDrawingHelper: any, annotationUID: string, ellipseUID: string, corner1: Types_2.Point2, corner2: Types_2.Point2, options?: {}): void; +function drawEllipse(svgDrawingHelper: SVGDrawingHelper, annotationUID: string, ellipseUID: string, corner1: Types_2.Point2, corner2: Types_2.Point2, options?: {}): void; // @public (undocumented) -function drawHandles(svgDrawingHelper: any, annotationUID: string, handleGroupUID: string, handlePoints: Array, options?: {}): void; +function drawHandles(svgDrawingHelper: SVGDrawingHelper, annotationUID: string, handleGroupUID: string, handlePoints: Array, options?: {}): void; declare namespace drawing { export { @@ -1240,13 +1242,13 @@ declare namespace drawing_2 { } // @public (undocumented) -function drawLine(svgDrawingHelper: any, annotationUID: string, lineUID: string, start: Types_2.Point2, end: Types_2.Point2, options?: {}): void; +function drawLine(svgDrawingHelper: SVGDrawingHelper, annotationUID: string, lineUID: string, start: Types_2.Point2, end: Types_2.Point2, options?: {}): void; // @public (undocumented) -function drawLinkedTextBox(svgDrawingHelper: Record, annotationUID: string, textBoxUID: string, textLines: Array, textBoxPosition: Types_2.Point2, annotationAnchorPoints: Array, textBox: unknown, options?: {}): SVGRect; +function drawLinkedTextBox(svgDrawingHelper: SVGDrawingHelper, annotationUID: string, textBoxUID: string, textLines: Array, textBoxPosition: Types_2.Point2, annotationAnchorPoints: Array, textBox: unknown, options?: {}): SVGRect; // @public (undocumented) -function drawPolyline(svgDrawingHelper: any, annotationUID: string, polylineUID: string, points: Types_2.Point2[], options: { +function drawPolyline(svgDrawingHelper: SVGDrawingHelper, annotationUID: string, polylineUID: string, points: Types_2.Point2[], options: { color?: string; width?: number; lineWidth?: number; @@ -1255,10 +1257,10 @@ function drawPolyline(svgDrawingHelper: any, annotationUID: string, polylineUID: }): void; // @public (undocumented) -function drawRect(svgDrawingHelper: any, annotationUID: string, rectangleUID: string, start: Types_2.Point2, end: Types_2.Point2, options?: {}): void; +function drawRect(svgDrawingHelper: SVGDrawingHelper, annotationUID: string, rectangleUID: string, start: Types_2.Point2, end: Types_2.Point2, options?: {}): void; // @public (undocumented) -function drawTextBox(svgDrawingHelper: Record, annotationUID: string, textUID: string, textLines: Array, position: Types_2.Point2, options?: {}): SVGRect; +function drawTextBox(svgDrawingHelper: SVGDrawingHelper, annotationUID: string, textUID: string, textLines: Array, position: Types_2.Point2, options?: {}): SVGRect; declare namespace elementCursor { export { @@ -1374,7 +1376,7 @@ export class EllipticalROITool extends AnnotationTool { // (undocumented) _pointInEllipseCanvas(ellipse: any, location: Types_2.Point2): boolean; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -1817,6 +1819,7 @@ interface ICamera { parallelProjection?: boolean; parallelScale?: number; position?: Point3; + scale?: number; viewAngle?: number; viewPlaneNormal?: Point3; viewUp?: Point3; @@ -2554,7 +2557,7 @@ export class LengthTool extends AnnotationTool { // (undocumented) _mouseUpCallback: (evt: EventTypes_2.MouseUpEventType | EventTypes_2.MouseClickEventType) => void; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -2904,7 +2907,7 @@ export class PlanarFreehandROITool extends AnnotationTool { // (undocumented) mouseDragCallback: any; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -3044,7 +3047,7 @@ export class ProbeTool extends AnnotationTool { // (undocumented) _mouseUpCallback: (evt: EventTypes_2.MouseUpEventType | EventTypes_2.MouseClickEventType) => void; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean; // (undocumented) static toolName: string; // (undocumented) @@ -3192,7 +3195,7 @@ export class RectangleROIStartEndThresholdTool extends RectangleROITool { // (undocumented) isHandleOutsideImage: boolean; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -3267,7 +3270,7 @@ export class RectangleROIThresholdTool extends RectangleROITool { // (undocumented) isHandleOutsideImage: boolean; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -3327,7 +3330,7 @@ export class RectangleROITool extends AnnotationTool { // (undocumented) _mouseUpCallback: (evt: EventTypes_2.MouseUpEventType | EventTypes_2.MouseClickEventType) => void; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -3374,7 +3377,7 @@ export class RectangleScissorsTool extends BaseTool { // (undocumented) preMouseDownCallback: (evt: EventTypes_2.MouseDownActivateEventType) => boolean; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean; // (undocumented) _throttledCalculateCachedStats: any; // (undocumented) @@ -3696,7 +3699,7 @@ export class SphereScissorsTool extends BaseTool { // (undocumented) preMouseDownCallback: (evt: EventTypes_2.MouseDownActivateEventType) => true; // (undocumented) - renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: any) => boolean; + renderAnnotation: (enabledElement: Types_2.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean; // (undocumented) static toolName: string; } @@ -3856,6 +3859,16 @@ type SVGCursorDescriptor = { mousePointerGroupString: string; }; +// @public (undocumented) +type SVGDrawingHelper = { + svgLayerElement: HTMLDivElement; + svgNodeCacheForCanvas: Record; + getSvgNode: (cacheKey: string) => SVGGElement | undefined; + appendNode: (svgNode: SVGElement, cacheKey: string) => void; + setNodeTouched: (cacheKey: string) => void; + clearUntouched: () => void; +}; + // @public (undocumented) class SVGMouseCursor extends ImageMouseCursor { constructor(url: string, x?: number, y?: number, name?: string | undefined, fallback?: MouseCursor | undefined); @@ -4145,7 +4158,8 @@ declare namespace Types { SVGPoint_2 as SVGPoint, ScrollOptions_2 as ScrollOptions, CINETypes, - BoundsIJK + BoundsIJK, + SVGDrawingHelper } } export { Types } @@ -4367,21 +4381,12 @@ export class ZoomTool extends BaseTool { // (undocumented) _dragCallback(evt: EventTypes_2.MouseDragEventType): void; // (undocumented) - _dragParallelProjection: (evt: EventTypes_2.MouseDragEventType, camera: Types_2.ICamera) => void; + _dragParallelProjection: (evt: EventTypes_2.MouseDragEventType, viewport: Types_2.IStackViewport | Types_2.IVolumeViewport, camera: Types_2.ICamera) => void; // (undocumented) - _dragPerspectiveProjection: (evt: any, camera: any) => void; - // (undocumented) - _getCappedParallelScale: (viewport: Types_2.IStackViewport | Types_2.IVolumeViewport, parallelScale: number) => { - parallelScale: number; - thresholdExceeded: boolean; - }; + _dragPerspectiveProjection: (evt: any, viewport: any, camera: any) => void; // (undocumented) initialMousePosWorld: Types_2.Point3; // (undocumented) - maxZoomScale: number; - // (undocumented) - minZoomScale: number; - // (undocumented) mouseDragCallback: () => void; // (undocumented) preMouseDownCallback: (evt: EventTypes_2.MouseDownActivateEventType) => boolean; diff --git a/packages/core/src/metaData.ts b/packages/core/src/metaData.ts index c31eb4e312..034401d530 100644 --- a/packages/core/src/metaData.ts +++ b/packages/core/src/metaData.ts @@ -70,7 +70,7 @@ export function removeAllProviders(): void { * @returns The metadata retrieved from the metadata store * @category MetaData */ -function getMetaData(type: string, imageId: string): unknown { +function getMetaData(type: string, imageId: string): any { // Invoke each provider in priority order until one returns something for (let i = 0; i < providers.length; i++) { const result = providers[i].provider(type, imageId); diff --git a/packages/tools/src/drawingSvg/clearByToolType.ts b/packages/tools/src/drawingSvg/clearByToolType.ts index 407585e9ae..bee0952afa 100644 --- a/packages/tools/src/drawingSvg/clearByToolType.ts +++ b/packages/tools/src/drawingSvg/clearByToolType.ts @@ -8,7 +8,7 @@ import getSvgDrawingHelper from './getSvgDrawingHelper'; */ function clearByToolType(element: HTMLDivElement, toolType: string): void { const svgDrawingHelper = getSvgDrawingHelper(element); - const nodes = svgDrawingHelper._svgLayerElement.querySelectorAll( + const nodes = svgDrawingHelper.svgLayerElement.querySelectorAll( 'svg > *' ) as NodeListOf; @@ -18,7 +18,7 @@ function clearByToolType(element: HTMLDivElement, toolType: string): void { const toolUID = node.dataset.toolUid; if (toolUID === toolType) { - svgDrawingHelper._svgLayerElement.removeChild(node); + svgDrawingHelper.svgLayerElement.removeChild(node); } } } diff --git a/packages/tools/src/drawingSvg/draw.ts b/packages/tools/src/drawingSvg/draw.ts index f0cc9257b6..80f7ddc2ff 100644 --- a/packages/tools/src/drawingSvg/draw.ts +++ b/packages/tools/src/drawingSvg/draw.ts @@ -10,7 +10,7 @@ function draw( fn(svgDrawingHelper); // Restore... - svgDrawingHelper._clearUntouched(); + svgDrawingHelper.clearUntouched(); } export default draw; diff --git a/packages/tools/src/drawingSvg/drawArrow.ts b/packages/tools/src/drawingSvg/drawArrow.ts index 0f4a7d63d0..03c4057e63 100644 --- a/packages/tools/src/drawingSvg/drawArrow.ts +++ b/packages/tools/src/drawingSvg/drawArrow.ts @@ -1,8 +1,9 @@ import type { Types } from '@cornerstonejs/core'; +import { SVGDrawingHelper } from '../types'; import drawLine from './drawLine'; export default function drawArrow( - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotationUID: string, arrowUID: string, start: Types.Point2, diff --git a/packages/tools/src/drawingSvg/drawCircle.ts b/packages/tools/src/drawingSvg/drawCircle.ts index 8b637942d6..93c1e7481f 100644 --- a/packages/tools/src/drawingSvg/drawCircle.ts +++ b/packages/tools/src/drawingSvg/drawCircle.ts @@ -1,4 +1,5 @@ import type { Types } from '@cornerstonejs/core'; +import { SVGDrawingHelper } from '../types'; import _getHash from './_getHash'; @@ -6,7 +7,7 @@ import _setAttributesIfNecessary from './_setAttributesIfNecessary'; import _setNewAttributesIfValid from './_setNewAttributesIfValid'; function drawCircle( - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotationUID: string, circleUID: string, center: Types.Point2, @@ -29,7 +30,7 @@ function drawCircle( // variable for the namespace const svgns = 'http://www.w3.org/2000/svg'; const svgNodeHash = _getHash(annotationUID, 'circle', circleUID); - const existingCircleElement = svgDrawingHelper._getSvgNode(svgNodeHash); + const existingCircleElement = svgDrawingHelper.getSvgNode(svgNodeHash); const attributes = { cx: `${center[0]}`, @@ -43,13 +44,13 @@ function drawCircle( if (existingCircleElement) { _setAttributesIfNecessary(attributes, existingCircleElement); - svgDrawingHelper._setNodeTouched(svgNodeHash); + svgDrawingHelper.setNodeTouched(svgNodeHash); } else { const newCircleElement = document.createElementNS(svgns, 'circle'); _setNewAttributesIfValid(attributes, newCircleElement); - svgDrawingHelper._appendNode(newCircleElement, svgNodeHash); + svgDrawingHelper.appendNode(newCircleElement, svgNodeHash); } } diff --git a/packages/tools/src/drawingSvg/drawEllipse.ts b/packages/tools/src/drawingSvg/drawEllipse.ts index 36235abc56..c9c0d5eeeb 100644 --- a/packages/tools/src/drawingSvg/drawEllipse.ts +++ b/packages/tools/src/drawingSvg/drawEllipse.ts @@ -1,11 +1,12 @@ import type { Types } from '@cornerstonejs/core'; +import { SVGDrawingHelper } from '../types'; import _getHash from './_getHash'; import _setAttributesIfNecessary from './_setAttributesIfNecessary'; import _setNewAttributesIfValid from './_setNewAttributesIfValid'; function drawEllipse( - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotationUID: string, ellipseUID: string, corner1: Types.Point2, @@ -27,7 +28,7 @@ function drawEllipse( const svgns = 'http://www.w3.org/2000/svg'; const svgNodeHash = _getHash(annotationUID, 'ellipse', ellipseUID); - const existingEllipse = svgDrawingHelper._getSvgNode(svgNodeHash); + const existingEllipse = svgDrawingHelper.getSvgNode(svgNodeHash); const w = Math.abs(corner1[0] - corner2[0]); const h = Math.abs(corner1[1] - corner2[1]); @@ -52,13 +53,13 @@ function drawEllipse( if (existingEllipse) { _setAttributesIfNecessary(attributes, existingEllipse); - svgDrawingHelper._setNodeTouched(svgNodeHash); + svgDrawingHelper.setNodeTouched(svgNodeHash); } else { const svgEllipseElement = document.createElementNS(svgns, 'ellipse'); _setNewAttributesIfValid(attributes, svgEllipseElement); - svgDrawingHelper._appendNode(svgEllipseElement, svgNodeHash); + svgDrawingHelper.appendNode(svgEllipseElement, svgNodeHash); } } diff --git a/packages/tools/src/drawingSvg/drawHandles.ts b/packages/tools/src/drawingSvg/drawHandles.ts index e9e2683d6c..0ea6f9c155 100644 --- a/packages/tools/src/drawingSvg/drawHandles.ts +++ b/packages/tools/src/drawingSvg/drawHandles.ts @@ -3,9 +3,10 @@ import type { Types } from '@cornerstonejs/core'; import _getHash from './_getHash'; import _setNewAttributesIfValid from './_setNewAttributesIfValid'; import _setAttributesIfNecessary from './_setAttributesIfNecessary'; +import { SVGDrawingHelper } from '../types'; function drawHandles( - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotationUID: string, handleGroupUID: string, handlePoints: Array, @@ -67,18 +68,18 @@ function drawHandles( throw new Error(`Unsupported handle type: ${type}`); } - const existingHandleElement = svgDrawingHelper._getSvgNode(svgNodeHash); + const existingHandleElement = svgDrawingHelper.getSvgNode(svgNodeHash); if (existingHandleElement) { _setAttributesIfNecessary(attributes, existingHandleElement); - svgDrawingHelper._setNodeTouched(svgNodeHash); + svgDrawingHelper.setNodeTouched(svgNodeHash); } else { const newHandleElement = document.createElementNS(svgns, type); _setNewAttributesIfValid(attributes, newHandleElement); - svgDrawingHelper._appendNode(newHandleElement, svgNodeHash); + svgDrawingHelper.appendNode(newHandleElement, svgNodeHash); } } } diff --git a/packages/tools/src/drawingSvg/drawLine.ts b/packages/tools/src/drawingSvg/drawLine.ts index e1056d85dc..e7d5f2821c 100644 --- a/packages/tools/src/drawingSvg/drawLine.ts +++ b/packages/tools/src/drawingSvg/drawLine.ts @@ -3,9 +3,10 @@ import type { Types } from '@cornerstonejs/core'; import _getHash from './_getHash'; import _setNewAttributesIfValid from './_setNewAttributesIfValid'; import _setAttributesIfNecessary from './_setAttributesIfNecessary'; +import { SVGDrawingHelper } from '../types'; export default function drawLine( - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotationUID: string, lineUID: string, start: Types.Point2, @@ -32,7 +33,7 @@ export default function drawLine( const svgns = 'http://www.w3.org/2000/svg'; const svgNodeHash = _getHash(annotationUID, 'line', lineUID); - const existingLine = svgDrawingHelper._getSvgNode(svgNodeHash); + const existingLine = svgDrawingHelper.getSvgNode(svgNodeHash); const attributes = { x1: `${start[0]}`, @@ -48,12 +49,12 @@ export default function drawLine( // This is run to avoid re-rendering annotations that actually haven't changed _setAttributesIfNecessary(attributes, existingLine); - svgDrawingHelper._setNodeTouched(svgNodeHash); + svgDrawingHelper.setNodeTouched(svgNodeHash); } else { const newLine = document.createElementNS(svgns, 'line'); _setNewAttributesIfValid(attributes, newLine); - svgDrawingHelper._appendNode(newLine, svgNodeHash); + svgDrawingHelper.appendNode(newLine, svgNodeHash); } } diff --git a/packages/tools/src/drawingSvg/drawLink.ts b/packages/tools/src/drawingSvg/drawLink.ts index 68133a63f4..e9ac3db4fa 100644 --- a/packages/tools/src/drawingSvg/drawLink.ts +++ b/packages/tools/src/drawingSvg/drawLink.ts @@ -2,13 +2,13 @@ import type { Types } from '@cornerstonejs/core'; import drawLine from './drawLine'; import findClosestPoint from '../utilities/math/vec2/findClosestPoint'; -import { PlanarBoundingBox } from '../types'; +import { PlanarBoundingBox, SVGDrawingHelper } from '../types'; /** * Draw a link between an annotation to a box. */ function drawLink( - svgDrawingHelper: Record, + svgDrawingHelper: SVGDrawingHelper, annotationUID: string, linkUID: string, // Find closest point to approx. bounding box diff --git a/packages/tools/src/drawingSvg/drawLinkedTextBox.ts b/packages/tools/src/drawingSvg/drawLinkedTextBox.ts index 54e6eacd34..8ae8fa020b 100644 --- a/packages/tools/src/drawingSvg/drawLinkedTextBox.ts +++ b/packages/tools/src/drawingSvg/drawLinkedTextBox.ts @@ -2,9 +2,10 @@ import type { Types } from '@cornerstonejs/core'; import drawTextBox from './drawTextBox'; import drawLink from './drawLink'; +import { SVGDrawingHelper } from '../types'; function drawLinkedTextBox( - svgDrawingHelper: Record, + svgDrawingHelper: SVGDrawingHelper, annotationUID: string, textBoxUID: string, // diff --git a/packages/tools/src/drawingSvg/drawPolyline.ts b/packages/tools/src/drawingSvg/drawPolyline.ts index d8f832b9b0..7504e545cd 100644 --- a/packages/tools/src/drawingSvg/drawPolyline.ts +++ b/packages/tools/src/drawingSvg/drawPolyline.ts @@ -2,6 +2,7 @@ import type { Types } from '@cornerstonejs/core'; import _getHash from './_getHash'; import _setNewAttributesIfValid from './_setNewAttributesIfValid'; import _setAttributesIfNecessary from './_setAttributesIfNecessary'; +import { SVGDrawingHelper } from '../types'; /** * Draws an SVG polyline with the given points. @@ -10,7 +11,7 @@ import _setAttributesIfNecessary from './_setAttributesIfNecessary'; * last point connected to the first. */ export default function drawPolyline( - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotationUID: string, polylineUID: string, points: Types.Point2[], @@ -42,7 +43,7 @@ export default function drawPolyline( const svgns = 'http://www.w3.org/2000/svg'; const svgNodeHash = _getHash(annotationUID, 'polyline', polylineUID); - const existingPolyLine = svgDrawingHelper._getSvgNode(svgNodeHash); + const existingPolyLine = svgDrawingHelper.getSvgNode(svgNodeHash); let pointsAttribute = ''; @@ -68,12 +69,12 @@ export default function drawPolyline( // This is run to avoid re-rendering annotations that actually haven't changed _setAttributesIfNecessary(attributes, existingPolyLine); - svgDrawingHelper._setNodeTouched(svgNodeHash); + svgDrawingHelper.setNodeTouched(svgNodeHash); } else { const newPolyLine = document.createElementNS(svgns, 'polyline'); _setNewAttributesIfValid(attributes, newPolyLine); - svgDrawingHelper._appendNode(newPolyLine, svgNodeHash); + svgDrawingHelper.appendNode(newPolyLine, svgNodeHash); } } diff --git a/packages/tools/src/drawingSvg/drawRect.ts b/packages/tools/src/drawingSvg/drawRect.ts index ed21678635..9fa1e46534 100644 --- a/packages/tools/src/drawingSvg/drawRect.ts +++ b/packages/tools/src/drawingSvg/drawRect.ts @@ -3,10 +3,11 @@ import type { Types } from '@cornerstonejs/core'; import _getHash from './_getHash'; import _setAttributesIfNecessary from './_setAttributesIfNecessary'; import _setNewAttributesIfValid from './_setNewAttributesIfValid'; +import { SVGDrawingHelper } from '../types'; // export default function drawRect( - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotationUID: string, rectangleUID: string, start: Types.Point2, @@ -33,7 +34,7 @@ export default function drawRect( const svgns = 'http://www.w3.org/2000/svg'; const svgNodeHash = _getHash(annotationUID, 'rect', rectangleUID); - const existingRect = svgDrawingHelper._getSvgNode(svgNodeHash); + const existingRect = svgDrawingHelper.getSvgNode(svgNodeHash); const tlhc = [Math.min(start[0], end[0]), Math.min(start[1], end[1])]; const width = Math.abs(start[0] - end[0]); @@ -53,12 +54,12 @@ export default function drawRect( if (existingRect) { _setAttributesIfNecessary(attributes, existingRect); - svgDrawingHelper._setNodeTouched(svgNodeHash); + svgDrawingHelper.setNodeTouched(svgNodeHash); } else { const svgRectElement = document.createElementNS(svgns, 'rect'); _setNewAttributesIfValid(attributes, svgRectElement); - svgDrawingHelper._appendNode(svgRectElement, svgNodeHash); + svgDrawingHelper.appendNode(svgRectElement, svgNodeHash); } } diff --git a/packages/tools/src/drawingSvg/drawTextBox.ts b/packages/tools/src/drawingSvg/drawTextBox.ts index ca2912be04..25e622b0c9 100644 --- a/packages/tools/src/drawingSvg/drawTextBox.ts +++ b/packages/tools/src/drawingSvg/drawTextBox.ts @@ -1,4 +1,5 @@ import type { Types } from '@cornerstonejs/core'; +import { SVGDrawingHelper } from '../types'; import _getHash from './_getHash'; import _setAttributesIfNecessary from './_setAttributesIfNecessary'; @@ -12,7 +13,7 @@ import _setAttributesIfNecessary from './_setAttributesIfNecessary'; * @returns Bounding box; can be used for isPointNearTool */ function drawTextBox( - svgDrawingHelper: Record, + svgDrawingHelper: SVGDrawingHelper, annotationUID: string, textUID: string, textLines: Array, @@ -46,7 +47,7 @@ function drawTextBox( } function _drawTextGroup( - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotationUID: string, textUID: string, textLines: Array, @@ -59,7 +60,7 @@ function _drawTextGroup( const [x, y] = [position[0] + padding, position[1] + padding]; const svgns = 'http://www.w3.org/2000/svg'; const svgNodeHash = _getHash(annotationUID, 'text', textUID); - const existingTextGroup = svgDrawingHelper._getSvgNode(svgNodeHash); + const existingTextGroup = svgDrawingHelper.getSvgNode(svgNodeHash); // Todo: right now textBox gets a re-render even if the textBox has not changed // and evenIf the attributes are not set again since they are the same. @@ -85,7 +86,7 @@ function _drawTextGroup( } existingTextGroup.appendChild(textElement); - svgDrawingHelper._appendNode(existingTextGroup, svgNodeHash); + svgDrawingHelper.appendNode(existingTextGroup, svgNodeHash); } const textAttributes = { @@ -104,7 +105,7 @@ function _drawTextGroup( textGroupBoundingBox = _drawTextBackground(existingTextGroup, background); - svgDrawingHelper._setNodeTouched(svgNodeHash); + svgDrawingHelper.setNodeTouched(svgNodeHash); } else { const textGroup = document.createElementNS(svgns, 'g'); @@ -120,7 +121,7 @@ function _drawTextGroup( } textGroup.appendChild(textElement); - svgDrawingHelper._appendNode(textGroup, svgNodeHash); + svgDrawingHelper.appendNode(textGroup, svgNodeHash); textGroupBoundingBox = _drawTextBackground(textGroup, background); } diff --git a/packages/tools/src/drawingSvg/getSvgDrawingHelper.ts b/packages/tools/src/drawingSvg/getSvgDrawingHelper.ts index c5a7f8e7e6..358102de81 100644 --- a/packages/tools/src/drawingSvg/getSvgDrawingHelper.ts +++ b/packages/tools/src/drawingSvg/getSvgDrawingHelper.ts @@ -1,12 +1,13 @@ import { state } from '../store'; import { getEnabledElement } from '@cornerstonejs/core'; +import { SVGDrawingHelper } from '../types'; /** * Returns the SVG drawing helper for the given HTML element. * @param element - The HTML element to get the SVG drawing helper for. * @private */ -function getSvgDrawingHelper(element: HTMLDivElement) { +function getSvgDrawingHelper(element: HTMLDivElement): SVGDrawingHelper { const enabledElement = getEnabledElement(element); const { viewportId, renderingEngineId } = enabledElement; const canvasHash = `${viewportId}:${renderingEngineId}`; @@ -18,22 +19,18 @@ function getSvgDrawingHelper(element: HTMLDivElement) { }); return { - // Todo: not sure if we need enabledElement and _element anymore here - enabledElement: enabledElement, - _element: element, - _svgLayerElement: svgLayerElement, - _svgNodeCacheForCanvas: state.svgNodeCache, - _getSvgNode: getSvgNode.bind(this, canvasHash), - _appendNode: appendNode.bind(this, svgLayerElement, canvasHash), - _setNodeTouched: setNodeTouched.bind(this, canvasHash), - _clearUntouched: clearUntouched.bind(this, svgLayerElement, canvasHash), - // _drawnAnnotations: drawnAnnotations, + svgLayerElement: svgLayerElement, + svgNodeCacheForCanvas: state.svgNodeCache, + getSvgNode: getSvgNode.bind(this, canvasHash), + appendNode: appendNode.bind(this, svgLayerElement, canvasHash), + setNodeTouched: setNodeTouched.bind(this, canvasHash), + clearUntouched: clearUntouched.bind(this, svgLayerElement, canvasHash), }; } /** * - * @param canvasElement + * @param element * @private */ function _getSvgLayer(element) { diff --git a/packages/tools/src/tools/CrosshairsTool.ts b/packages/tools/src/tools/CrosshairsTool.ts index dd8ded5acb..cf289ae8e4 100644 --- a/packages/tools/src/tools/CrosshairsTool.ts +++ b/packages/tools/src/tools/CrosshairsTool.ts @@ -43,6 +43,7 @@ import { PublicToolProps, ToolProps, InteractionTypes, + SVGDrawingHelper, } from '../types'; import { isAnnotationLocked } from '../stateManagement/annotation/annotationLocking'; import triggerAnnotationRenderForViewportIds from '../utilities/triggerAnnotationRenderForViewportIds'; @@ -668,7 +669,7 @@ export default class CrosshairsTool extends AnnotationTool { */ renderAnnotation = ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any + svgDrawingHelper: SVGDrawingHelper ): boolean => { let renderStatus = false; const { viewport, renderingEngine } = enabledElement; diff --git a/packages/tools/src/tools/annotation/AngleTool.ts b/packages/tools/src/tools/annotation/AngleTool.ts index e41363fc5e..0732528175 100644 --- a/packages/tools/src/tools/annotation/AngleTool.ts +++ b/packages/tools/src/tools/annotation/AngleTool.ts @@ -43,6 +43,7 @@ import { PublicToolProps, ToolProps, InteractionTypes, + SVGDrawingHelper, } from '../../types'; import { AngleAnnotation } from '../../types/ToolSpecificAnnotationTypes'; import { StyleSpecifier } from '../../types/AnnotationStyle'; @@ -522,7 +523,7 @@ class AngleTool extends AnnotationTool { */ renderAnnotation = ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any + svgDrawingHelper: SVGDrawingHelper ): boolean => { let renderStatus = false; diff --git a/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts b/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts index fbe7ed3620..85d636127a 100644 --- a/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts +++ b/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts @@ -39,6 +39,7 @@ import { PublicToolProps, ToolProps, InteractionTypes, + SVGDrawingHelper, } from '../../types'; import { ArrowAnnotation } from '../../types/ToolSpecificAnnotationTypes'; import { StyleSpecifier } from '../../types/AnnotationStyle'; @@ -563,7 +564,7 @@ class ArrowAnnotateTool extends AnnotationTool { */ renderAnnotation = ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any + svgDrawingHelper: SVGDrawingHelper ): boolean => { let renderStatus = false; const { viewport } = enabledElement; diff --git a/packages/tools/src/tools/annotation/BidirectionalTool.ts b/packages/tools/src/tools/annotation/BidirectionalTool.ts index af821d6af0..1f003d1a05 100644 --- a/packages/tools/src/tools/annotation/BidirectionalTool.ts +++ b/packages/tools/src/tools/annotation/BidirectionalTool.ts @@ -37,6 +37,7 @@ import { PublicToolProps, ToolProps, InteractionTypes, + SVGDrawingHelper, } from '../../types'; import { BidirectionalAnnotation } from '../../types/ToolSpecificAnnotationTypes'; @@ -951,7 +952,7 @@ export default class BidirectionalTool extends AnnotationTool { */ renderAnnotation = ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any + svgDrawingHelper: SVGDrawingHelper ): boolean => { let renderStatus = true; const { viewport } = enabledElement; diff --git a/packages/tools/src/tools/annotation/DragProbeTool.ts b/packages/tools/src/tools/annotation/DragProbeTool.ts index 5a1ab27906..75f7aec40e 100644 --- a/packages/tools/src/tools/annotation/DragProbeTool.ts +++ b/packages/tools/src/tools/annotation/DragProbeTool.ts @@ -8,7 +8,12 @@ import { } from '../../drawingSvg'; import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters'; import { hideElementCursor } from '../../cursors/elementCursor'; -import { EventTypes, PublicToolProps, ToolProps } from '../../types'; +import { + EventTypes, + PublicToolProps, + SVGDrawingHelper, + ToolProps, +} from '../../types'; import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds'; import ProbeTool from './ProbeTool'; import { ProbeAnnotation } from '../../types/ToolSpecificAnnotationTypes'; @@ -105,7 +110,7 @@ export default class DragProbeTool extends ProbeTool { renderAnnotation = ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any + svgDrawingHelper: SVGDrawingHelper ): boolean => { let renderStatus = false; const { viewport } = enabledElement; diff --git a/packages/tools/src/tools/annotation/EllipticalROITool.ts b/packages/tools/src/tools/annotation/EllipticalROITool.ts index 945b7ad383..91905bef83 100644 --- a/packages/tools/src/tools/annotation/EllipticalROITool.ts +++ b/packages/tools/src/tools/annotation/EllipticalROITool.ts @@ -42,6 +42,7 @@ import { PublicToolProps, ToolProps, InteractionTypes, + SVGDrawingHelper, } from '../../types'; import { EllipticalROIAnnotation } from '../../types/ToolSpecificAnnotationTypes'; @@ -704,7 +705,7 @@ export default class EllipticalROITool extends AnnotationTool { */ renderAnnotation = ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any + svgDrawingHelper: SVGDrawingHelper ): boolean => { let renderStatus = false; const { viewport } = enabledElement; diff --git a/packages/tools/src/tools/annotation/LengthTool.ts b/packages/tools/src/tools/annotation/LengthTool.ts index a47f25ba67..58128710a5 100644 --- a/packages/tools/src/tools/annotation/LengthTool.ts +++ b/packages/tools/src/tools/annotation/LengthTool.ts @@ -44,6 +44,7 @@ import { PublicToolProps, ToolProps, InteractionTypes, + SVGDrawingHelper, } from '../../types'; import { LengthAnnotation } from '../../types/ToolSpecificAnnotationTypes'; import { StyleSpecifier } from '../../types/AnnotationStyle'; @@ -527,7 +528,7 @@ class LengthTool extends AnnotationTool { */ renderAnnotation = ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any + svgDrawingHelper: SVGDrawingHelper ): boolean => { let renderStatus = false; const { viewport } = enabledElement; diff --git a/packages/tools/src/tools/annotation/PlanarFreehandROITool.ts b/packages/tools/src/tools/annotation/PlanarFreehandROITool.ts index 392d7547d2..0d352d2472 100644 --- a/packages/tools/src/tools/annotation/PlanarFreehandROITool.ts +++ b/packages/tools/src/tools/annotation/PlanarFreehandROITool.ts @@ -36,6 +36,7 @@ import { PublicToolProps, ToolProps, InteractionTypes, + SVGDrawingHelper, } from '../../types'; import { PlanarFreehandROIAnnotation } from '../../types/ToolSpecificAnnotationTypes'; import { PlanarFreehandROICommonData } from '../../utilities/math/polyline/planarFreehandROIInternalTypes'; @@ -110,22 +111,22 @@ class PlanarFreehandROITool extends AnnotationTool { private renderContour: ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotation: PlanarFreehandROIAnnotation ) => void; private renderContourBeingDrawn: ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotation: PlanarFreehandROIAnnotation ) => void; private renderClosedContourBeingEdited: ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotation: PlanarFreehandROIAnnotation ) => void; private renderOpenContourBeingEdited: ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotation: PlanarFreehandROIAnnotation ) => void; @@ -503,7 +504,7 @@ class PlanarFreehandROITool extends AnnotationTool { */ renderAnnotation = ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any + svgDrawingHelper: SVGDrawingHelper ): boolean => { const renderStatus = false; const { viewport } = enabledElement; diff --git a/packages/tools/src/tools/annotation/ProbeTool.ts b/packages/tools/src/tools/annotation/ProbeTool.ts index 8eae8b2bcb..a84f4e8a9d 100644 --- a/packages/tools/src/tools/annotation/ProbeTool.ts +++ b/packages/tools/src/tools/annotation/ProbeTool.ts @@ -40,6 +40,7 @@ import { ToolHandle, PublicToolProps, ToolProps, + SVGDrawingHelper, } from '../../types'; import { ProbeAnnotation } from '../../types/ToolSpecificAnnotationTypes'; import { StyleSpecifier } from '../../types/AnnotationStyle'; @@ -395,7 +396,7 @@ export default class ProbeTool extends AnnotationTool { */ renderAnnotation = ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any + svgDrawingHelper: SVGDrawingHelper ): boolean => { let renderStatus = false; const { viewport } = enabledElement; diff --git a/packages/tools/src/tools/annotation/RectangleROITool.ts b/packages/tools/src/tools/annotation/RectangleROITool.ts index b88c5fbdad..57268dac89 100644 --- a/packages/tools/src/tools/annotation/RectangleROITool.ts +++ b/packages/tools/src/tools/annotation/RectangleROITool.ts @@ -41,6 +41,7 @@ import { ToolProps, PublicToolProps, InteractionTypes, + SVGDrawingHelper, } from '../../types'; import { RectangleROIAnnotation } from '../../types/ToolSpecificAnnotationTypes'; import { @@ -603,7 +604,7 @@ export default class RectangleROITool extends AnnotationTool { */ renderAnnotation = ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any + svgDrawingHelper: SVGDrawingHelper ): boolean => { let renderStatus = false; const { viewport } = enabledElement; diff --git a/packages/tools/src/tools/annotation/planarFreehandROITool/renderMethods.ts b/packages/tools/src/tools/annotation/planarFreehandROITool/renderMethods.ts index 4725edbed9..095c42bbd7 100644 --- a/packages/tools/src/tools/annotation/planarFreehandROITool/renderMethods.ts +++ b/packages/tools/src/tools/annotation/planarFreehandROITool/renderMethods.ts @@ -7,6 +7,7 @@ import { polyline } from '../../../utilities/math'; import { findOpenUShapedContourVectorToPeakOnRender } from './findOpenUShapedContourVectorToPeak'; import { PlanarFreehandROIAnnotation } from '../../../types/ToolSpecificAnnotationTypes'; import { StyleSpecifier } from '../../../types/AnnotationStyle'; +import { SVGDrawingHelper } from '../../../types'; const { pointsAreWithinCloseContourProximity } = polyline; @@ -48,7 +49,7 @@ function _getRenderingOptions( */ function renderContour( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotation: PlanarFreehandROIAnnotation ): void { // Check if the contour is an open contour @@ -94,7 +95,7 @@ function calculateUShapeContourVectorToPeakIfNotPresent( */ function renderClosedContour( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotation: PlanarFreehandROIAnnotation ): void { const { viewport } = enabledElement; @@ -125,7 +126,7 @@ function renderClosedContour( */ function renderOpenContour( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotation: PlanarFreehandROIAnnotation ): void { const { viewport } = enabledElement; @@ -203,7 +204,7 @@ function renderOpenContour( function renderOpenUShapedContour( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotation: PlanarFreehandROIAnnotation ): void { const { viewport } = enabledElement; @@ -259,7 +260,7 @@ function renderOpenUShapedContour( */ function renderContourBeingDrawn( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotation: PlanarFreehandROIAnnotation ): void { const options = this._getRenderingOptions(enabledElement, annotation); @@ -349,7 +350,7 @@ function renderClosedContourBeingEdited( */ function renderOpenContourBeingEdited( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any, + svgDrawingHelper: SVGDrawingHelper, annotation: PlanarFreehandROIAnnotation ): void { const { fusedCanvasPoints } = this.editData; diff --git a/packages/tools/src/tools/base/AnnotationTool.ts b/packages/tools/src/tools/base/AnnotationTool.ts index 0d5ab45786..810fe30c19 100644 --- a/packages/tools/src/tools/base/AnnotationTool.ts +++ b/packages/tools/src/tools/base/AnnotationTool.ts @@ -19,6 +19,7 @@ import { EventTypes, ToolHandle, InteractionTypes, + SVGDrawingHelper, } from '../../types'; import triggerAnnotationRender from '../../utilities/triggerAnnotationRender'; import filterAnnotationsForDisplay from '../../utilities/planar/filterAnnotationsForDisplay'; @@ -62,7 +63,7 @@ abstract class AnnotationTool extends BaseTool { */ abstract renderAnnotation( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any + svgDrawingHelper: SVGDrawingHelper ); /** diff --git a/packages/tools/src/tools/segmentation/BrushTool.ts b/packages/tools/src/tools/segmentation/BrushTool.ts index 65062155a6..08a057ab60 100644 --- a/packages/tools/src/tools/segmentation/BrushTool.ts +++ b/packages/tools/src/tools/segmentation/BrushTool.ts @@ -1,7 +1,12 @@ import { cache, getEnabledElement, StackViewport } from '@cornerstonejs/core'; import type { Types } from '@cornerstonejs/core'; -import type { PublicToolProps, ToolProps, EventTypes } from '../../types'; +import type { + PublicToolProps, + ToolProps, + EventTypes, + SVGDrawingHelper, +} from '../../types'; import { BaseTool } from '../base'; import { fillInsideCircle } from './strategies/fillCircle'; @@ -416,7 +421,7 @@ export default class BrushTool extends BaseTool { renderAnnotation( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any + svgDrawingHelper: SVGDrawingHelper ): void { if (!this._hoverData) { return; diff --git a/packages/tools/src/tools/segmentation/CircleScissorsTool.ts b/packages/tools/src/tools/segmentation/CircleScissorsTool.ts index 65c60e5b2a..b54754e391 100644 --- a/packages/tools/src/tools/segmentation/CircleScissorsTool.ts +++ b/packages/tools/src/tools/segmentation/CircleScissorsTool.ts @@ -2,7 +2,12 @@ import { cache, getEnabledElement, StackViewport } from '@cornerstonejs/core'; import type { Types } from '@cornerstonejs/core'; import { BaseTool } from '../base'; -import { PublicToolProps, ToolProps, EventTypes } from '../../types'; +import { + PublicToolProps, + ToolProps, + EventTypes, + SVGDrawingHelper, +} from '../../types'; import { fillInsideCircle } from './strategies/fillCircle'; import { Events } from '../../enums'; @@ -298,7 +303,7 @@ export default class CircleScissorsTool extends BaseTool { */ renderAnnotation = ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any + svgDrawingHelper: SVGDrawingHelper ): boolean => { let renderStatus = false; if (!this.editData) { diff --git a/packages/tools/src/tools/segmentation/RectangleROIStartEndThresholdTool.ts b/packages/tools/src/tools/segmentation/RectangleROIStartEndThresholdTool.ts index 6d3dd6d572..de71aadf1a 100644 --- a/packages/tools/src/tools/segmentation/RectangleROIStartEndThresholdTool.ts +++ b/packages/tools/src/tools/segmentation/RectangleROIStartEndThresholdTool.ts @@ -24,7 +24,12 @@ import { isAnnotationVisible } from '../../stateManagement/annotation/annotation import { hideElementCursor } from '../../cursors/elementCursor'; import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds'; -import { PublicToolProps, ToolProps, EventTypes } from '../../types'; +import { + PublicToolProps, + ToolProps, + EventTypes, + SVGDrawingHelper, +} from '../../types'; import { RectangleROIStartEndThresholdAnnotation } from '../../types/ToolSpecificAnnotationTypes'; import RectangleROITool from '../annotation/RectangleROITool'; import { StyleSpecifier } from '../../types/AnnotationStyle'; @@ -296,7 +301,7 @@ export default class RectangleROIStartEndThresholdTool extends RectangleROITool */ renderAnnotation = ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any + svgDrawingHelper: SVGDrawingHelper ): boolean => { let renderStatus = false; const annotations = getAnnotations( diff --git a/packages/tools/src/tools/segmentation/RectangleROIThresholdTool.ts b/packages/tools/src/tools/segmentation/RectangleROIThresholdTool.ts index adb97c26cc..f0e66d1f80 100644 --- a/packages/tools/src/tools/segmentation/RectangleROIThresholdTool.ts +++ b/packages/tools/src/tools/segmentation/RectangleROIThresholdTool.ts @@ -20,7 +20,12 @@ import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters' import { hideElementCursor } from '../../cursors/elementCursor'; import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds'; import { isAnnotationVisible } from '../../stateManagement/annotation/annotationVisibility'; -import { PublicToolProps, ToolProps, EventTypes } from '../../types'; +import { + PublicToolProps, + ToolProps, + EventTypes, + SVGDrawingHelper, +} from '../../types'; import { RectangleROIThresholdAnnotation } from '../../types/ToolSpecificAnnotationTypes'; import { AnnotationModifiedEventDetail } from '../../types/EventTypes'; import RectangleROITool from '../annotation/RectangleROITool'; @@ -164,7 +169,7 @@ export default class RectangleROIThresholdTool extends RectangleROITool { */ renderAnnotation = ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any + svgDrawingHelper: SVGDrawingHelper ): boolean => { let renderStatus = false; const { viewport, renderingEngineId } = enabledElement; diff --git a/packages/tools/src/tools/segmentation/RectangleScissorsTool.ts b/packages/tools/src/tools/segmentation/RectangleScissorsTool.ts index 111bbaa97f..f2183fb1ac 100644 --- a/packages/tools/src/tools/segmentation/RectangleScissorsTool.ts +++ b/packages/tools/src/tools/segmentation/RectangleScissorsTool.ts @@ -2,7 +2,12 @@ import { cache, getEnabledElement, StackViewport } from '@cornerstonejs/core'; import type { Types } from '@cornerstonejs/core'; import { BaseTool } from '../base'; -import { PublicToolProps, ToolProps, EventTypes } from '../../types'; +import { + PublicToolProps, + ToolProps, + EventTypes, + SVGDrawingHelper, +} from '../../types'; import { fillInsideRectangle } from './strategies/fillRectangle'; import { eraseInsideRectangle } from './strategies/eraseRectangle'; import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters'; @@ -333,7 +338,7 @@ export default class RectangleScissorsTool extends BaseTool { */ renderAnnotation = ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any + svgDrawingHelper: SVGDrawingHelper ): boolean => { let renderStatus = false; if (!this.editData) { diff --git a/packages/tools/src/tools/segmentation/SphereScissorsTool.ts b/packages/tools/src/tools/segmentation/SphereScissorsTool.ts index 8e341a75a0..6dd9f58e91 100644 --- a/packages/tools/src/tools/segmentation/SphereScissorsTool.ts +++ b/packages/tools/src/tools/segmentation/SphereScissorsTool.ts @@ -2,7 +2,12 @@ import { cache, getEnabledElement, StackViewport } from '@cornerstonejs/core'; import type { Types } from '@cornerstonejs/core'; import { BaseTool } from '../base'; -import { PublicToolProps, ToolProps, EventTypes } from '../../types'; +import { + PublicToolProps, + ToolProps, + EventTypes, + SVGDrawingHelper, +} from '../../types'; import { fillInsideSphere } from './strategies/fillSphere'; import { Events } from '../../enums'; @@ -299,7 +304,7 @@ export default class SphereScissorsTool extends BaseTool { */ renderAnnotation = ( enabledElement: Types.IEnabledElement, - svgDrawingHelper: any + svgDrawingHelper: SVGDrawingHelper ): boolean => { let renderStatus = false; if (!this.editData) { diff --git a/packages/tools/src/types/SVGDrawingHelper.ts b/packages/tools/src/types/SVGDrawingHelper.ts new file mode 100644 index 0000000000..37de5bacf7 --- /dev/null +++ b/packages/tools/src/types/SVGDrawingHelper.ts @@ -0,0 +1,10 @@ +type SVGDrawingHelper = { + svgLayerElement: HTMLDivElement; + svgNodeCacheForCanvas: Record; + getSvgNode: (cacheKey: string) => SVGGElement | undefined; + appendNode: (svgNode: SVGElement, cacheKey: string) => void; + setNodeTouched: (cacheKey: string) => void; + clearUntouched: () => void; +}; + +export default SVGDrawingHelper; diff --git a/packages/tools/src/types/index.ts b/packages/tools/src/types/index.ts index 756a24734d..257caeecaf 100644 --- a/packages/tools/src/types/index.ts +++ b/packages/tools/src/types/index.ts @@ -24,6 +24,7 @@ import type { SVGCursorDescriptor, SVGPoint } from './CursorTypes'; import type JumpToSliceOptions from './JumpToSliceOptions'; import type ScrollOptions from './ScrollOptions'; import type BoundsIJK from './BoundsIJK'; +import type SVGDrawingHelper from './SVGDrawingHelper'; import type * as CINETypes from './CINETypes'; import type { Color, @@ -86,4 +87,5 @@ export type { // CINE CINETypes, BoundsIJK, + SVGDrawingHelper, }; From 6280900aa161cc68287a410e2c0928acb841ff85 Mon Sep 17 00:00:00 2001 From: Alireza Date: Thu, 9 Jun 2022 16:37:08 -0400 Subject: [PATCH 08/10] fix: parallel scale physical calculation --- .../core/src/RenderingEngine/StackViewport.ts | 27 +++++++++++++------ packages/tools/src/tools/ZoomTool.ts | 4 +-- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/packages/core/src/RenderingEngine/StackViewport.ts b/packages/core/src/RenderingEngine/StackViewport.ts index c93e18f7c3..b64722afaa 100644 --- a/packages/core/src/RenderingEngine/StackViewport.ts +++ b/packages/core/src/RenderingEngine/StackViewport.ts @@ -667,13 +667,18 @@ class StackViewport extends Viewport implements IStackViewport { // Focal point is the center of the canvas in world coordinate by design const canvasCenterWorld = this.canvasToWorld(canvasCenter); + // parallel scale is half of the viewport height in the world units (mm) + + const topLeftCanvas = this.canvasToWorld([0, 0]); + const bottomLeftCanvas = this.canvasToWorld([0, this.element.clientHeight]); + + const parallelScale = vec3.distance(topLeftCanvas, bottomLeftCanvas) / 2; + return { parallelProjection: true, focalPoint: canvasCenterWorld, position: [0, 0, 0], - parallelScale: image - ? (image.width * image.columnPixelSpacing) / viewport.scale - : 1, + parallelScale, scale: viewport.scale, viewPlaneNormal: [ viewPlaneNormal[0], @@ -697,6 +702,8 @@ class StackViewport extends Viewport implements IStackViewport { flipVertical, } = cameraInterface; + const { clientHeight } = this.element; + if (focalPoint) { const focalPointCanvas = this.worldToCanvasCPU(focalPoint); const focalPointPixel = canvasToPixel( @@ -724,18 +731,22 @@ class StackViewport extends Viewport implements IStackViewport { } if (parallelScale) { - // We need to convert he parallelScale which has a physical meaning for - // camera scale factor to scale (since CPU works with scale) - const { columnPixelSpacing } = image; - const scale = (image.width * columnPixelSpacing) / parallelScale; + // We need to convert he parallelScale which has a physical meaning to + // camera scale factor (since CPU works with scale). Since parallelScale represents + // half of the height of the viewport in the world unit (mm), we can use that + // to compute the scale factor which is the ratio of the viewport height in pixels + // to the current rendered image height. + const { rowPixelSpacing } = image; + const scale = (clientHeight * rowPixelSpacing * 0.5) / parallelScale; viewport.scale = scale; viewport.parallelScale = parallelScale; } if (scale) { + const { rowPixelSpacing } = image; viewport.scale = scale; - viewport.parallelScale = (image.width * image.columnPixelSpacing) / scale; + viewport.parallelScale = (clientHeight * rowPixelSpacing * 0.5) / scale; } if (flipHorizontal || flipVertical) { diff --git a/packages/tools/src/tools/ZoomTool.ts b/packages/tools/src/tools/ZoomTool.ts index 811c0ee713..cecbf99b5a 100644 --- a/packages/tools/src/tools/ZoomTool.ts +++ b/packages/tools/src/tools/ZoomTool.ts @@ -148,10 +148,10 @@ export default class ZoomTool extends BaseTool { // has a physical meaning and we can use that to determine the threshold const imageData = viewport.getImageData(); - const { dimensions, spacing } = imageData; + const { spacing } = imageData; const { minZoomScale, maxZoomScale } = this.configuration; - const t = dimensions[0] * spacing[0]; + const t = element.clientHeight * spacing[1] * 0.5; const scale = t / parallelScaleToSet; let cappedParallelScale = parallelScaleToSet; From e161ff52fc9bae7e531d405f2b40524e439b396a Mon Sep 17 00:00:00 2001 From: Alireza Date: Mon, 13 Jun 2022 13:44:26 -0400 Subject: [PATCH 09/10] fix: cpu camera api to accomodate rotation --- .../core/src/RenderingEngine/StackViewport.ts | 14 +++++-- .../cpuFallback/rendering/correctShift.ts | 38 +++++++++++++++++++ 2 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 packages/core/src/RenderingEngine/helpers/cpuFallback/rendering/correctShift.ts diff --git a/packages/core/src/RenderingEngine/StackViewport.ts b/packages/core/src/RenderingEngine/StackViewport.ts index b64722afaa..6b500a033c 100644 --- a/packages/core/src/RenderingEngine/StackViewport.ts +++ b/packages/core/src/RenderingEngine/StackViewport.ts @@ -62,6 +62,7 @@ import { } from '../types/EventTypes'; import getScalingParameters from '../utilities/getScalingParameters'; import cache from '../cache'; +import correctShift from './helpers/cpuFallback/rendering/correctShift'; const EPSILON = 1; // Slice Thickness @@ -686,6 +687,8 @@ class StackViewport extends Viewport implements IStackViewport { viewPlaneNormal[2], ], viewUp: [viewUp[0], viewUp[1], viewUp[2]], + flipHorizontal: this.flipHorizontal, + flipVertical: this.flipVertical, }; } @@ -726,8 +729,13 @@ class StackViewport extends Viewport implements IStackViewport { vec2.fromValues(prevFocalPointPixel[0], prevFocalPointPixel[1]) ); - viewport.translation.x -= deltaPixel[0]; - viewport.translation.y -= deltaPixel[1]; + const shift = correctShift( + { x: deltaPixel[0], y: deltaPixel[1] }, + viewport + ); + + viewport.translation.x -= shift.x; + viewport.translation.y -= shift.y; } if (parallelScale) { @@ -749,7 +757,7 @@ class StackViewport extends Viewport implements IStackViewport { viewport.parallelScale = (clientHeight * rowPixelSpacing * 0.5) / scale; } - if (flipHorizontal || flipVertical) { + if (flipHorizontal !== undefined || flipVertical !== undefined) { this.setFlipCPU({ flipHorizontal, flipVertical }); } diff --git a/packages/core/src/RenderingEngine/helpers/cpuFallback/rendering/correctShift.ts b/packages/core/src/RenderingEngine/helpers/cpuFallback/rendering/correctShift.ts new file mode 100644 index 0000000000..d8f2af56ee --- /dev/null +++ b/packages/core/src/RenderingEngine/helpers/cpuFallback/rendering/correctShift.ts @@ -0,0 +1,38 @@ +import { CPUFallbackViewport, Point2 } from '../../../../types'; + +type Shift = { + x: number; + y: number; +}; +/** + * Corrects the shift by accounting for viewport rotation and flips. + * + * @param shift - The shift to correct. + * @param viewportOrientation - Object containing information on the viewport orientation. + */ +export default function ( + shift: Shift, + viewportOrientation: CPUFallbackViewport +): Shift { + const { hflip, vflip, rotation } = viewportOrientation; + + // Apply Flips + shift.x *= hflip ? -1 : 1; + shift.y *= vflip ? -1 : 1; + + // Apply rotations + if (rotation !== 0) { + const angle = (rotation * Math.PI) / 180; + + const cosA = Math.cos(angle); + const sinA = Math.sin(angle); + + const newX = shift.x * cosA - shift.y * sinA; + const newY = shift.x * sinA + shift.y * cosA; + + shift.x = newX; + shift.y = newY; + } + + return shift; +} From 9be9f81249b3ef0bc9b5db01b938c16d37eeab35 Mon Sep 17 00:00:00 2001 From: Alireza Date: Mon, 13 Jun 2022 15:03:44 -0400 Subject: [PATCH 10/10] apply review comments --- packages/core/src/RenderingEngine/StackViewport.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/core/src/RenderingEngine/StackViewport.ts b/packages/core/src/RenderingEngine/StackViewport.ts index 6b500a033c..9d0c4f734a 100644 --- a/packages/core/src/RenderingEngine/StackViewport.ts +++ b/packages/core/src/RenderingEngine/StackViewport.ts @@ -637,7 +637,7 @@ class StackViewport extends Viewport implements IStackViewport { } private getCameraCPU(): Partial { - const { metadata, viewport, image } = this._cpuFallbackEnabledElement; + const { metadata, viewport } = this._cpuFallbackEnabledElement; const { direction } = metadata; // focalPoint and position of CPU camera is just a placeholder since @@ -665,15 +665,15 @@ class StackViewport extends Viewport implements IStackViewport { this.element.clientHeight / 2, ]; - // Focal point is the center of the canvas in world coordinate by design + // Focal point is the center of the canvas in world coordinate by construction const canvasCenterWorld = this.canvasToWorld(canvasCenter); // parallel scale is half of the viewport height in the world units (mm) - const topLeftCanvas = this.canvasToWorld([0, 0]); - const bottomLeftCanvas = this.canvasToWorld([0, this.element.clientHeight]); + const topLeftWorld = this.canvasToWorld([0, 0]); + const bottomLeftWorld = this.canvasToWorld([0, this.element.clientHeight]); - const parallelScale = vec3.distance(topLeftCanvas, bottomLeftCanvas) / 2; + const parallelScale = vec3.distance(topLeftWorld, bottomLeftWorld) / 2; return { parallelProjection: true,