@cornerstonejs/tools 4.4.1 → 4.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { AnnotationTool } from '../base';
2
- import { getEnabledElement, VolumeViewport, utilities as csUtils, getEnabledElementByViewportId, } from '@cornerstonejs/core';
3
- import { getCalibratedLengthUnitsAndScale } from '../../utilities/getCalibratedUnits';
2
+ import { getEnabledElement, VolumeViewport, utilities as csUtils, getEnabledElementByViewportId, EPSILON, } from '@cornerstonejs/core';
3
+ import { getCalibratedAspect, getCalibratedLengthUnitsAndScale, } from '../../utilities/getCalibratedUnits';
4
4
  import throttle from '../../utilities/throttle';
5
5
  import { addAnnotation, getAnnotations, removeAnnotation, } from '../../stateManagement/annotation/annotationState';
6
6
  import { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking';
@@ -535,68 +535,79 @@ class EllipticalROITool extends AnnotationTool {
535
535
  pos1Index[0] = Math.floor(pos1Index[0]);
536
536
  pos1Index[1] = Math.floor(pos1Index[1]);
537
537
  pos1Index[2] = Math.floor(pos1Index[2]);
538
- const post2Index = transformWorldToIndex(imageData, worldPos2);
539
- post2Index[0] = Math.floor(post2Index[0]);
540
- post2Index[1] = Math.floor(post2Index[1]);
541
- post2Index[2] = Math.floor(post2Index[2]);
542
- this.isHandleOutsideImage = !this._isInsideVolume(pos1Index, post2Index, dimensions);
543
- const iMin = Math.min(pos1Index[0], post2Index[0]);
544
- const iMax = Math.max(pos1Index[0], post2Index[0]);
545
- const jMin = Math.min(pos1Index[1], post2Index[1]);
546
- const jMax = Math.max(pos1Index[1], post2Index[1]);
547
- const kMin = Math.min(pos1Index[2], post2Index[2]);
548
- const kMax = Math.max(pos1Index[2], post2Index[2]);
549
- const boundsIJK = [
550
- [iMin, iMax],
551
- [jMin, jMax],
552
- [kMin, kMax],
553
- ];
554
- const center = [
555
- (topLeftWorld[0] + bottomRightWorld[0]) / 2,
556
- (topLeftWorld[1] + bottomRightWorld[1]) / 2,
557
- (topLeftWorld[2] + bottomRightWorld[2]) / 2,
558
- ];
559
- const ellipseObj = {
560
- center,
561
- xRadius: Math.abs(topLeftWorld[0] - bottomRightWorld[0]) / 2,
562
- yRadius: Math.abs(topLeftWorld[1] - bottomRightWorld[1]) / 2,
563
- zRadius: Math.abs(topLeftWorld[2] - bottomRightWorld[2]) / 2,
564
- };
565
- const { worldWidth, worldHeight } = getWorldWidthAndHeightFromTwoPoints(viewPlaneNormal, viewUp, worldPos1, worldPos2);
566
- const isEmptyArea = worldWidth === 0 && worldHeight === 0;
567
- const handles = [pos1Index, post2Index];
568
- const { scale, areaUnit } = getCalibratedLengthUnitsAndScale(image, handles);
569
- const area = Math.abs(Math.PI * (worldWidth / 2) * (worldHeight / 2)) /
570
- scale /
571
- scale;
572
- const pixelUnitsOptions = {
573
- isPreScaled: isViewportPreScaled(viewport, targetId),
574
- isSuvScaled: this.isSuvScaled(viewport, targetId, annotation.metadata.referencedImageId),
575
- };
576
- const modalityUnit = getPixelValueUnits(metadata.Modality, annotation.metadata.referencedImageId, pixelUnitsOptions);
577
- let pointsInShape;
578
- if (voxelManager) {
579
- const pointsInShape = voxelManager.forEach(this.configuration.statsCalculator.statsCallback, {
580
- boundsIJK,
581
- imageData,
582
- isInObject: (pointLPS) => pointInEllipse(ellipseObj, pointLPS, { fast: true }),
583
- returnPoints: this.configuration.storePointData,
584
- });
538
+ const pos2Index = transformWorldToIndex(imageData, worldPos2);
539
+ pos2Index[0] = Math.floor(pos2Index[0]);
540
+ pos2Index[1] = Math.floor(pos2Index[1]);
541
+ pos2Index[2] = Math.floor(pos2Index[2]);
542
+ if (this._isInsideVolume(pos1Index, pos2Index, dimensions)) {
543
+ const iMin = Math.min(pos1Index[0], pos2Index[0]);
544
+ const iMax = Math.max(pos1Index[0], pos2Index[0]);
545
+ const jMin = Math.min(pos1Index[1], pos2Index[1]);
546
+ const jMax = Math.max(pos1Index[1], pos2Index[1]);
547
+ const kMin = Math.min(pos1Index[2], pos2Index[2]);
548
+ const kMax = Math.max(pos1Index[2], pos2Index[2]);
549
+ const boundsIJK = [
550
+ [iMin, iMax],
551
+ [jMin, jMax],
552
+ [kMin, kMax],
553
+ ];
554
+ const center = [
555
+ (topLeftWorld[0] + bottomRightWorld[0]) / 2,
556
+ (topLeftWorld[1] + bottomRightWorld[1]) / 2,
557
+ (topLeftWorld[2] + bottomRightWorld[2]) / 2,
558
+ ];
559
+ const xRadius = Math.abs(topLeftWorld[0] - bottomRightWorld[0]) / 2;
560
+ const yRadius = Math.abs(topLeftWorld[1] - bottomRightWorld[1]) / 2;
561
+ const zRadius = Math.abs(topLeftWorld[2] - bottomRightWorld[2]) / 2;
562
+ const ellipseObj = {
563
+ center,
564
+ xRadius: xRadius < EPSILON / 2 ? 0 : xRadius,
565
+ yRadius: yRadius < EPSILON / 2 ? 0 : yRadius,
566
+ zRadius: zRadius < EPSILON / 2 ? 0 : zRadius,
567
+ };
568
+ const { worldWidth, worldHeight } = getWorldWidthAndHeightFromTwoPoints(viewPlaneNormal, viewUp, worldPos1, worldPos2);
569
+ const isEmptyArea = worldWidth === 0 && worldHeight === 0;
570
+ const handles = [pos1Index, pos2Index];
571
+ const { scale, unit, areaUnit } = getCalibratedLengthUnitsAndScale(image, handles);
572
+ const aspect = getCalibratedAspect(image);
573
+ const area = Math.abs(Math.PI *
574
+ (worldWidth / scale / 2) *
575
+ (worldHeight / aspect / scale / 2));
576
+ const pixelUnitsOptions = {
577
+ isPreScaled: isViewportPreScaled(viewport, targetId),
578
+ isSuvScaled: this.isSuvScaled(viewport, targetId, annotation.metadata.referencedImageId),
579
+ };
580
+ const modalityUnit = getPixelValueUnits(metadata.Modality, annotation.metadata.referencedImageId, pixelUnitsOptions);
581
+ let pointsInShape;
582
+ if (voxelManager) {
583
+ pointsInShape = voxelManager.forEach(this.configuration.statsCalculator.statsCallback, {
584
+ isInObject: (pointLPS) => pointInEllipse(ellipseObj, pointLPS, { fast: true }),
585
+ boundsIJK,
586
+ imageData,
587
+ returnPoints: this.configuration.storePointData,
588
+ });
589
+ }
590
+ const stats = this.configuration.statsCalculator.getStatistics();
591
+ cachedStats[targetId] = {
592
+ Modality: metadata.Modality,
593
+ area,
594
+ mean: stats.mean?.value,
595
+ max: stats.max?.value,
596
+ min: stats.min?.value,
597
+ stdDev: stats.stdDev?.value,
598
+ statsArray: stats.array,
599
+ pointsInShape,
600
+ isEmptyArea,
601
+ areaUnit,
602
+ modalityUnit,
603
+ };
604
+ }
605
+ else {
606
+ this.isHandleOutsideImage = true;
607
+ cachedStats[targetId] = {
608
+ Modality: metadata.Modality,
609
+ };
585
610
  }
586
- const stats = this.configuration.statsCalculator.getStatistics();
587
- cachedStats[targetId] = {
588
- Modality: metadata.Modality,
589
- area,
590
- mean: stats.mean?.value,
591
- max: stats.max?.value,
592
- min: stats.min?.value,
593
- stdDev: stats.stdDev?.value,
594
- statsArray: stats.array,
595
- pointsInShape,
596
- isEmptyArea,
597
- areaUnit,
598
- modalityUnit,
599
- };
600
611
  }
601
612
  const invalidated = annotation.invalidated;
602
613
  annotation.invalidated = false;
@@ -1 +1 @@
1
- export declare const version = "4.4.1";
1
+ export declare const version = "4.4.2";
@@ -1 +1 @@
1
- export const version = '4.4.1';
1
+ export const version = '4.4.2';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cornerstonejs/tools",
3
- "version": "4.4.1",
3
+ "version": "4.4.2",
4
4
  "description": "Cornerstone3D Tools",
5
5
  "types": "./dist/esm/index.d.ts",
6
6
  "module": "./dist/esm/index.js",
@@ -108,7 +108,7 @@
108
108
  "canvas": "3.1.0"
109
109
  },
110
110
  "peerDependencies": {
111
- "@cornerstonejs/core": "4.4.1",
111
+ "@cornerstonejs/core": "4.4.2",
112
112
  "@kitware/vtk.js": "32.12.1",
113
113
  "@types/d3-array": "3.2.1",
114
114
  "@types/d3-interpolate": "3.0.4",
@@ -127,5 +127,5 @@
127
127
  "type": "individual",
128
128
  "url": "https://ohif.org/donate"
129
129
  },
130
- "gitHead": "a3125cde6a15894c53f1c4e8e7bcd31530b78aaf"
130
+ "gitHead": "e9db49c820e93f4b404ff0aa918ccb013191bebe"
131
131
  }