From e52ee09b3c8acd1109639571a8bfbe75a695e65b Mon Sep 17 00:00:00 2001 From: Jason Hostetter MD Date: Thu, 23 Jan 2025 13:29:00 -0500 Subject: [PATCH 1/4] Add options to tool hydrate method - Optional referencedImageId, viewPlaneNormal, and viewUp to populate annotation metadata rather than use current viewport data. - Don't calculate spline polyline coordinates on hydration, as this only works for the current camera position, not any passed in parameters. It appears this gets recalculated on annotation render anyways, so seems to be redundant. --- common/reviews/api/tools.api.md | 24 ++++++++++ .../dynamicallyAddAnnotations/angleToolUI.ts | 26 ++++++++-- .../arrowAnnotateToolUI.ts | 21 +++++++-- .../circleROIToolUI.ts | 25 ++++++++-- .../ellipticalROIToolUI.ts | 13 +++-- .../dynamicallyAddAnnotations/lengthToolUI.ts | 21 +++++++-- .../dynamicallyAddAnnotations/probeToolUI.ts | 16 +++++-- .../rectangleROIToolUI.ts | 16 +++++-- .../splineROIToolUI.ts | 36 ++++++++++---- .../tools/src/tools/annotation/AngleTool.ts | 24 +++++++++- .../src/tools/annotation/ArrowAnnotateTool.ts | 24 +++++++++- .../src/tools/annotation/CircleROITool.ts | 24 +++++++++- .../src/tools/annotation/EllipticalROITool.ts | 24 +++++++++- .../tools/src/tools/annotation/LengthTool.ts | 24 +++++++++- .../tools/src/tools/annotation/ProbeTool.ts | 24 +++++++++- .../src/tools/annotation/RectangleROITool.ts | 24 +++++++++- .../src/tools/annotation/SplineROITool.ts | 47 +++++++++++++++---- 17 files changed, 352 insertions(+), 61 deletions(-) diff --git a/common/reviews/api/tools.api.md b/common/reviews/api/tools.api.md index 870142c859..db43889fb6 100644 --- a/common/reviews/api/tools.api.md +++ b/common/reviews/api/tools.api.md @@ -231,6 +231,9 @@ export class AngleTool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; + referencedImageId?: string; + viewplaneNormal?: Types_2.Point3; + viewUp?: Types_2.Point3; }) => AngleAnnotation; // (undocumented) isDrawing: boolean; @@ -645,6 +648,9 @@ export class ArrowAnnotateTool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], text?: string, options?: { annotationUID?: string; + referencedImageId?: string; + viewplaneNormal?: Types_2.Point3; + viewUp?: Types_2.Point3; }) => ArrowAnnotation; // (undocumented) isDrawing: boolean; @@ -1244,6 +1250,9 @@ export class CircleROITool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; + referencedImageId?: string; + viewplaneNormal?: Types_2.Point3; + viewUp?: Types_2.Point3; }) => CircleROIAnnotation; // (undocumented) isDrawing: boolean; @@ -2231,6 +2240,9 @@ export class EllipticalROITool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; + referencedImageId?: string; + viewplaneNormal?: Types_2.Point3; + viewUp?: Types_2.Point3; }) => EllipticalROIAnnotation; // (undocumented) isDrawing: boolean; @@ -3639,6 +3651,9 @@ export class LengthTool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; + referencedImageId?: string; + viewplaneNormal?: Types_2.Point3; + viewUp?: Types_2.Point3; }) => LengthAnnotation; // (undocumented) isDrawing: boolean; @@ -4406,6 +4421,9 @@ export class ProbeTool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; + referencedImageId?: string; + viewplaneNormal?: Types_2.Point3; + viewUp?: Types_2.Point3; }) => ProbeAnnotation; // (undocumented) isDrawing: boolean; @@ -4737,6 +4755,9 @@ export class RectangleROITool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; + referencedImageId?: string; + viewplaneNormal?: Types_2.Point3; + viewUp?: Types_2.Point3; }) => RectangleROIAnnotation; // (undocumented) isDrawing: boolean; @@ -5676,6 +5697,9 @@ export class SplineROITool extends ContourSegmentationBaseTool { static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; splineType?: SplineTypesEnum; + referencedImageId?: string; + viewplaneNormal?: Types_2.Point3; + viewUp?: Types_2.Point3; }) => SplineROIAnnotation; // (undocumented) protected isContourSegmentationTool(): boolean; diff --git a/packages/tools/examples/dynamicallyAddAnnotations/angleToolUI.ts b/packages/tools/examples/dynamicallyAddAnnotations/angleToolUI.ts index b0e762f918..a80d6ff903 100644 --- a/packages/tools/examples/dynamicallyAddAnnotations/angleToolUI.ts +++ b/packages/tools/examples/dynamicallyAddAnnotations/angleToolUI.ts @@ -65,6 +65,11 @@ function createFormElement(): HTMLFormElement {
+ ${ + coordType === 'image' + ? ` ` + : '' + }

`; }); @@ -76,30 +81,41 @@ function addButtonListeners(form: HTMLFormElement): void { const buttons = form.querySelectorAll('button'); buttons.forEach((button) => { button.addEventListener('click', () => { - const [type, viewportType] = button.id.split('-') as [ + const [type, viewportType, useImageId] = button.id.split('-') as [ 'canvas' | 'image', - keyof typeof typeToIdMap + keyof typeof typeToIdMap, + 'imageId'? ]; const enabledElement = getEnabledElementByViewportId( typeToIdMap[viewportType] ); const viewport = enabledElement.viewport; + const imageId = useImageId && viewport.getImageIds()[0]; const coords = getCoordinates(form, type); const currentImageId = viewport.getCurrentImageId() as string; const worldPoint1 = type === 'image' - ? utilities.imageToWorldCoords(currentImageId, coords.point1) + ? utilities.imageToWorldCoords( + imageId || currentImageId, + coords.point1 + ) : viewport.canvasToWorld(coords.point1); const worldPoint2 = type === 'image' - ? utilities.imageToWorldCoords(currentImageId, coords.point2) + ? utilities.imageToWorldCoords( + imageId || currentImageId, + coords.point2 + ) : viewport.canvasToWorld(coords.point2); const worldPoint3 = type === 'image' - ? utilities.imageToWorldCoords(currentImageId, coords.point3) + ? utilities.imageToWorldCoords( + imageId || currentImageId, + coords.point3 + ) : viewport.canvasToWorld(coords.point3); AngleTool.hydrate(viewport.id, [worldPoint1, worldPoint2, worldPoint3]); diff --git a/packages/tools/examples/dynamicallyAddAnnotations/arrowAnnotateToolUI.ts b/packages/tools/examples/dynamicallyAddAnnotations/arrowAnnotateToolUI.ts index 01261ae982..d0578d4ed5 100644 --- a/packages/tools/examples/dynamicallyAddAnnotations/arrowAnnotateToolUI.ts +++ b/packages/tools/examples/dynamicallyAddAnnotations/arrowAnnotateToolUI.ts @@ -53,6 +53,11 @@ function createFormElement(): HTMLFormElement {
+ ${ + coordType === 'image' + ? ` ` + : '' + }

`; }); @@ -64,14 +69,16 @@ function addButtonListeners(form: HTMLFormElement): void { const buttons = form.querySelectorAll('button'); buttons.forEach((button) => { button.addEventListener('click', () => { - const [type, viewportType] = button.id.split('-') as [ + const [type, viewportType, useImageId] = button.id.split('-') as [ 'canvas' | 'image', - keyof typeof typeToIdMap + keyof typeof typeToIdMap, + 'imageId'? ]; const enabledElement = getEnabledElementByViewportId( typeToIdMap[viewportType] ); const viewport = enabledElement.viewport; + const imageId = useImageId && viewport.getImageIds()[0]; const coords = getCoordinates(form, type); const textInput = form.querySelector(`#${type}-text`) as HTMLInputElement; const text = textInput ? textInput.value : ''; @@ -80,12 +87,18 @@ function addButtonListeners(form: HTMLFormElement): void { const point1 = type === 'image' - ? utilities.imageToWorldCoords(currentImageId, coords.point1) + ? utilities.imageToWorldCoords( + imageId || currentImageId, + coords.point1 + ) : viewport.canvasToWorld(coords.point1); const point2 = type === 'image' - ? utilities.imageToWorldCoords(currentImageId, coords.point2) + ? utilities.imageToWorldCoords( + imageId || currentImageId, + coords.point2 + ) : viewport.canvasToWorld(coords.point2); ArrowAnnotateTool.hydrate(viewport.id, [point1, point2], text); diff --git a/packages/tools/examples/dynamicallyAddAnnotations/circleROIToolUI.ts b/packages/tools/examples/dynamicallyAddAnnotations/circleROIToolUI.ts index 6085dda1ec..f83446704b 100644 --- a/packages/tools/examples/dynamicallyAddAnnotations/circleROIToolUI.ts +++ b/packages/tools/examples/dynamicallyAddAnnotations/circleROIToolUI.ts @@ -51,6 +51,11 @@ function createFormElement(): HTMLFormElement {
+ ${ + coordType === 'image' + ? ` ` + : '' + }

`; }); @@ -62,28 +67,38 @@ function addButtonListeners(form: HTMLFormElement): void { const buttons = form.querySelectorAll('button'); buttons.forEach((button) => { button.addEventListener('click', () => { - const [type, viewportType] = button.id.split('-') as [ + const [type, viewportType, useImageId] = button.id.split('-') as [ 'canvas' | 'image', - keyof typeof typeToIdMap + keyof typeof typeToIdMap, + 'imageId'? ]; const enabledElement = getEnabledElementByViewportId( typeToIdMap[viewportType] ); const viewport = enabledElement.viewport; + const imageId = useImageId && viewport.getImageIds()[0]; const coords = getCoordinates(form, type); const currentImageId = viewport.getCurrentImageId() as string; const worldCenter = type === 'image' - ? utilities.imageToWorldCoords(currentImageId, coords.center) + ? utilities.imageToWorldCoords( + imageId || currentImageId, + coords.center + ) : viewport.canvasToWorld(coords.center); const worldRadiusPoint = type === 'image' - ? utilities.imageToWorldCoords(currentImageId, coords.radiusPoint) + ? utilities.imageToWorldCoords( + imageId || currentImageId, + coords.radiusPoint + ) : viewport.canvasToWorld(coords.radiusPoint); - CircleROITool.hydrate(viewport.id, [worldCenter, worldRadiusPoint]); + CircleROITool.hydrate(viewport.id, [worldCenter, worldRadiusPoint], { + referencedImageId: imageId, + }); }); }); } diff --git a/packages/tools/examples/dynamicallyAddAnnotations/ellipticalROIToolUI.ts b/packages/tools/examples/dynamicallyAddAnnotations/ellipticalROIToolUI.ts index 6ce414dc45..4f64d6f789 100644 --- a/packages/tools/examples/dynamicallyAddAnnotations/ellipticalROIToolUI.ts +++ b/packages/tools/examples/dynamicallyAddAnnotations/ellipticalROIToolUI.ts @@ -70,6 +70,11 @@ function createFormElement(): HTMLFormElement {
+ ${ + coordType === 'image' + ? ` ` + : '' + }

`; }); @@ -81,20 +86,22 @@ function addButtonListeners(form: HTMLFormElement): void { const buttons = form.querySelectorAll('button'); buttons.forEach((button) => { button.addEventListener('click', () => { - const [type, viewportType] = button.id.split('-') as [ + const [type, viewportType, useImageId] = button.id.split('-') as [ 'canvas' | 'image', - keyof typeof typeToIdMap + keyof typeof typeToIdMap, + 'imageId'? ]; const enabledElement = getEnabledElementByViewportId( typeToIdMap[viewportType] ); const viewport = enabledElement.viewport; + const imageId = useImageId && viewport.getImageIds()[0]; const coords = getCoordinates(form, type); const currentImageId = viewport.getCurrentImageId() as string; const convertPoint = (point: Point2): Point3 => type === 'image' - ? (utilities.imageToWorldCoords(currentImageId, point) as Point3) + ? (utilities.imageToWorldCoords(imageId || currentImageId, point) as Point3) : viewport.canvasToWorld(point); const points: Point3[] = [ diff --git a/packages/tools/examples/dynamicallyAddAnnotations/lengthToolUI.ts b/packages/tools/examples/dynamicallyAddAnnotations/lengthToolUI.ts index d9bf0ec17e..4a065b20ea 100644 --- a/packages/tools/examples/dynamicallyAddAnnotations/lengthToolUI.ts +++ b/packages/tools/examples/dynamicallyAddAnnotations/lengthToolUI.ts @@ -52,6 +52,11 @@ function createFormElement(): HTMLFormElement {
+ ${ + coordType === 'image' + ? ` ` + : '' + }

`; }); @@ -63,25 +68,33 @@ function addButtonListeners(form: HTMLFormElement): void { const buttons = form.querySelectorAll('button'); buttons.forEach((button) => { button.addEventListener('click', () => { - const [type, viewportType] = button.id.split('-') as [ + const [type, viewportType, useImageId] = button.id.split('-') as [ 'canvas' | 'image', - keyof typeof typeToIdMap + keyof typeof typeToIdMap, + 'imageId'? ]; const enabledElement = getEnabledElementByViewportId( typeToIdMap[viewportType] ); const viewport = enabledElement.viewport; + const imageId = useImageId && viewport.getImageIds()[0]; const coords = getCoordinates(form, type); const currentImageId = viewport.getCurrentImageId() as string; const worldStart = type === 'image' - ? utilities.imageToWorldCoords(currentImageId, coords.topLeft) + ? utilities.imageToWorldCoords( + imageId || currentImageId, + coords.topLeft + ) : viewport.canvasToWorld(coords.topLeft); const worldEnd = type === 'image' - ? utilities.imageToWorldCoords(currentImageId, coords.topRight) + ? utilities.imageToWorldCoords( + imageId || currentImageId, + coords.topRight + ) : viewport.canvasToWorld(coords.topRight); LengthTool.hydrate(viewport.id, [worldStart, worldEnd]); diff --git a/packages/tools/examples/dynamicallyAddAnnotations/probeToolUI.ts b/packages/tools/examples/dynamicallyAddAnnotations/probeToolUI.ts index 23d022f8b7..71df27ed8d 100644 --- a/packages/tools/examples/dynamicallyAddAnnotations/probeToolUI.ts +++ b/packages/tools/examples/dynamicallyAddAnnotations/probeToolUI.ts @@ -42,6 +42,11 @@ function createFormElement(): HTMLFormElement {
+ ${ + coordType === 'image' + ? ` ` + : '' + }

`; }); @@ -53,20 +58,25 @@ function addButtonListeners(form: HTMLFormElement): void { const buttons = form.querySelectorAll('button'); buttons.forEach((button) => { button.addEventListener('click', () => { - const [type, viewportType] = button.id.split('-') as [ + const [type, viewportType, useImageId] = button.id.split('-') as [ 'canvas' | 'image', - keyof typeof typeToIdMap + keyof typeof typeToIdMap, + 'imageId'? ]; const enabledElement = getEnabledElementByViewportId( typeToIdMap[viewportType] ); const viewport = enabledElement.viewport; + const imageId = useImageId && viewport.getImageIds()[0]; const coords = getCoordinates(form, type); const currentImageId = viewport.getCurrentImageId() as string; const worldStart = type === 'image' - ? utilities.imageToWorldCoords(currentImageId, coords.topLeft) + ? utilities.imageToWorldCoords( + imageId || currentImageId, + coords.topLeft + ) : viewport.canvasToWorld(coords.topLeft); ProbeTool.hydrate(viewport.id, [worldStart]); diff --git a/packages/tools/examples/dynamicallyAddAnnotations/rectangleROIToolUI.ts b/packages/tools/examples/dynamicallyAddAnnotations/rectangleROIToolUI.ts index 62284e766a..0e5acad432 100644 --- a/packages/tools/examples/dynamicallyAddAnnotations/rectangleROIToolUI.ts +++ b/packages/tools/examples/dynamicallyAddAnnotations/rectangleROIToolUI.ts @@ -71,6 +71,11 @@ function createFormElement(): HTMLFormElement {
+ ${ + coordType === 'image' + ? ` ` + : '' + }

`; }); @@ -82,20 +87,25 @@ function addButtonListeners(form: HTMLFormElement): void { const buttons = form.querySelectorAll('button'); buttons.forEach((button) => { button.addEventListener('click', () => { - const [type, viewportType] = button.id.split('-') as [ + const [type, viewportType, useImageId] = button.id.split('-') as [ 'canvas' | 'image', - keyof typeof typeToIdMap + keyof typeof typeToIdMap, + 'imageId'? ]; const enabledElement = getEnabledElementByViewportId( typeToIdMap[viewportType] ); const viewport = enabledElement.viewport; + const imageId = useImageId && viewport.getImageIds()[0]; const coords = getCoordinates(form, type); const currentImageId = viewport.getCurrentImageId() as string; const convertPoint = (point: Point2): Point3 => type === 'image' - ? (utilities.imageToWorldCoords(currentImageId, point) as Point3) + ? (utilities.imageToWorldCoords( + imageId || currentImageId, + point + ) as Point3) : viewport.canvasToWorld(point); const points: Point3[] = [ diff --git a/packages/tools/examples/dynamicallyAddAnnotations/splineROIToolUI.ts b/packages/tools/examples/dynamicallyAddAnnotations/splineROIToolUI.ts index de9b56b0f8..d2dcb39983 100644 --- a/packages/tools/examples/dynamicallyAddAnnotations/splineROIToolUI.ts +++ b/packages/tools/examples/dynamicallyAddAnnotations/splineROIToolUI.ts @@ -65,6 +65,11 @@ function createFormElement(): HTMLFormElement {
+ ${ + coordType === 'image' + ? ` ` + : '' + }

`; }); @@ -76,37 +81,48 @@ function addButtonListeners(form: HTMLFormElement): void { const buttons = form.querySelectorAll('button'); buttons.forEach((button) => { button.addEventListener('click', () => { - const [type, viewportType] = button.id.split('-') as [ + const [type, viewportType, useImageId] = button.id.split('-') as [ 'canvas' | 'image', - keyof typeof typeToIdMap + keyof typeof typeToIdMap, + 'imageId'? ]; const enabledElement = getEnabledElementByViewportId( typeToIdMap[viewportType] ); const viewport = enabledElement.viewport; + const imageId = useImageId && viewport.getImageIds()[0]; const coords = getCoordinates(form, type); const currentImageId = viewport.getCurrentImageId() as string; const worldPoint1 = type === 'image' - ? utilities.imageToWorldCoords(currentImageId, coords.point1) + ? utilities.imageToWorldCoords( + imageId || currentImageId, + coords.point1 + ) : viewport.canvasToWorld(coords.point1); const worldPoint2 = type === 'image' - ? utilities.imageToWorldCoords(currentImageId, coords.point2) + ? utilities.imageToWorldCoords( + imageId || currentImageId, + coords.point2 + ) : viewport.canvasToWorld(coords.point2); const worldPoint3 = type === 'image' - ? utilities.imageToWorldCoords(currentImageId, coords.point3) + ? utilities.imageToWorldCoords( + imageId || currentImageId, + coords.point3 + ) : viewport.canvasToWorld(coords.point3); - SplineROITool.hydrate(viewport.id, [ - worldPoint1, - worldPoint2, - worldPoint3, - ]); + SplineROITool.hydrate( + viewport.id, + [worldPoint1, worldPoint2, worldPoint3], + { referencedImageId: imageId } + ); }); }); } diff --git a/packages/tools/src/tools/annotation/AngleTool.ts b/packages/tools/src/tools/annotation/AngleTool.ts index 06b37e5f63..41810a1164 100644 --- a/packages/tools/src/tools/annotation/AngleTool.ts +++ b/packages/tools/src/tools/annotation/AngleTool.ts @@ -88,6 +88,9 @@ class AngleTool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; + referencedImageId?: string; + viewplaneNormal?: Types.Point3; + viewUp?: Types.Point3; } ): AngleAnnotation => { const enabledElement = getEnabledElementByViewportId(viewportId); @@ -97,19 +100,36 @@ class AngleTool extends AnnotationTool { const { viewport } = enabledElement; const FrameOfReferenceUID = viewport.getFrameOfReferenceUID(); - const { viewPlaneNormal, viewUp } = viewport.getCamera(); + let { viewPlaneNormal, viewUp } = viewport.getCamera(); + if (options?.viewplaneNormal && options?.viewUp) { + viewPlaneNormal = options.viewplaneNormal; + viewUp = options.viewUp; + } // This is a workaround to access the protected method getReferencedImageId // we should make those static too const instance = new this(); - const referencedImageId = instance.getReferencedImageId( + let referencedImageId = instance.getReferencedImageId( viewport, points[0], viewPlaneNormal, viewUp ); + if (options?.referencedImageId) { + // If the provided referencedImageId is not the same as the one calculated + // by the camera positions, only set the referencedImageId. The scenario + // here is that only a referencedImageId is given in the options, which + // does not match the current camera position, so the user is wanting to + // apply the annotation to a specific image. + if (referencedImageId !== options.referencedImageId) { + viewPlaneNormal = undefined; + viewUp = undefined; + } + referencedImageId = options.referencedImageId; + } + const annotation = { annotationUID: options?.annotationUID || csUtils.uuidv4(), data: { diff --git a/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts b/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts index 198f668a63..fb52a23401 100644 --- a/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts +++ b/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts @@ -87,6 +87,9 @@ class ArrowAnnotateTool extends AnnotationTool { text?: string, options?: { annotationUID?: string; + referencedImageId?: string; + viewplaneNormal?: Types.Point3; + viewUp?: Types.Point3; } ): ArrowAnnotation => { const enabledElement = getEnabledElementByViewportId(viewportId); @@ -96,19 +99,36 @@ class ArrowAnnotateTool extends AnnotationTool { const { viewport } = enabledElement; const FrameOfReferenceUID = viewport.getFrameOfReferenceUID(); - const { viewPlaneNormal, viewUp } = viewport.getCamera(); + let { viewPlaneNormal, viewUp } = viewport.getCamera(); + if (options?.viewplaneNormal && options?.viewUp) { + viewPlaneNormal = options.viewplaneNormal; + viewUp = options.viewUp; + } // This is a workaround to access the protected method getReferencedImageId // we should make those static too const instance = new this(); - const referencedImageId = instance.getReferencedImageId( + let referencedImageId = instance.getReferencedImageId( viewport, points[0], viewPlaneNormal, viewUp ); + if (options?.referencedImageId) { + // If the provided referencedImageId is not the same as the one calculated + // by the camera positions, only set the referencedImageId. The scenario + // here is that only a referencedImageId is given in the options, which + // does not match the current camera position, so the user is wanting to + // apply the annotation to a specific image. + if (referencedImageId !== options.referencedImageId) { + viewPlaneNormal = undefined; + viewUp = undefined; + } + referencedImageId = options.referencedImageId; + } + const annotation = { annotationUID: options?.annotationUID || csUtils.uuidv4(), data: { diff --git a/packages/tools/src/tools/annotation/CircleROITool.ts b/packages/tools/src/tools/annotation/CircleROITool.ts index 8a338784b2..c201d1b4c8 100644 --- a/packages/tools/src/tools/annotation/CircleROITool.ts +++ b/packages/tools/src/tools/annotation/CircleROITool.ts @@ -1029,6 +1029,9 @@ class CircleROITool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; + referencedImageId?: string; + viewplaneNormal?: Types.Point3; + viewUp?: Types.Point3; } ): CircleROIAnnotation => { const enabledElement = getEnabledElementByViewportId(viewportId); @@ -1038,19 +1041,36 @@ class CircleROITool extends AnnotationTool { const { viewport } = enabledElement; const FrameOfReferenceUID = viewport.getFrameOfReferenceUID(); - const { viewPlaneNormal, viewUp } = viewport.getCamera(); + let { viewPlaneNormal, viewUp } = viewport.getCamera(); + if (options?.viewplaneNormal && options?.viewUp) { + viewPlaneNormal = options.viewplaneNormal; + viewUp = options.viewUp; + } // This is a workaround to access the protected method getReferencedImageId // we should make those static too const instance = new this(); - const referencedImageId = instance.getReferencedImageId( + let referencedImageId = instance.getReferencedImageId( viewport, points[0], viewPlaneNormal, viewUp ); + if (options?.referencedImageId) { + // If the provided referencedImageId is not the same as the one calculated + // by the camera positions, only set the referencedImageId. The scenario + // here is that only a referencedImageId is given in the options, which + // does not match the current camera position, so the user is wanting to + // apply the annotation to a specific image. + if (referencedImageId !== options.referencedImageId) { + viewPlaneNormal = undefined; + viewUp = undefined; + } + referencedImageId = options.referencedImageId; + } + const annotation = { annotationUID: options?.annotationUID || csUtils.uuidv4(), data: { diff --git a/packages/tools/src/tools/annotation/EllipticalROITool.ts b/packages/tools/src/tools/annotation/EllipticalROITool.ts index 11e4427d00..43752459b1 100644 --- a/packages/tools/src/tools/annotation/EllipticalROITool.ts +++ b/packages/tools/src/tools/annotation/EllipticalROITool.ts @@ -156,6 +156,9 @@ class EllipticalROITool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; + referencedImageId?: string; + viewplaneNormal?: Types.Point3; + viewUp?: Types.Point3; } ): EllipticalROIAnnotation => { const enabledElement = getEnabledElementByViewportId(viewportId); @@ -165,19 +168,36 @@ class EllipticalROITool extends AnnotationTool { const { viewport } = enabledElement; const FrameOfReferenceUID = viewport.getFrameOfReferenceUID(); - const { viewPlaneNormal, viewUp } = viewport.getCamera(); + let { viewPlaneNormal, viewUp } = viewport.getCamera(); + if (options?.viewplaneNormal && options?.viewUp) { + viewPlaneNormal = options.viewplaneNormal; + viewUp = options.viewUp; + } // This is a workaround to access the protected method getReferencedImageId // we should make those static too const instance = new this(); - const referencedImageId = instance.getReferencedImageId( + let referencedImageId = instance.getReferencedImageId( viewport, points[0], viewPlaneNormal, viewUp ); + if (options?.referencedImageId) { + // If the provided referencedImageId is not the same as the one calculated + // by the camera positions, only set the referencedImageId. The scenario + // here is that only a referencedImageId is given in the options, which + // does not match the current camera position, so the user is wanting to + // apply the annotation to a specific image. + if (referencedImageId !== options.referencedImageId) { + viewPlaneNormal = undefined; + viewUp = undefined; + } + referencedImageId = options.referencedImageId; + } + const annotation = { annotationUID: options?.annotationUID || csUtils.uuidv4(), data: { diff --git a/packages/tools/src/tools/annotation/LengthTool.ts b/packages/tools/src/tools/annotation/LengthTool.ts index a2c5ec3223..95c59307b1 100644 --- a/packages/tools/src/tools/annotation/LengthTool.ts +++ b/packages/tools/src/tools/annotation/LengthTool.ts @@ -138,6 +138,9 @@ class LengthTool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; + referencedImageId?: string; + viewplaneNormal?: Types.Point3; + viewUp?: Types.Point3; } ): LengthAnnotation => { const enabledElement = getEnabledElementByViewportId(viewportId); @@ -147,19 +150,36 @@ class LengthTool extends AnnotationTool { const { viewport } = enabledElement; const FrameOfReferenceUID = viewport.getFrameOfReferenceUID(); - const { viewPlaneNormal, viewUp } = viewport.getCamera(); + let { viewPlaneNormal, viewUp } = viewport.getCamera(); + if (options?.viewplaneNormal && options?.viewUp) { + viewPlaneNormal = options.viewplaneNormal; + viewUp = options.viewUp; + } // This is a workaround to access the protected method getReferencedImageId // we should make those static too const instance = new this(); - const referencedImageId = instance.getReferencedImageId( + let referencedImageId = instance.getReferencedImageId( viewport, points[0], viewPlaneNormal, viewUp ); + if (options?.referencedImageId) { + // If the provided referencedImageId is not the same as the one calculated + // by the camera positions, only set the referencedImageId. The scenario + // here is that only a referencedImageId is given in the options, which + // does not match the current camera position, so the user is wanting to + // apply the annotation to a specific image. + if (referencedImageId !== options.referencedImageId) { + viewPlaneNormal = undefined; + viewUp = undefined; + } + referencedImageId = options.referencedImageId; + } + const annotation = { annotationUID: options?.annotationUID || utilities.uuidv4(), data: { diff --git a/packages/tools/src/tools/annotation/ProbeTool.ts b/packages/tools/src/tools/annotation/ProbeTool.ts index 7327a9e58c..cbf9cac42b 100644 --- a/packages/tools/src/tools/annotation/ProbeTool.ts +++ b/packages/tools/src/tools/annotation/ProbeTool.ts @@ -149,6 +149,9 @@ class ProbeTool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; + referencedImageId?: string; + viewplaneNormal?: Types.Point3; + viewUp?: Types.Point3; } ): ProbeAnnotation => { const enabledElement = getEnabledElementByViewportId(viewportId); @@ -158,19 +161,36 @@ class ProbeTool extends AnnotationTool { const { viewport } = enabledElement; const FrameOfReferenceUID = viewport.getFrameOfReferenceUID(); - const { viewPlaneNormal, viewUp } = viewport.getCamera(); + let { viewPlaneNormal, viewUp } = viewport.getCamera(); + if (options?.viewplaneNormal && options?.viewUp) { + viewPlaneNormal = options.viewplaneNormal; + viewUp = options.viewUp; + } // This is a workaround to access the protected method getReferencedImageId // we should make those static too const instance = new this(); - const referencedImageId = instance.getReferencedImageId( + let referencedImageId = instance.getReferencedImageId( viewport, points[0], viewPlaneNormal, viewUp ); + if (options?.referencedImageId) { + // If the provided referencedImageId is not the same as the one calculated + // by the camera positions, only set the referencedImageId. The scenario + // here is that only a referencedImageId is given in the options, which + // does not match the current camera position, so the user is wanting to + // apply the annotation to a specific image. + if (referencedImageId !== options.referencedImageId) { + viewPlaneNormal = undefined; + viewUp = undefined; + } + referencedImageId = options.referencedImageId; + } + const annotation = { annotationUID: options?.annotationUID || csUtils.uuidv4(), data: { diff --git a/packages/tools/src/tools/annotation/RectangleROITool.ts b/packages/tools/src/tools/annotation/RectangleROITool.ts index 623c1a194d..74eaa476ed 100644 --- a/packages/tools/src/tools/annotation/RectangleROITool.ts +++ b/packages/tools/src/tools/annotation/RectangleROITool.ts @@ -973,6 +973,9 @@ class RectangleROITool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; + referencedImageId?: string; + viewplaneNormal?: Types.Point3; + viewUp?: Types.Point3; } ): RectangleROIAnnotation => { const enabledElement = getEnabledElementByViewportId(viewportId); @@ -982,19 +985,36 @@ class RectangleROITool extends AnnotationTool { const { viewport } = enabledElement; const FrameOfReferenceUID = viewport.getFrameOfReferenceUID(); - const { viewPlaneNormal, viewUp } = viewport.getCamera(); + let { viewPlaneNormal, viewUp } = viewport.getCamera(); + if (options?.viewplaneNormal && options?.viewUp) { + viewPlaneNormal = options.viewplaneNormal; + viewUp = options.viewUp; + } // This is a workaround to access the protected method getReferencedImageId // we should make those static too const instance = new this(); - const referencedImageId = instance.getReferencedImageId( + let referencedImageId = instance.getReferencedImageId( viewport, points[0], viewPlaneNormal, viewUp ); + if (options?.referencedImageId) { + // If the provided referencedImageId is not the same as the one calculated + // by the camera positions, only set the referencedImageId. The scenario + // here is that only a referencedImageId is given in the options, which + // does not match the current camera position, so the user is wanting to + // apply the annotation to a specific image. + if (referencedImageId !== options.referencedImageId) { + viewPlaneNormal = undefined; + viewUp = undefined; + } + referencedImageId = options.referencedImageId; + } + const annotation = { annotationUID: options?.annotationUID || csUtils.uuidv4(), data: { diff --git a/packages/tools/src/tools/annotation/SplineROITool.ts b/packages/tools/src/tools/annotation/SplineROITool.ts index 9b13128359..6170ab4b9d 100644 --- a/packages/tools/src/tools/annotation/SplineROITool.ts +++ b/packages/tools/src/tools/annotation/SplineROITool.ts @@ -1240,6 +1240,9 @@ class SplineROITool extends ContourSegmentationBaseTool { options?: { annotationUID?: string; splineType?: SplineTypesEnum; + referencedImageId?: string; + viewplaneNormal?: Types.Point3; + viewUp?: Types.Point3; } ): SplineROIAnnotation => { const enabledElement = getEnabledElementByViewportId(viewportId); @@ -1254,32 +1257,56 @@ class SplineROITool extends ContourSegmentationBaseTool { const { viewport } = enabledElement; const FrameOfReferenceUID = viewport.getFrameOfReferenceUID(); - const { viewPlaneNormal, viewUp } = viewport.getCamera(); + + let { viewPlaneNormal, viewUp } = viewport.getCamera(); + if (options?.viewplaneNormal && options?.viewUp) { + viewPlaneNormal = options.viewplaneNormal; + viewUp = options.viewUp; + } // This is a workaround to access the protected method getReferencedImageId // we should make those static too const instance = new this(); - const referencedImageId = instance.getReferencedImageId( + let referencedImageId = instance.getReferencedImageId( viewport, points[0], viewPlaneNormal, viewUp ); + if (options?.referencedImageId) { + // If the provided referencedImageId is not the same as the one calculated + // by the camera positions, only set the referencedImageId. The scenario + // here is that only a referencedImageId is given in the options, which + // does not match the current camera position, so the user is wanting to + // apply the annotation to a specific image. + if (referencedImageId !== options.referencedImageId) { + viewPlaneNormal = undefined; + viewUp = undefined; + } + referencedImageId = options.referencedImageId; + } + // Create appropriate spline instance based on type or default const splineType = options?.splineType || SplineTypesEnum.CatmullRom; const splineConfig = instance._getSplineConfig(splineType); const SplineClass = splineConfig.Class; const splineInstance = new SplineClass(); - // Convert world points to canvas for the spline - const canvasPoints = points.map((point) => viewport.worldToCanvas(point)); - splineInstance.setControlPoints(canvasPoints); - const splinePolylineCanvas = splineInstance.getPolylinePoints(); - const splinePolylineWorld = splinePolylineCanvas.map((point) => - viewport.canvasToWorld(point) - ); + /** + * The following appears to be done when rendering the spline, so don't need + * to do it here. This is helpful anyways because if we are adding an + * annotation to an image/plane that is not currently displayed we can't get + * the canvas coordinates for the points. + */ + // Convert world points to canvas for the spline + // const canvasPoints = points.map((point) => viewport.worldToCanvas(point)); + // splineInstance.setControlPoints(canvasPoints); + // const splinePolylineCanvas = splineInstance.getPolylinePoints(); + // const splinePolylineWorld = splinePolylineCanvas.map((point) => + // viewport.canvasToWorld(point) + // ); const annotation = { annotationUID: options?.annotationUID || utilities.uuidv4(), @@ -1295,7 +1322,7 @@ class SplineROITool extends ContourSegmentationBaseTool { }, contour: { closed: true, - polyline: splinePolylineWorld, + // polyline: splinePolylineWorld, }, }, highlighted: false, From 1fa2892e3cf620be481efa6d6957019cac6a570b Mon Sep 17 00:00:00 2001 From: Jason Hostetter MD Date: Thu, 23 Jan 2025 13:42:19 -0500 Subject: [PATCH 2/4] Add option to pass an existing tool instance to the hydrate method, so that the correct config is used. --- common/reviews/api/tools.api.md | 8 ++++++++ packages/tools/src/tools/annotation/AngleTool.ts | 3 ++- packages/tools/src/tools/annotation/ArrowAnnotateTool.ts | 3 ++- packages/tools/src/tools/annotation/CircleROITool.ts | 3 ++- packages/tools/src/tools/annotation/EllipticalROITool.ts | 3 ++- packages/tools/src/tools/annotation/LengthTool.ts | 3 ++- packages/tools/src/tools/annotation/ProbeTool.ts | 3 ++- packages/tools/src/tools/annotation/RectangleROITool.ts | 3 ++- packages/tools/src/tools/annotation/SplineROITool.ts | 6 ++++-- 9 files changed, 26 insertions(+), 9 deletions(-) diff --git a/common/reviews/api/tools.api.md b/common/reviews/api/tools.api.md index db43889fb6..f87183aefd 100644 --- a/common/reviews/api/tools.api.md +++ b/common/reviews/api/tools.api.md @@ -231,6 +231,7 @@ export class AngleTool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; + instance?: AngleTool; referencedImageId?: string; viewplaneNormal?: Types_2.Point3; viewUp?: Types_2.Point3; @@ -648,6 +649,7 @@ export class ArrowAnnotateTool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], text?: string, options?: { annotationUID?: string; + instance?: ArrowAnnotateTool; referencedImageId?: string; viewplaneNormal?: Types_2.Point3; viewUp?: Types_2.Point3; @@ -1250,6 +1252,7 @@ export class CircleROITool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; + instance?: CircleROITool; referencedImageId?: string; viewplaneNormal?: Types_2.Point3; viewUp?: Types_2.Point3; @@ -2240,6 +2243,7 @@ export class EllipticalROITool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; + instance?: EllipticalROITool; referencedImageId?: string; viewplaneNormal?: Types_2.Point3; viewUp?: Types_2.Point3; @@ -3651,6 +3655,7 @@ export class LengthTool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; + instance?: LengthTool; referencedImageId?: string; viewplaneNormal?: Types_2.Point3; viewUp?: Types_2.Point3; @@ -4421,6 +4426,7 @@ export class ProbeTool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; + instance?: ProbeTool; referencedImageId?: string; viewplaneNormal?: Types_2.Point3; viewUp?: Types_2.Point3; @@ -4755,6 +4761,7 @@ export class RectangleROITool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; + instance?: RectangleROITool; referencedImageId?: string; viewplaneNormal?: Types_2.Point3; viewUp?: Types_2.Point3; @@ -5697,6 +5704,7 @@ export class SplineROITool extends ContourSegmentationBaseTool { static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; splineType?: SplineTypesEnum; + instance?: SplineROITool; referencedImageId?: string; viewplaneNormal?: Types_2.Point3; viewUp?: Types_2.Point3; diff --git a/packages/tools/src/tools/annotation/AngleTool.ts b/packages/tools/src/tools/annotation/AngleTool.ts index 41810a1164..e1158e62b0 100644 --- a/packages/tools/src/tools/annotation/AngleTool.ts +++ b/packages/tools/src/tools/annotation/AngleTool.ts @@ -88,6 +88,7 @@ class AngleTool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; + instance?: AngleTool; referencedImageId?: string; viewplaneNormal?: Types.Point3; viewUp?: Types.Point3; @@ -108,7 +109,7 @@ class AngleTool extends AnnotationTool { // This is a workaround to access the protected method getReferencedImageId // we should make those static too - const instance = new this(); + const instance = options.instance || new this(); let referencedImageId = instance.getReferencedImageId( viewport, diff --git a/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts b/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts index fb52a23401..6380fe8ec5 100644 --- a/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts +++ b/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts @@ -87,6 +87,7 @@ class ArrowAnnotateTool extends AnnotationTool { text?: string, options?: { annotationUID?: string; + instance?: ArrowAnnotateTool; referencedImageId?: string; viewplaneNormal?: Types.Point3; viewUp?: Types.Point3; @@ -107,7 +108,7 @@ class ArrowAnnotateTool extends AnnotationTool { // This is a workaround to access the protected method getReferencedImageId // we should make those static too - const instance = new this(); + const instance = options.instance || new this(); let referencedImageId = instance.getReferencedImageId( viewport, diff --git a/packages/tools/src/tools/annotation/CircleROITool.ts b/packages/tools/src/tools/annotation/CircleROITool.ts index c201d1b4c8..6cf6698b33 100644 --- a/packages/tools/src/tools/annotation/CircleROITool.ts +++ b/packages/tools/src/tools/annotation/CircleROITool.ts @@ -1029,6 +1029,7 @@ class CircleROITool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; + instance?: CircleROITool; referencedImageId?: string; viewplaneNormal?: Types.Point3; viewUp?: Types.Point3; @@ -1049,7 +1050,7 @@ class CircleROITool extends AnnotationTool { // This is a workaround to access the protected method getReferencedImageId // we should make those static too - const instance = new this(); + const instance = options.instance || new this(); let referencedImageId = instance.getReferencedImageId( viewport, diff --git a/packages/tools/src/tools/annotation/EllipticalROITool.ts b/packages/tools/src/tools/annotation/EllipticalROITool.ts index 43752459b1..1f7910c65e 100644 --- a/packages/tools/src/tools/annotation/EllipticalROITool.ts +++ b/packages/tools/src/tools/annotation/EllipticalROITool.ts @@ -156,6 +156,7 @@ class EllipticalROITool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; + instance?: EllipticalROITool; referencedImageId?: string; viewplaneNormal?: Types.Point3; viewUp?: Types.Point3; @@ -176,7 +177,7 @@ class EllipticalROITool extends AnnotationTool { // This is a workaround to access the protected method getReferencedImageId // we should make those static too - const instance = new this(); + const instance = options.instance || new this(); let referencedImageId = instance.getReferencedImageId( viewport, diff --git a/packages/tools/src/tools/annotation/LengthTool.ts b/packages/tools/src/tools/annotation/LengthTool.ts index 95c59307b1..93f2f4555d 100644 --- a/packages/tools/src/tools/annotation/LengthTool.ts +++ b/packages/tools/src/tools/annotation/LengthTool.ts @@ -138,6 +138,7 @@ class LengthTool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; + instance?: LengthTool; referencedImageId?: string; viewplaneNormal?: Types.Point3; viewUp?: Types.Point3; @@ -158,7 +159,7 @@ class LengthTool extends AnnotationTool { // This is a workaround to access the protected method getReferencedImageId // we should make those static too - const instance = new this(); + const instance = options.instance || new this(); let referencedImageId = instance.getReferencedImageId( viewport, diff --git a/packages/tools/src/tools/annotation/ProbeTool.ts b/packages/tools/src/tools/annotation/ProbeTool.ts index cbf9cac42b..90b4a6e0d8 100644 --- a/packages/tools/src/tools/annotation/ProbeTool.ts +++ b/packages/tools/src/tools/annotation/ProbeTool.ts @@ -149,6 +149,7 @@ class ProbeTool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; + instance?: ProbeTool; referencedImageId?: string; viewplaneNormal?: Types.Point3; viewUp?: Types.Point3; @@ -169,7 +170,7 @@ class ProbeTool extends AnnotationTool { // This is a workaround to access the protected method getReferencedImageId // we should make those static too - const instance = new this(); + const instance = options.instance || new this(); let referencedImageId = instance.getReferencedImageId( viewport, diff --git a/packages/tools/src/tools/annotation/RectangleROITool.ts b/packages/tools/src/tools/annotation/RectangleROITool.ts index 74eaa476ed..c665280161 100644 --- a/packages/tools/src/tools/annotation/RectangleROITool.ts +++ b/packages/tools/src/tools/annotation/RectangleROITool.ts @@ -973,6 +973,7 @@ class RectangleROITool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; + instance?: RectangleROITool; referencedImageId?: string; viewplaneNormal?: Types.Point3; viewUp?: Types.Point3; @@ -993,7 +994,7 @@ class RectangleROITool extends AnnotationTool { // This is a workaround to access the protected method getReferencedImageId // we should make those static too - const instance = new this(); + const instance = options.instance || new this(); let referencedImageId = instance.getReferencedImageId( viewport, diff --git a/packages/tools/src/tools/annotation/SplineROITool.ts b/packages/tools/src/tools/annotation/SplineROITool.ts index 6170ab4b9d..a288858c28 100644 --- a/packages/tools/src/tools/annotation/SplineROITool.ts +++ b/packages/tools/src/tools/annotation/SplineROITool.ts @@ -1240,6 +1240,7 @@ class SplineROITool extends ContourSegmentationBaseTool { options?: { annotationUID?: string; splineType?: SplineTypesEnum; + instance?: SplineROITool; referencedImageId?: string; viewplaneNormal?: Types.Point3; viewUp?: Types.Point3; @@ -1265,8 +1266,9 @@ class SplineROITool extends ContourSegmentationBaseTool { } // This is a workaround to access the protected method getReferencedImageId - // we should make those static too - const instance = new this(); + // we should make those static too Use the provided instance if available so + // that correct configuration is used. + const instance = options.instance || new this(); let referencedImageId = instance.getReferencedImageId( viewport, From 698ef5e71a4dae24e2e379401ba86d93a2340746 Mon Sep 17 00:00:00 2001 From: Jason Hostetter MD Date: Wed, 29 Jan 2025 10:10:59 -0500 Subject: [PATCH 3/4] PR review updates --- packages/tools/src/tools/annotation/AngleTool.ts | 10 ++++------ .../tools/src/tools/annotation/ArrowAnnotateTool.ts | 10 ++++------ packages/tools/src/tools/annotation/CircleROITool.ts | 10 ++++------ .../tools/src/tools/annotation/EllipticalROITool.ts | 10 ++++------ packages/tools/src/tools/annotation/LengthTool.ts | 10 ++++------ packages/tools/src/tools/annotation/ProbeTool.ts | 10 ++++------ .../tools/src/tools/annotation/RectangleROITool.ts | 10 ++++------ packages/tools/src/tools/annotation/SplineROITool.ts | 10 ++++------ 8 files changed, 32 insertions(+), 48 deletions(-) diff --git a/packages/tools/src/tools/annotation/AngleTool.ts b/packages/tools/src/tools/annotation/AngleTool.ts index e1158e62b0..14756d45da 100644 --- a/packages/tools/src/tools/annotation/AngleTool.ts +++ b/packages/tools/src/tools/annotation/AngleTool.ts @@ -88,7 +88,7 @@ class AngleTool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; - instance?: AngleTool; + toolInstance?: AngleTool; referencedImageId?: string; viewplaneNormal?: Types.Point3; viewUp?: Types.Point3; @@ -102,14 +102,12 @@ class AngleTool extends AnnotationTool { const FrameOfReferenceUID = viewport.getFrameOfReferenceUID(); let { viewPlaneNormal, viewUp } = viewport.getCamera(); - if (options?.viewplaneNormal && options?.viewUp) { - viewPlaneNormal = options.viewplaneNormal; - viewUp = options.viewUp; - } + viewPlaneNormal = options?.viewplaneNormal ?? viewPlaneNormal; + viewUp = options?.viewUp ?? viewUp; // This is a workaround to access the protected method getReferencedImageId // we should make those static too - const instance = options.instance || new this(); + const instance = options?.toolInstance ?? new this(); let referencedImageId = instance.getReferencedImageId( viewport, diff --git a/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts b/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts index 6380fe8ec5..5917f7b8b2 100644 --- a/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts +++ b/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts @@ -87,7 +87,7 @@ class ArrowAnnotateTool extends AnnotationTool { text?: string, options?: { annotationUID?: string; - instance?: ArrowAnnotateTool; + toolInstance?: ArrowAnnotateTool; referencedImageId?: string; viewplaneNormal?: Types.Point3; viewUp?: Types.Point3; @@ -101,14 +101,12 @@ class ArrowAnnotateTool extends AnnotationTool { const FrameOfReferenceUID = viewport.getFrameOfReferenceUID(); let { viewPlaneNormal, viewUp } = viewport.getCamera(); - if (options?.viewplaneNormal && options?.viewUp) { - viewPlaneNormal = options.viewplaneNormal; - viewUp = options.viewUp; - } + viewPlaneNormal = options?.viewplaneNormal ?? viewPlaneNormal; + viewUp = options?.viewUp ?? viewUp; // This is a workaround to access the protected method getReferencedImageId // we should make those static too - const instance = options.instance || new this(); + const instance = options?.toolInstance ?? new this(); let referencedImageId = instance.getReferencedImageId( viewport, diff --git a/packages/tools/src/tools/annotation/CircleROITool.ts b/packages/tools/src/tools/annotation/CircleROITool.ts index 6cf6698b33..931ab915ca 100644 --- a/packages/tools/src/tools/annotation/CircleROITool.ts +++ b/packages/tools/src/tools/annotation/CircleROITool.ts @@ -1029,7 +1029,7 @@ class CircleROITool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; - instance?: CircleROITool; + toolInstance?: CircleROITool; referencedImageId?: string; viewplaneNormal?: Types.Point3; viewUp?: Types.Point3; @@ -1043,14 +1043,12 @@ class CircleROITool extends AnnotationTool { const FrameOfReferenceUID = viewport.getFrameOfReferenceUID(); let { viewPlaneNormal, viewUp } = viewport.getCamera(); - if (options?.viewplaneNormal && options?.viewUp) { - viewPlaneNormal = options.viewplaneNormal; - viewUp = options.viewUp; - } + viewPlaneNormal = options?.viewplaneNormal ?? viewPlaneNormal; + viewUp = options?.viewUp ?? viewUp; // This is a workaround to access the protected method getReferencedImageId // we should make those static too - const instance = options.instance || new this(); + const instance = options?.toolInstance ?? new this(); let referencedImageId = instance.getReferencedImageId( viewport, diff --git a/packages/tools/src/tools/annotation/EllipticalROITool.ts b/packages/tools/src/tools/annotation/EllipticalROITool.ts index 1f7910c65e..502c8373da 100644 --- a/packages/tools/src/tools/annotation/EllipticalROITool.ts +++ b/packages/tools/src/tools/annotation/EllipticalROITool.ts @@ -156,7 +156,7 @@ class EllipticalROITool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; - instance?: EllipticalROITool; + toolInstance?: EllipticalROITool; referencedImageId?: string; viewplaneNormal?: Types.Point3; viewUp?: Types.Point3; @@ -170,14 +170,12 @@ class EllipticalROITool extends AnnotationTool { const FrameOfReferenceUID = viewport.getFrameOfReferenceUID(); let { viewPlaneNormal, viewUp } = viewport.getCamera(); - if (options?.viewplaneNormal && options?.viewUp) { - viewPlaneNormal = options.viewplaneNormal; - viewUp = options.viewUp; - } + viewPlaneNormal = options?.viewplaneNormal ?? viewPlaneNormal; + viewUp = options?.viewUp ?? viewUp; // This is a workaround to access the protected method getReferencedImageId // we should make those static too - const instance = options.instance || new this(); + const instance = options?.toolInstance ?? new this(); let referencedImageId = instance.getReferencedImageId( viewport, diff --git a/packages/tools/src/tools/annotation/LengthTool.ts b/packages/tools/src/tools/annotation/LengthTool.ts index 93f2f4555d..03827d84ec 100644 --- a/packages/tools/src/tools/annotation/LengthTool.ts +++ b/packages/tools/src/tools/annotation/LengthTool.ts @@ -138,7 +138,7 @@ class LengthTool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; - instance?: LengthTool; + toolInstance?: LengthTool; referencedImageId?: string; viewplaneNormal?: Types.Point3; viewUp?: Types.Point3; @@ -152,14 +152,12 @@ class LengthTool extends AnnotationTool { const FrameOfReferenceUID = viewport.getFrameOfReferenceUID(); let { viewPlaneNormal, viewUp } = viewport.getCamera(); - if (options?.viewplaneNormal && options?.viewUp) { - viewPlaneNormal = options.viewplaneNormal; - viewUp = options.viewUp; - } + viewPlaneNormal = options?.viewplaneNormal ?? viewPlaneNormal; + viewUp = options?.viewUp ?? viewUp; // This is a workaround to access the protected method getReferencedImageId // we should make those static too - const instance = options.instance || new this(); + const instance = options?.toolInstance ?? new this(); let referencedImageId = instance.getReferencedImageId( viewport, diff --git a/packages/tools/src/tools/annotation/ProbeTool.ts b/packages/tools/src/tools/annotation/ProbeTool.ts index 90b4a6e0d8..9babf47551 100644 --- a/packages/tools/src/tools/annotation/ProbeTool.ts +++ b/packages/tools/src/tools/annotation/ProbeTool.ts @@ -149,7 +149,7 @@ class ProbeTool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; - instance?: ProbeTool; + toolInstance?: ProbeTool; referencedImageId?: string; viewplaneNormal?: Types.Point3; viewUp?: Types.Point3; @@ -163,14 +163,12 @@ class ProbeTool extends AnnotationTool { const FrameOfReferenceUID = viewport.getFrameOfReferenceUID(); let { viewPlaneNormal, viewUp } = viewport.getCamera(); - if (options?.viewplaneNormal && options?.viewUp) { - viewPlaneNormal = options.viewplaneNormal; - viewUp = options.viewUp; - } + viewPlaneNormal = options?.viewplaneNormal ?? viewPlaneNormal; + viewUp = options?.viewUp ?? viewUp; // This is a workaround to access the protected method getReferencedImageId // we should make those static too - const instance = options.instance || new this(); + const instance = options?.toolInstance ?? new this(); let referencedImageId = instance.getReferencedImageId( viewport, diff --git a/packages/tools/src/tools/annotation/RectangleROITool.ts b/packages/tools/src/tools/annotation/RectangleROITool.ts index c665280161..693a26e5db 100644 --- a/packages/tools/src/tools/annotation/RectangleROITool.ts +++ b/packages/tools/src/tools/annotation/RectangleROITool.ts @@ -973,7 +973,7 @@ class RectangleROITool extends AnnotationTool { points: Types.Point3[], options?: { annotationUID?: string; - instance?: RectangleROITool; + toolInstance?: RectangleROITool; referencedImageId?: string; viewplaneNormal?: Types.Point3; viewUp?: Types.Point3; @@ -987,14 +987,12 @@ class RectangleROITool extends AnnotationTool { const FrameOfReferenceUID = viewport.getFrameOfReferenceUID(); let { viewPlaneNormal, viewUp } = viewport.getCamera(); - if (options?.viewplaneNormal && options?.viewUp) { - viewPlaneNormal = options.viewplaneNormal; - viewUp = options.viewUp; - } + viewPlaneNormal = options?.viewplaneNormal ?? viewPlaneNormal; + viewUp = options?.viewUp ?? viewUp; // This is a workaround to access the protected method getReferencedImageId // we should make those static too - const instance = options.instance || new this(); + const instance = options?.toolInstance ?? new this(); let referencedImageId = instance.getReferencedImageId( viewport, diff --git a/packages/tools/src/tools/annotation/SplineROITool.ts b/packages/tools/src/tools/annotation/SplineROITool.ts index a288858c28..c4608d176c 100644 --- a/packages/tools/src/tools/annotation/SplineROITool.ts +++ b/packages/tools/src/tools/annotation/SplineROITool.ts @@ -1240,7 +1240,7 @@ class SplineROITool extends ContourSegmentationBaseTool { options?: { annotationUID?: string; splineType?: SplineTypesEnum; - instance?: SplineROITool; + toolInstance?: SplineROITool; referencedImageId?: string; viewplaneNormal?: Types.Point3; viewUp?: Types.Point3; @@ -1260,15 +1260,13 @@ class SplineROITool extends ContourSegmentationBaseTool { const FrameOfReferenceUID = viewport.getFrameOfReferenceUID(); let { viewPlaneNormal, viewUp } = viewport.getCamera(); - if (options?.viewplaneNormal && options?.viewUp) { - viewPlaneNormal = options.viewplaneNormal; - viewUp = options.viewUp; - } + viewPlaneNormal = options?.viewplaneNormal ?? viewPlaneNormal; + viewUp = options?.viewUp ?? viewUp; // This is a workaround to access the protected method getReferencedImageId // we should make those static too Use the provided instance if available so // that correct configuration is used. - const instance = options.instance || new this(); + const instance = options?.toolInstance ?? new this(); let referencedImageId = instance.getReferencedImageId( viewport, From 8d5080a7ec8c95d835b79b7efb74e2222b9077fb Mon Sep 17 00:00:00 2001 From: Jason Hostetter MD Date: Wed, 29 Jan 2025 10:12:15 -0500 Subject: [PATCH 4/4] Update api --- common/reviews/api/tools.api.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/common/reviews/api/tools.api.md b/common/reviews/api/tools.api.md index f87183aefd..e04222237f 100644 --- a/common/reviews/api/tools.api.md +++ b/common/reviews/api/tools.api.md @@ -231,7 +231,7 @@ export class AngleTool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; - instance?: AngleTool; + toolInstance?: AngleTool; referencedImageId?: string; viewplaneNormal?: Types_2.Point3; viewUp?: Types_2.Point3; @@ -649,7 +649,7 @@ export class ArrowAnnotateTool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], text?: string, options?: { annotationUID?: string; - instance?: ArrowAnnotateTool; + toolInstance?: ArrowAnnotateTool; referencedImageId?: string; viewplaneNormal?: Types_2.Point3; viewUp?: Types_2.Point3; @@ -1252,7 +1252,7 @@ export class CircleROITool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; - instance?: CircleROITool; + toolInstance?: CircleROITool; referencedImageId?: string; viewplaneNormal?: Types_2.Point3; viewUp?: Types_2.Point3; @@ -2243,7 +2243,7 @@ export class EllipticalROITool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; - instance?: EllipticalROITool; + toolInstance?: EllipticalROITool; referencedImageId?: string; viewplaneNormal?: Types_2.Point3; viewUp?: Types_2.Point3; @@ -3655,7 +3655,7 @@ export class LengthTool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; - instance?: LengthTool; + toolInstance?: LengthTool; referencedImageId?: string; viewplaneNormal?: Types_2.Point3; viewUp?: Types_2.Point3; @@ -4426,7 +4426,7 @@ export class ProbeTool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; - instance?: ProbeTool; + toolInstance?: ProbeTool; referencedImageId?: string; viewplaneNormal?: Types_2.Point3; viewUp?: Types_2.Point3; @@ -4761,7 +4761,7 @@ export class RectangleROITool extends AnnotationTool { // (undocumented) static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; - instance?: RectangleROITool; + toolInstance?: RectangleROITool; referencedImageId?: string; viewplaneNormal?: Types_2.Point3; viewUp?: Types_2.Point3; @@ -5704,7 +5704,7 @@ export class SplineROITool extends ContourSegmentationBaseTool { static hydrate: (viewportId: string, points: Types_2.Point3[], options?: { annotationUID?: string; splineType?: SplineTypesEnum; - instance?: SplineROITool; + toolInstance?: SplineROITool; referencedImageId?: string; viewplaneNormal?: Types_2.Point3; viewUp?: Types_2.Point3;