@cornerstonejs/tools 1.13.1 → 1.13.3

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.
Files changed (127) hide show
  1. package/dist/cjs/drawingSvg/drawCircle.js +9 -5
  2. package/dist/cjs/drawingSvg/drawCircle.js.map +1 -1
  3. package/dist/cjs/drawingSvg/drawEllipse.js +4 -4
  4. package/dist/cjs/drawingSvg/drawEllipse.js.map +1 -1
  5. package/dist/cjs/drawingSvg/drawHandles.js +4 -4
  6. package/dist/cjs/drawingSvg/drawHandles.js.map +1 -1
  7. package/dist/cjs/drawingSvg/drawLine.js +4 -4
  8. package/dist/cjs/drawingSvg/drawLine.js.map +1 -1
  9. package/dist/cjs/drawingSvg/drawPolyline.js +4 -4
  10. package/dist/cjs/drawingSvg/drawPolyline.js.map +1 -1
  11. package/dist/cjs/drawingSvg/drawRect.js +4 -4
  12. package/dist/cjs/drawingSvg/drawRect.js.map +1 -1
  13. package/dist/cjs/drawingSvg/drawTextBox.js +4 -4
  14. package/dist/cjs/drawingSvg/drawTextBox.js.map +1 -1
  15. package/dist/cjs/drawingSvg/index.d.ts +3 -1
  16. package/dist/cjs/drawingSvg/index.js +5 -1
  17. package/dist/cjs/drawingSvg/index.js.map +1 -1
  18. package/dist/cjs/drawingSvg/setAttributesIfNecessary.d.ts +2 -0
  19. package/dist/cjs/drawingSvg/{_setAttributesIfNecessary.js → setAttributesIfNecessary.js} +5 -5
  20. package/dist/cjs/drawingSvg/setAttributesIfNecessary.js.map +1 -0
  21. package/dist/cjs/drawingSvg/setNewAttributesIfValid.d.ts +2 -0
  22. package/dist/cjs/drawingSvg/{_setNewAttributesIfValid.js → setNewAttributesIfValid.js} +5 -5
  23. package/dist/cjs/drawingSvg/setNewAttributesIfValid.js.map +1 -0
  24. package/dist/cjs/index.d.ts +2 -2
  25. package/dist/cjs/index.js +3 -2
  26. package/dist/cjs/index.js.map +1 -1
  27. package/dist/cjs/store/ToolGroupManager/ToolGroup.js +1 -1
  28. package/dist/cjs/store/ToolGroupManager/ToolGroup.js.map +1 -1
  29. package/dist/cjs/tools/base/AnnotationTool.js +16 -14
  30. package/dist/cjs/tools/base/AnnotationTool.js.map +1 -1
  31. package/dist/cjs/tools/base/index.d.ts +2 -1
  32. package/dist/cjs/tools/base/index.js +3 -1
  33. package/dist/cjs/tools/base/index.js.map +1 -1
  34. package/dist/cjs/tools/index.d.ts +2 -2
  35. package/dist/cjs/tools/index.js +2 -1
  36. package/dist/cjs/tools/index.js.map +1 -1
  37. package/dist/cjs/tools/segmentation/BrushTool.js +24 -17
  38. package/dist/cjs/tools/segmentation/BrushTool.js.map +1 -1
  39. package/dist/cjs/tools/segmentation/strategies/eraseSphere.d.ts +2 -0
  40. package/dist/cjs/tools/segmentation/strategies/eraseSphere.js.map +1 -1
  41. package/dist/cjs/tools/segmentation/strategies/fillCircle.js +5 -7
  42. package/dist/cjs/tools/segmentation/strategies/fillCircle.js.map +1 -1
  43. package/dist/cjs/tools/segmentation/strategies/fillSphere.d.ts +3 -0
  44. package/dist/cjs/tools/segmentation/strategies/fillSphere.js +38 -10
  45. package/dist/cjs/tools/segmentation/strategies/fillSphere.js.map +1 -1
  46. package/dist/cjs/tools/segmentation/strategies/utils/isWithinThreshold.d.ts +3 -0
  47. package/dist/cjs/tools/segmentation/strategies/utils/isWithinThreshold.js +10 -0
  48. package/dist/cjs/tools/segmentation/strategies/utils/isWithinThreshold.js.map +1 -0
  49. package/dist/esm/drawingSvg/drawCircle.js +9 -5
  50. package/dist/esm/drawingSvg/drawCircle.js.map +1 -1
  51. package/dist/esm/drawingSvg/drawEllipse.js +4 -4
  52. package/dist/esm/drawingSvg/drawEllipse.js.map +1 -1
  53. package/dist/esm/drawingSvg/drawHandles.js +4 -4
  54. package/dist/esm/drawingSvg/drawHandles.js.map +1 -1
  55. package/dist/esm/drawingSvg/drawLine.js +4 -4
  56. package/dist/esm/drawingSvg/drawLine.js.map +1 -1
  57. package/dist/esm/drawingSvg/drawPolyline.js +4 -4
  58. package/dist/esm/drawingSvg/drawPolyline.js.map +1 -1
  59. package/dist/esm/drawingSvg/drawRect.js +4 -4
  60. package/dist/esm/drawingSvg/drawRect.js.map +1 -1
  61. package/dist/esm/drawingSvg/drawTextBox.js +4 -4
  62. package/dist/esm/drawingSvg/drawTextBox.js.map +1 -1
  63. package/dist/esm/drawingSvg/index.d.ts +3 -1
  64. package/dist/esm/drawingSvg/index.js +3 -1
  65. package/dist/esm/drawingSvg/index.js.map +1 -1
  66. package/dist/esm/drawingSvg/setAttributesIfNecessary.d.ts +2 -0
  67. package/dist/esm/drawingSvg/{_setAttributesIfNecessary.js → setAttributesIfNecessary.js} +3 -3
  68. package/dist/esm/drawingSvg/setAttributesIfNecessary.js.map +1 -0
  69. package/dist/esm/drawingSvg/setNewAttributesIfValid.d.ts +2 -0
  70. package/dist/esm/drawingSvg/{_setNewAttributesIfValid.js → setNewAttributesIfValid.js} +3 -3
  71. package/dist/esm/drawingSvg/setNewAttributesIfValid.js.map +1 -0
  72. package/dist/esm/index.d.ts +2 -2
  73. package/dist/esm/index.js +2 -2
  74. package/dist/esm/index.js.map +1 -1
  75. package/dist/esm/store/ToolGroupManager/ToolGroup.js +2 -2
  76. package/dist/esm/store/ToolGroupManager/ToolGroup.js.map +1 -1
  77. package/dist/esm/tools/base/AnnotationTool.js +16 -14
  78. package/dist/esm/tools/base/AnnotationTool.js.map +1 -1
  79. package/dist/esm/tools/base/index.d.ts +2 -1
  80. package/dist/esm/tools/base/index.js +2 -1
  81. package/dist/esm/tools/base/index.js.map +1 -1
  82. package/dist/esm/tools/index.d.ts +2 -2
  83. package/dist/esm/tools/index.js +2 -2
  84. package/dist/esm/tools/index.js.map +1 -1
  85. package/dist/esm/tools/segmentation/BrushTool.js +25 -18
  86. package/dist/esm/tools/segmentation/BrushTool.js.map +1 -1
  87. package/dist/esm/tools/segmentation/strategies/eraseSphere.d.ts +2 -0
  88. package/dist/esm/tools/segmentation/strategies/eraseSphere.js.map +1 -1
  89. package/dist/esm/tools/segmentation/strategies/fillCircle.js +1 -6
  90. package/dist/esm/tools/segmentation/strategies/fillCircle.js.map +1 -1
  91. package/dist/esm/tools/segmentation/strategies/fillSphere.d.ts +3 -0
  92. package/dist/esm/tools/segmentation/strategies/fillSphere.js +33 -9
  93. package/dist/esm/tools/segmentation/strategies/fillSphere.js.map +1 -1
  94. package/dist/esm/tools/segmentation/strategies/utils/isWithinThreshold.d.ts +3 -0
  95. package/dist/esm/tools/segmentation/strategies/utils/isWithinThreshold.js +8 -0
  96. package/dist/esm/tools/segmentation/strategies/utils/isWithinThreshold.js.map +1 -0
  97. package/dist/umd/index.js +1 -1
  98. package/dist/umd/index.js.map +1 -1
  99. package/package.json +3 -3
  100. package/src/drawingSvg/drawCircle.ts +17 -5
  101. package/src/drawingSvg/drawEllipse.ts +4 -4
  102. package/src/drawingSvg/drawHandles.ts +4 -4
  103. package/src/drawingSvg/drawLine.ts +4 -4
  104. package/src/drawingSvg/drawPolyline.ts +4 -4
  105. package/src/drawingSvg/drawRect.ts +4 -4
  106. package/src/drawingSvg/drawTextBox.ts +4 -4
  107. package/src/drawingSvg/index.ts +4 -0
  108. package/src/drawingSvg/{_setAttributesIfNecessary.ts → setAttributesIfNecessary.ts} +2 -2
  109. package/src/drawingSvg/{_setNewAttributesIfValid.ts → setNewAttributesIfValid.ts} +2 -2
  110. package/src/index.ts +2 -0
  111. package/src/store/ToolGroupManager/ToolGroup.ts +4 -1
  112. package/src/tools/base/AnnotationTool.ts +19 -17
  113. package/src/tools/base/index.ts +2 -1
  114. package/src/tools/index.ts +2 -1
  115. package/src/tools/segmentation/BrushTool.ts +42 -19
  116. package/src/tools/segmentation/strategies/eraseSphere.ts +2 -0
  117. package/src/tools/segmentation/strategies/fillCircle.ts +1 -13
  118. package/src/tools/segmentation/strategies/fillSphere.ts +56 -8
  119. package/src/tools/segmentation/strategies/utils/isWithinThreshold.ts +16 -0
  120. package/dist/cjs/drawingSvg/_setAttributesIfNecessary.d.ts +0 -2
  121. package/dist/cjs/drawingSvg/_setAttributesIfNecessary.js.map +0 -1
  122. package/dist/cjs/drawingSvg/_setNewAttributesIfValid.d.ts +0 -2
  123. package/dist/cjs/drawingSvg/_setNewAttributesIfValid.js.map +0 -1
  124. package/dist/esm/drawingSvg/_setAttributesIfNecessary.d.ts +0 -2
  125. package/dist/esm/drawingSvg/_setAttributesIfNecessary.js.map +0 -1
  126. package/dist/esm/drawingSvg/_setNewAttributesIfValid.d.ts +0 -2
  127. package/dist/esm/drawingSvg/_setNewAttributesIfValid.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cornerstonejs/tools",
3
- "version": "1.13.1",
3
+ "version": "1.13.3",
4
4
  "description": "Cornerstone3D Tools",
5
5
  "main": "dist/umd/index.js",
6
6
  "types": "dist/esm/index.d.ts",
@@ -29,7 +29,7 @@
29
29
  "webpack:watch": "webpack --mode development --progress --watch --config ./.webpack/webpack.dev.js"
30
30
  },
31
31
  "dependencies": {
32
- "@cornerstonejs/core": "^1.13.1",
32
+ "@cornerstonejs/core": "^1.13.3",
33
33
  "lodash.clonedeep": "4.5.0",
34
34
  "lodash.get": "^4.4.2"
35
35
  },
@@ -52,5 +52,5 @@
52
52
  "type": "individual",
53
53
  "url": "https://ohif.org/donate"
54
54
  },
55
- "gitHead": "3a64e9b77ad6549529d665c8fda89dc2235accf1"
55
+ "gitHead": "c6b8f5db43f3ae2e397240bf7d0da0be7a4fd434"
56
56
  }
@@ -3,8 +3,8 @@ import { SVGDrawingHelper } from '../types';
3
3
 
4
4
  import _getHash from './_getHash';
5
5
 
6
- import _setAttributesIfNecessary from './_setAttributesIfNecessary';
7
- import _setNewAttributesIfValid from './_setNewAttributesIfValid';
6
+ import setAttributesIfNecessary from './setAttributesIfNecessary';
7
+ import setNewAttributesIfValid from './setNewAttributesIfValid';
8
8
 
9
9
  function drawCircle(
10
10
  svgDrawingHelper: SVGDrawingHelper,
@@ -15,13 +15,23 @@ function drawCircle(
15
15
  options = {},
16
16
  dataId = ''
17
17
  ): void {
18
- const { color, fill, width, lineWidth, lineDash } = Object.assign(
18
+ const {
19
+ color,
20
+ fill,
21
+ width,
22
+ lineWidth,
23
+ lineDash,
24
+ fillOpacity,
25
+ strokeOpacity,
26
+ } = Object.assign(
19
27
  {
20
28
  color: 'dodgerblue',
21
29
  fill: 'transparent',
22
30
  width: '2',
23
31
  lineDash: undefined,
24
32
  lineWidth: undefined,
33
+ strokeOpacity: 1,
34
+ fillOpacity: 1,
25
35
  },
26
36
  options
27
37
  );
@@ -42,10 +52,12 @@ function drawCircle(
42
52
  fill,
43
53
  'stroke-width': strokeWidth,
44
54
  'stroke-dasharray': lineDash,
55
+ 'fill-opacity': fillOpacity, // setting fill opacity
56
+ 'stroke-opacity': strokeOpacity, // setting stroke opacity
45
57
  };
46
58
 
47
59
  if (existingCircleElement) {
48
- _setAttributesIfNecessary(attributes, existingCircleElement);
60
+ setAttributesIfNecessary(attributes, existingCircleElement);
49
61
 
50
62
  svgDrawingHelper.setNodeTouched(svgNodeHash);
51
63
  } else {
@@ -55,7 +67,7 @@ function drawCircle(
55
67
  newCircleElement.setAttribute('data-id', dataId);
56
68
  }
57
69
 
58
- _setNewAttributesIfValid(attributes, newCircleElement);
70
+ setNewAttributesIfValid(attributes, newCircleElement);
59
71
 
60
72
  svgDrawingHelper.appendNode(newCircleElement, svgNodeHash);
61
73
  }
@@ -2,8 +2,8 @@ import type { Types } from '@cornerstonejs/core';
2
2
  import { SVGDrawingHelper } from '../types';
3
3
 
4
4
  import _getHash from './_getHash';
5
- import _setAttributesIfNecessary from './_setAttributesIfNecessary';
6
- import _setNewAttributesIfValid from './_setNewAttributesIfValid';
5
+ import setAttributesIfNecessary from './setAttributesIfNecessary';
6
+ import setNewAttributesIfValid from './setNewAttributesIfValid';
7
7
 
8
8
  function drawEllipse(
9
9
  svgDrawingHelper: SVGDrawingHelper,
@@ -52,7 +52,7 @@ function drawEllipse(
52
52
  };
53
53
 
54
54
  if (existingEllipse) {
55
- _setAttributesIfNecessary(attributes, existingEllipse);
55
+ setAttributesIfNecessary(attributes, existingEllipse);
56
56
 
57
57
  svgDrawingHelper.setNodeTouched(svgNodeHash);
58
58
  } else {
@@ -62,7 +62,7 @@ function drawEllipse(
62
62
  svgEllipseElement.setAttribute('data-id', dataId);
63
63
  }
64
64
 
65
- _setNewAttributesIfValid(attributes, svgEllipseElement);
65
+ setNewAttributesIfValid(attributes, svgEllipseElement);
66
66
 
67
67
  svgDrawingHelper.appendNode(svgEllipseElement, svgNodeHash);
68
68
  }
@@ -1,8 +1,8 @@
1
1
  import type { Types } from '@cornerstonejs/core';
2
2
 
3
3
  import _getHash from './_getHash';
4
- import _setNewAttributesIfValid from './_setNewAttributesIfValid';
5
- import _setAttributesIfNecessary from './_setAttributesIfNecessary';
4
+ import setNewAttributesIfValid from './setNewAttributesIfValid';
5
+ import setAttributesIfNecessary from './setAttributesIfNecessary';
6
6
  import { SVGDrawingHelper } from '../types';
7
7
 
8
8
  function drawHandles(
@@ -75,13 +75,13 @@ function drawHandles(
75
75
  const existingHandleElement = svgDrawingHelper.getSvgNode(svgNodeHash);
76
76
 
77
77
  if (existingHandleElement) {
78
- _setAttributesIfNecessary(attributes, existingHandleElement);
78
+ setAttributesIfNecessary(attributes, existingHandleElement);
79
79
 
80
80
  svgDrawingHelper.setNodeTouched(svgNodeHash);
81
81
  } else {
82
82
  const newHandleElement = document.createElementNS(svgns, type);
83
83
 
84
- _setNewAttributesIfValid(attributes, newHandleElement);
84
+ setNewAttributesIfValid(attributes, newHandleElement);
85
85
 
86
86
  svgDrawingHelper.appendNode(newHandleElement, svgNodeHash);
87
87
  }
@@ -1,8 +1,8 @@
1
1
  import type { Types } from '@cornerstonejs/core';
2
2
 
3
3
  import _getHash from './_getHash';
4
- import _setNewAttributesIfValid from './_setNewAttributesIfValid';
5
- import _setAttributesIfNecessary from './_setAttributesIfNecessary';
4
+ import setNewAttributesIfValid from './setNewAttributesIfValid';
5
+ import setAttributesIfNecessary from './setAttributesIfNecessary';
6
6
  import { SVGDrawingHelper } from '../types';
7
7
 
8
8
  export default function drawLine(
@@ -53,7 +53,7 @@ export default function drawLine(
53
53
 
54
54
  if (existingLine) {
55
55
  // This is run to avoid re-rendering annotations that actually haven't changed
56
- _setAttributesIfNecessary(attributes, existingLine);
56
+ setAttributesIfNecessary(attributes, existingLine);
57
57
 
58
58
  svgDrawingHelper.setNodeTouched(svgNodeHash);
59
59
  } else {
@@ -63,7 +63,7 @@ export default function drawLine(
63
63
  newLine.setAttribute('data-id', dataId);
64
64
  }
65
65
 
66
- _setNewAttributesIfValid(attributes, newLine);
66
+ setNewAttributesIfValid(attributes, newLine);
67
67
 
68
68
  svgDrawingHelper.appendNode(newLine, svgNodeHash);
69
69
  }
@@ -1,7 +1,7 @@
1
1
  import type { Types } from '@cornerstonejs/core';
2
2
  import _getHash from './_getHash';
3
- import _setNewAttributesIfValid from './_setNewAttributesIfValid';
4
- import _setAttributesIfNecessary from './_setAttributesIfNecessary';
3
+ import setNewAttributesIfValid from './setNewAttributesIfValid';
4
+ import setAttributesIfNecessary from './setAttributesIfNecessary';
5
5
  import { SVGDrawingHelper } from '../types';
6
6
 
7
7
  /**
@@ -67,13 +67,13 @@ export default function drawPolyline(
67
67
 
68
68
  if (existingPolyLine) {
69
69
  // This is run to avoid re-rendering annotations that actually haven't changed
70
- _setAttributesIfNecessary(attributes, existingPolyLine);
70
+ setAttributesIfNecessary(attributes, existingPolyLine);
71
71
 
72
72
  svgDrawingHelper.setNodeTouched(svgNodeHash);
73
73
  } else {
74
74
  const newPolyLine = document.createElementNS(svgns, 'polyline');
75
75
 
76
- _setNewAttributesIfValid(attributes, newPolyLine);
76
+ setNewAttributesIfValid(attributes, newPolyLine);
77
77
 
78
78
  svgDrawingHelper.appendNode(newPolyLine, svgNodeHash);
79
79
  }
@@ -1,8 +1,8 @@
1
1
  import type { Types } from '@cornerstonejs/core';
2
2
 
3
3
  import _getHash from './_getHash';
4
- import _setAttributesIfNecessary from './_setAttributesIfNecessary';
5
- import _setNewAttributesIfValid from './_setNewAttributesIfValid';
4
+ import setAttributesIfNecessary from './setAttributesIfNecessary';
5
+ import setNewAttributesIfValid from './setNewAttributesIfValid';
6
6
  import { SVGDrawingHelper } from '../types';
7
7
 
8
8
  // <rect x="120" y="100" width="100" height="100" />
@@ -53,7 +53,7 @@ export default function drawRect(
53
53
  };
54
54
 
55
55
  if (existingRect) {
56
- _setAttributesIfNecessary(attributes, existingRect);
56
+ setAttributesIfNecessary(attributes, existingRect);
57
57
 
58
58
  svgDrawingHelper.setNodeTouched(svgNodeHash);
59
59
  } else {
@@ -63,7 +63,7 @@ export default function drawRect(
63
63
  svgRectElement.setAttribute('data-id', dataId);
64
64
  }
65
65
 
66
- _setNewAttributesIfValid(attributes, svgRectElement);
66
+ setNewAttributesIfValid(attributes, svgRectElement);
67
67
 
68
68
  svgDrawingHelper.appendNode(svgRectElement, svgNodeHash);
69
69
  }
@@ -2,7 +2,7 @@ import type { Types } from '@cornerstonejs/core';
2
2
  import { SVGDrawingHelper } from '../types';
3
3
 
4
4
  import _getHash from './_getHash';
5
- import _setAttributesIfNecessary from './_setAttributesIfNecessary';
5
+ import setAttributesIfNecessary from './setAttributesIfNecessary';
6
6
 
7
7
  /**
8
8
  * Draws a textBox.
@@ -100,8 +100,8 @@ function _drawTextGroup(
100
100
  };
101
101
 
102
102
  // Todo: for some reason this does not work to not re-render the textBox
103
- _setAttributesIfNecessary(textAttributes, textElement);
104
- _setAttributesIfNecessary(textGroupAttributes, existingTextGroup);
103
+ setAttributesIfNecessary(textAttributes, textElement);
104
+ setAttributesIfNecessary(textGroupAttributes, existingTextGroup);
105
105
 
106
106
  textGroupBoundingBox = _drawTextBackground(existingTextGroup, background);
107
107
 
@@ -205,7 +205,7 @@ function _drawTextBackground(group: SVGGElement, color: string) {
205
205
  fill: color,
206
206
  };
207
207
 
208
- _setAttributesIfNecessary(attributes, element);
208
+ setAttributesIfNecessary(attributes, element);
209
209
 
210
210
  return bBox;
211
211
  }
@@ -8,6 +8,8 @@ import drawLinkedTextBox from './drawLinkedTextBox';
8
8
  import drawRect from './drawRect';
9
9
  import drawTextBox from './drawTextBox';
10
10
  import drawArrow from './drawArrow';
11
+ import setAttributesIfNecessary from './setAttributesIfNecessary';
12
+ import setNewAttributesIfValid from './setNewAttributesIfValid';
11
13
 
12
14
  export {
13
15
  draw,
@@ -20,4 +22,6 @@ export {
20
22
  drawRect,
21
23
  drawTextBox,
22
24
  drawArrow,
25
+ setAttributesIfNecessary,
26
+ setNewAttributesIfValid,
23
27
  };
@@ -1,4 +1,4 @@
1
- export function _setAttributesIfNecessary(attributes, svgNode) {
1
+ export function setAttributesIfNecessary(attributes, svgNode) {
2
2
  Object.keys(attributes).forEach((key) => {
3
3
  const currentValue = svgNode.getAttribute(key);
4
4
  const newValue = attributes[key];
@@ -10,4 +10,4 @@ export function _setAttributesIfNecessary(attributes, svgNode) {
10
10
  });
11
11
  }
12
12
 
13
- export default _setAttributesIfNecessary;
13
+ export default setAttributesIfNecessary;
@@ -1,4 +1,4 @@
1
- export function _setNewAttributesIfValid(attributes, svgNode) {
1
+ export function setNewAttributesIfValid(attributes, svgNode) {
2
2
  Object.keys(attributes).forEach((key) => {
3
3
  const newValue = attributes[key];
4
4
  if (newValue !== undefined && newValue !== '') {
@@ -7,4 +7,4 @@ export function _setNewAttributesIfValid(attributes, svgNode) {
7
7
  });
8
8
  }
9
9
 
10
- export default _setNewAttributesIfValid;
10
+ export default setNewAttributesIfValid;
package/src/index.ts CHANGED
@@ -23,6 +23,7 @@ import * as segmentation from './stateManagement/segmentation';
23
23
  import {
24
24
  BaseTool,
25
25
  AnnotationTool,
26
+ AnnotationDisplayTool,
26
27
  PanTool,
27
28
  TrackballRotateTool,
28
29
  DragProbeTool,
@@ -71,6 +72,7 @@ export {
71
72
  // Base Tools
72
73
  BaseTool,
73
74
  AnnotationTool,
75
+ AnnotationDisplayTool,
74
76
  // Manipulation Tools
75
77
  PanTool,
76
78
  TrackballRotateTool,
@@ -621,7 +621,10 @@ export default class ToolGroup implements IToolGroup {
621
621
  if (overwrite) {
622
622
  _configuration = configuration;
623
623
  } else {
624
- _configuration = csUtils.deepMerge(
624
+ // We should not deep copy here, it is the job of the application to
625
+ // deep copy the configuration before passing it to the toolGroup, otherwise
626
+ // some strange appending behaviour happens for the arrays
627
+ _configuration = Object.assign(
625
628
  this._toolInstances[toolName].configuration,
626
629
  configuration
627
630
  );
@@ -200,24 +200,26 @@ abstract class AnnotationTool extends AnnotationDisplayTool {
200
200
 
201
201
  const { data } = annotation;
202
202
  const { points, textBox } = data.handles;
203
- const { worldBoundingBox } = textBox;
204
203
 
205
- if (worldBoundingBox) {
206
- const canvasBoundingBox = {
207
- topLeft: viewport.worldToCanvas(worldBoundingBox.topLeft),
208
- topRight: viewport.worldToCanvas(worldBoundingBox.topRight),
209
- bottomLeft: viewport.worldToCanvas(worldBoundingBox.bottomLeft),
210
- bottomRight: viewport.worldToCanvas(worldBoundingBox.bottomRight),
211
- };
212
-
213
- if (
214
- canvasCoords[0] >= canvasBoundingBox.topLeft[0] &&
215
- canvasCoords[0] <= canvasBoundingBox.bottomRight[0] &&
216
- canvasCoords[1] >= canvasBoundingBox.topLeft[1] &&
217
- canvasCoords[1] <= canvasBoundingBox.bottomRight[1]
218
- ) {
219
- data.handles.activeHandleIndex = null;
220
- return textBox;
204
+ if (textBox) {
205
+ const { worldBoundingBox } = textBox;
206
+ if (worldBoundingBox) {
207
+ const canvasBoundingBox = {
208
+ topLeft: viewport.worldToCanvas(worldBoundingBox.topLeft),
209
+ topRight: viewport.worldToCanvas(worldBoundingBox.topRight),
210
+ bottomLeft: viewport.worldToCanvas(worldBoundingBox.bottomLeft),
211
+ bottomRight: viewport.worldToCanvas(worldBoundingBox.bottomRight),
212
+ };
213
+
214
+ if (
215
+ canvasCoords[0] >= canvasBoundingBox.topLeft[0] &&
216
+ canvasCoords[0] <= canvasBoundingBox.bottomRight[0] &&
217
+ canvasCoords[1] >= canvasBoundingBox.topLeft[1] &&
218
+ canvasCoords[1] <= canvasBoundingBox.bottomRight[1]
219
+ ) {
220
+ data.handles.activeHandleIndex = null;
221
+ return textBox;
222
+ }
221
223
  }
222
224
  }
223
225
 
@@ -1,4 +1,5 @@
1
1
  import BaseTool from './BaseTool';
2
2
  import AnnotationTool from './AnnotationTool';
3
+ import AnnotationDisplayTool from './AnnotationDisplayTool';
3
4
 
4
- export { BaseTool, AnnotationTool };
5
+ export { BaseTool, AnnotationTool, AnnotationDisplayTool };
@@ -1,4 +1,4 @@
1
- import { BaseTool, AnnotationTool } from './base';
1
+ import { BaseTool, AnnotationTool, AnnotationDisplayTool } from './base';
2
2
  import PanTool from './PanTool';
3
3
  import TrackballRotateTool from './TrackballRotateTool';
4
4
  import WindowLevelTool from './WindowLevelTool';
@@ -43,6 +43,7 @@ export {
43
43
  // ~~ BASE
44
44
  BaseTool,
45
45
  AnnotationTool,
46
+ AnnotationDisplayTool,
46
47
  // Manipulation Tools
47
48
  PanTool,
48
49
  TrackballRotateTool,
@@ -1,4 +1,5 @@
1
1
  import { cache, getEnabledElement, StackViewport } from '@cornerstonejs/core';
2
+ import { vec3 } from 'gl-matrix';
2
3
 
3
4
  import type { Types } from '@cornerstonejs/core';
4
5
  import type {
@@ -8,7 +9,10 @@ import type {
8
9
  SVGDrawingHelper,
9
10
  } from '../../types';
10
11
  import { BaseTool } from '../base';
11
- import { fillInsideSphere } from './strategies/fillSphere';
12
+ import {
13
+ fillInsideSphere,
14
+ thresholdInsideSphere,
15
+ } from './strategies/fillSphere';
12
16
  import { eraseInsideSphere } from './strategies/eraseSphere';
13
17
  import {
14
18
  thresholdInsideCircle,
@@ -59,10 +63,11 @@ class BrushTool extends BaseTool {
59
63
  configuration: {
60
64
  strategies: {
61
65
  FILL_INSIDE_CIRCLE: fillInsideCircle,
62
- THRESHOLD_INSIDE_CIRCLE: thresholdInsideCircle,
63
66
  ERASE_INSIDE_CIRCLE: eraseInsideCircle,
64
67
  FILL_INSIDE_SPHERE: fillInsideSphere,
65
68
  ERASE_INSIDE_SPHERE: eraseInsideSphere,
69
+ THRESHOLD_INSIDE_CIRCLE: thresholdInsideCircle,
70
+ THRESHOLD_INSIDE_SPHERE: thresholdInsideSphere,
66
71
  },
67
72
  strategySpecificConfiguration: {
68
73
  THRESHOLD_INSIDE_CIRCLE: {
@@ -277,24 +282,42 @@ class BrushTool extends BaseTool {
277
282
  const enabledElement = getEnabledElement(element);
278
283
  const { viewport } = enabledElement;
279
284
  const { canvasToWorld } = viewport;
285
+ const camera = viewport.getCamera();
280
286
  const { brushSize } = this.configuration;
281
- // Center of circle in canvas Coordinates
282
287
 
283
- const radius = brushSize;
288
+ const viewUp = vec3.fromValues(
289
+ camera.viewUp[0],
290
+ camera.viewUp[1],
291
+ camera.viewUp[2]
292
+ );
293
+ const viewPlaneNormal = vec3.fromValues(
294
+ camera.viewPlaneNormal[0],
295
+ camera.viewPlaneNormal[1],
296
+ camera.viewPlaneNormal[2]
297
+ );
298
+ const viewRight = vec3.create();
284
299
 
285
- const bottomCanvas: Types.Point2 = [
300
+ vec3.cross(viewRight, viewUp, viewPlaneNormal);
301
+
302
+ // in the world coordinate system, the brushSize is the radius of the circle
303
+ // in mm
304
+ const centerCursorInWorld: Types.Point3 = canvasToWorld([
286
305
  centerCanvas[0],
287
- centerCanvas[1] + radius,
288
- ];
289
- const topCanvas: Types.Point2 = [centerCanvas[0], centerCanvas[1] - radius];
290
- const leftCanvas: Types.Point2 = [
291
- centerCanvas[0] - radius,
292
- centerCanvas[1],
293
- ];
294
- const rightCanvas: Types.Point2 = [
295
- centerCanvas[0] + radius,
296
306
  centerCanvas[1],
297
- ];
307
+ ]);
308
+
309
+ const bottomCursorInWorld = vec3.create();
310
+ const topCursorInWorld = vec3.create();
311
+ const leftCursorInWorld = vec3.create();
312
+ const rightCursorInWorld = vec3.create();
313
+
314
+ // Calculate the bottom and top points of the circle in world coordinates
315
+ for (let i = 0; i <= 2; i++) {
316
+ bottomCursorInWorld[i] = centerCursorInWorld[i] - viewUp[i] * brushSize;
317
+ topCursorInWorld[i] = centerCursorInWorld[i] + viewUp[i] * brushSize;
318
+ leftCursorInWorld[i] = centerCursorInWorld[i] - viewRight[i] * brushSize;
319
+ rightCursorInWorld[i] = centerCursorInWorld[i] + viewRight[i] * brushSize;
320
+ }
298
321
 
299
322
  const { brushCursor } = this._hoverData;
300
323
  const { data } = brushCursor;
@@ -304,10 +327,10 @@ class BrushTool extends BaseTool {
304
327
  }
305
328
 
306
329
  data.handles.points = [
307
- canvasToWorld(bottomCanvas),
308
- canvasToWorld(topCanvas),
309
- canvasToWorld(leftCanvas),
310
- canvasToWorld(rightCanvas),
330
+ bottomCursorInWorld,
331
+ topCursorInWorld,
332
+ leftCursorInWorld,
333
+ rightCursorInWorld,
311
334
  ];
312
335
 
313
336
  data.invalidated = false;
@@ -4,6 +4,7 @@ import { fillInsideSphere } from './fillSphere';
4
4
 
5
5
  type OperationData = {
6
6
  points: [Types.Point3, Types.Point3, Types.Point3, Types.Point3];
7
+ imageVolume: Types.IImageVolume;
7
8
  volume: Types.IImageVolume;
8
9
  segmentIndex: number;
9
10
  segmentationId: string;
@@ -11,6 +12,7 @@ type OperationData = {
11
12
  viewPlaneNormal: Types.Point3;
12
13
  viewUp: Types.Point3;
13
14
  constraintFn: () => boolean;
15
+ strategySpecificConfiguration: any;
14
16
  };
15
17
 
16
18
  export function eraseInsideSphere(
@@ -9,6 +9,7 @@ import {
9
9
  import { getBoundingBoxAroundShape } from '../../../utilities/boundingBox';
10
10
  import { triggerSegmentationDataModified } from '../../../stateManagement/segmentation/triggerSegmentationEvents';
11
11
  import { pointInShapeCallback } from '../../../utilities';
12
+ import isWithinThreshold from './utils/isWithinThreshold';
12
13
 
13
14
  const { transformWorldToIndex } = csUtils;
14
15
 
@@ -117,19 +118,6 @@ function fillCircle(
117
118
  triggerSegmentationDataModified(segmentationId, arrayOfSlices);
118
119
  }
119
120
 
120
- function isWithinThreshold(
121
- index: number,
122
- imageVolume: Types.IImageVolume,
123
- strategySpecificConfiguration: any
124
- ) {
125
- const { THRESHOLD_INSIDE_CIRCLE } = strategySpecificConfiguration;
126
-
127
- const voxelValue = imageVolume.getScalarData()[index];
128
- const { threshold } = THRESHOLD_INSIDE_CIRCLE;
129
-
130
- return threshold[0] <= voxelValue && voxelValue <= threshold[1];
131
- }
132
-
133
121
  /**
134
122
  * Fill inside the circular region segment inside the segmentation defined by the operationData.
135
123
  * It fills the segmentation pixels inside the defined circle.
@@ -1,29 +1,36 @@
1
1
  import type { Types } from '@cornerstonejs/core';
2
+ import { utilities as csUtils } from '@cornerstonejs/core';
2
3
 
3
4
  import { triggerSegmentationDataModified } from '../../../stateManagement/segmentation/triggerSegmentationEvents';
4
5
  import { pointInSurroundingSphereCallback } from '../../../utilities';
6
+ import isWithinThreshold from './utils/isWithinThreshold';
5
7
 
6
8
  type OperationData = {
7
9
  points: [Types.Point3, Types.Point3, Types.Point3, Types.Point3];
8
10
  volume: Types.IImageVolume;
11
+ imageVolume: Types.IImageVolume;
9
12
  segmentIndex: number;
10
13
  segmentationId: string;
11
14
  segmentsLocked: number[];
12
15
  viewPlaneNormal: Types.Point3;
13
16
  viewUp: Types.Point3;
17
+ strategySpecificConfiguration: any;
14
18
  constraintFn: () => boolean;
15
19
  };
16
20
 
17
21
  function fillSphere(
18
22
  enabledElement: Types.IEnabledElement,
19
23
  operationData: OperationData,
20
- _inside = true
24
+ _inside = true,
25
+ threshold = false
21
26
  ): void {
22
27
  const { viewport } = enabledElement;
23
28
  const {
24
29
  volume: segmentation,
25
30
  segmentsLocked,
26
31
  segmentIndex,
32
+ imageVolume,
33
+ strategySpecificConfiguration,
27
34
  segmentationId,
28
35
  points,
29
36
  } = operationData;
@@ -32,13 +39,30 @@ function fillSphere(
32
39
  const scalarData = segmentation.getScalarData();
33
40
  const scalarIndex = [];
34
41
 
35
- const callback = ({ index, value }) => {
36
- if (segmentsLocked.includes(value)) {
37
- return;
38
- }
39
- scalarData[index] = segmentIndex;
40
- scalarIndex.push(index);
41
- };
42
+ let callback;
43
+
44
+ if (threshold) {
45
+ callback = ({ value, index, pointIJK }) => {
46
+ if (segmentsLocked.includes(value)) {
47
+ return;
48
+ }
49
+
50
+ if (
51
+ isWithinThreshold(index, imageVolume, strategySpecificConfiguration)
52
+ ) {
53
+ scalarData[index] = segmentIndex;
54
+ scalarIndex.push(index);
55
+ }
56
+ };
57
+ } else {
58
+ callback = ({ index, value }) => {
59
+ if (segmentsLocked.includes(value)) {
60
+ return;
61
+ }
62
+ scalarData[index] = segmentIndex;
63
+ scalarIndex.push(index);
64
+ };
65
+ }
42
66
 
43
67
  pointInSurroundingSphereCallback(
44
68
  imageData,
@@ -74,6 +98,30 @@ export function fillInsideSphere(
74
98
  fillSphere(enabledElement, operationData, true);
75
99
  }
76
100
 
101
+ /**
102
+ * Fill inside the circular region segment inside the segmentation defined by the operationData.
103
+ * It fills the segmentation pixels inside the defined circle.
104
+ * @param enabledElement - The element for which the segment is being filled.
105
+ * @param operationData - EraseOperationData
106
+ */
107
+ export function thresholdInsideSphere(
108
+ enabledElement: Types.IEnabledElement,
109
+ operationData: OperationData
110
+ ): void {
111
+ const { volume, imageVolume } = operationData;
112
+
113
+ if (
114
+ !csUtils.isEqual(volume.dimensions, imageVolume.dimensions) ||
115
+ !csUtils.isEqual(volume.direction, imageVolume.direction)
116
+ ) {
117
+ throw new Error(
118
+ 'Only source data the same dimensions/size/orientation as the segmentation currently supported.'
119
+ );
120
+ }
121
+
122
+ fillSphere(enabledElement, operationData, true, true);
123
+ }
124
+
77
125
  /**
78
126
  * Fill outside a sphere with the given segment index in the given operation data. The
79
127
  * operation data contains the sphere required points.
@@ -0,0 +1,16 @@
1
+ import { Types } from '@cornerstonejs/core';
2
+
3
+ function isWithinThreshold(
4
+ index: number,
5
+ imageVolume: Types.IImageVolume,
6
+ strategySpecificConfiguration: any
7
+ ) {
8
+ const { THRESHOLD_INSIDE_CIRCLE } = strategySpecificConfiguration;
9
+
10
+ const voxelValue = imageVolume.getScalarData()[index];
11
+ const { threshold } = THRESHOLD_INSIDE_CIRCLE;
12
+
13
+ return threshold[0] <= voxelValue && voxelValue <= threshold[1];
14
+ }
15
+
16
+ export default isWithinThreshold;
@@ -1,2 +0,0 @@
1
- export declare function _setAttributesIfNecessary(attributes: any, svgNode: any): void;
2
- export default _setAttributesIfNecessary;