`;
});
@@ -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..14756d45da 100644
--- a/packages/tools/src/tools/annotation/AngleTool.ts
+++ b/packages/tools/src/tools/annotation/AngleTool.ts
@@ -88,6 +88,10 @@ class AngleTool extends AnnotationTool {
points: Types.Point3[],
options?: {
annotationUID?: string;
+ toolInstance?: AngleTool;
+ referencedImageId?: string;
+ viewplaneNormal?: Types.Point3;
+ viewUp?: Types.Point3;
}
): AngleAnnotation => {
const enabledElement = getEnabledElementByViewportId(viewportId);
@@ -97,19 +101,34 @@ class AngleTool extends AnnotationTool {
const { viewport } = enabledElement;
const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
- const { viewPlaneNormal, viewUp } = viewport.getCamera();
+ let { viewPlaneNormal, viewUp } = viewport.getCamera();
+ 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 = new this();
+ const instance = options?.toolInstance ?? 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..5917f7b8b2 100644
--- a/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts
+++ b/packages/tools/src/tools/annotation/ArrowAnnotateTool.ts
@@ -87,6 +87,10 @@ class ArrowAnnotateTool extends AnnotationTool {
text?: string,
options?: {
annotationUID?: string;
+ toolInstance?: ArrowAnnotateTool;
+ referencedImageId?: string;
+ viewplaneNormal?: Types.Point3;
+ viewUp?: Types.Point3;
}
): ArrowAnnotation => {
const enabledElement = getEnabledElementByViewportId(viewportId);
@@ -96,19 +100,34 @@ class ArrowAnnotateTool extends AnnotationTool {
const { viewport } = enabledElement;
const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
- const { viewPlaneNormal, viewUp } = viewport.getCamera();
+ let { viewPlaneNormal, viewUp } = viewport.getCamera();
+ 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 = new this();
+ const instance = options?.toolInstance ?? 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..931ab915ca 100644
--- a/packages/tools/src/tools/annotation/CircleROITool.ts
+++ b/packages/tools/src/tools/annotation/CircleROITool.ts
@@ -1029,6 +1029,10 @@ class CircleROITool extends AnnotationTool {
points: Types.Point3[],
options?: {
annotationUID?: string;
+ toolInstance?: CircleROITool;
+ referencedImageId?: string;
+ viewplaneNormal?: Types.Point3;
+ viewUp?: Types.Point3;
}
): CircleROIAnnotation => {
const enabledElement = getEnabledElementByViewportId(viewportId);
@@ -1038,19 +1042,34 @@ class CircleROITool extends AnnotationTool {
const { viewport } = enabledElement;
const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
- const { viewPlaneNormal, viewUp } = viewport.getCamera();
+ let { viewPlaneNormal, viewUp } = viewport.getCamera();
+ 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 = new this();
+ const instance = options?.toolInstance ?? 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..502c8373da 100644
--- a/packages/tools/src/tools/annotation/EllipticalROITool.ts
+++ b/packages/tools/src/tools/annotation/EllipticalROITool.ts
@@ -156,6 +156,10 @@ class EllipticalROITool extends AnnotationTool {
points: Types.Point3[],
options?: {
annotationUID?: string;
+ toolInstance?: EllipticalROITool;
+ referencedImageId?: string;
+ viewplaneNormal?: Types.Point3;
+ viewUp?: Types.Point3;
}
): EllipticalROIAnnotation => {
const enabledElement = getEnabledElementByViewportId(viewportId);
@@ -165,19 +169,34 @@ class EllipticalROITool extends AnnotationTool {
const { viewport } = enabledElement;
const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
- const { viewPlaneNormal, viewUp } = viewport.getCamera();
+ let { viewPlaneNormal, viewUp } = viewport.getCamera();
+ 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 = new this();
+ const instance = options?.toolInstance ?? 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..03827d84ec 100644
--- a/packages/tools/src/tools/annotation/LengthTool.ts
+++ b/packages/tools/src/tools/annotation/LengthTool.ts
@@ -138,6 +138,10 @@ class LengthTool extends AnnotationTool {
points: Types.Point3[],
options?: {
annotationUID?: string;
+ toolInstance?: LengthTool;
+ referencedImageId?: string;
+ viewplaneNormal?: Types.Point3;
+ viewUp?: Types.Point3;
}
): LengthAnnotation => {
const enabledElement = getEnabledElementByViewportId(viewportId);
@@ -147,19 +151,34 @@ class LengthTool extends AnnotationTool {
const { viewport } = enabledElement;
const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
- const { viewPlaneNormal, viewUp } = viewport.getCamera();
+ let { viewPlaneNormal, viewUp } = viewport.getCamera();
+ 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 = new this();
+ const instance = options?.toolInstance ?? 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..9babf47551 100644
--- a/packages/tools/src/tools/annotation/ProbeTool.ts
+++ b/packages/tools/src/tools/annotation/ProbeTool.ts
@@ -149,6 +149,10 @@ class ProbeTool extends AnnotationTool {
points: Types.Point3[],
options?: {
annotationUID?: string;
+ toolInstance?: ProbeTool;
+ referencedImageId?: string;
+ viewplaneNormal?: Types.Point3;
+ viewUp?: Types.Point3;
}
): ProbeAnnotation => {
const enabledElement = getEnabledElementByViewportId(viewportId);
@@ -158,19 +162,34 @@ class ProbeTool extends AnnotationTool {
const { viewport } = enabledElement;
const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
- const { viewPlaneNormal, viewUp } = viewport.getCamera();
+ let { viewPlaneNormal, viewUp } = viewport.getCamera();
+ 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 = new this();
+ const instance = options?.toolInstance ?? 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..693a26e5db 100644
--- a/packages/tools/src/tools/annotation/RectangleROITool.ts
+++ b/packages/tools/src/tools/annotation/RectangleROITool.ts
@@ -973,6 +973,10 @@ class RectangleROITool extends AnnotationTool {
points: Types.Point3[],
options?: {
annotationUID?: string;
+ toolInstance?: RectangleROITool;
+ referencedImageId?: string;
+ viewplaneNormal?: Types.Point3;
+ viewUp?: Types.Point3;
}
): RectangleROIAnnotation => {
const enabledElement = getEnabledElementByViewportId(viewportId);
@@ -982,19 +986,34 @@ class RectangleROITool extends AnnotationTool {
const { viewport } = enabledElement;
const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
- const { viewPlaneNormal, viewUp } = viewport.getCamera();
+ let { viewPlaneNormal, viewUp } = viewport.getCamera();
+ 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 = new this();
+ const instance = options?.toolInstance ?? 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..c4608d176c 100644
--- a/packages/tools/src/tools/annotation/SplineROITool.ts
+++ b/packages/tools/src/tools/annotation/SplineROITool.ts
@@ -1240,6 +1240,10 @@ class SplineROITool extends ContourSegmentationBaseTool {
options?: {
annotationUID?: string;
splineType?: SplineTypesEnum;
+ toolInstance?: SplineROITool;
+ referencedImageId?: string;
+ viewplaneNormal?: Types.Point3;
+ viewUp?: Types.Point3;
}
): SplineROIAnnotation => {
const enabledElement = getEnabledElementByViewportId(viewportId);
@@ -1254,32 +1258,55 @@ class SplineROITool extends ContourSegmentationBaseTool {
const { viewport } = enabledElement;
const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
- const { viewPlaneNormal, viewUp } = viewport.getCamera();
+
+ let { viewPlaneNormal, viewUp } = viewport.getCamera();
+ 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 = new this();
+ // we should make those static too Use the provided instance if available so
+ // that correct configuration is used.
+ const instance = options?.toolInstance ?? 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,