@ohif/app 3.10.0-beta.2 → 3.10.0-beta.20

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 (59) hide show
  1. package/dist/{1185.bundle.52f04f41c08dc5853aed.js → 1185.bundle.f5bdc6fbf5cf6e77f1ca.js} +129 -29
  2. package/dist/{1266.bundle.4f06772fcf6b303d894d.js → 1266.bundle.723b1e14a8c03300ca49.js} +30 -0
  3. package/dist/1266.css +1 -1
  4. package/dist/1801.css +1 -1
  5. package/dist/{1927.bundle.49539e3ab5b0aad1399c.js → 1927.bundle.c55edd5a362e7d79e23d.js} +1 -1
  6. package/dist/{2701.bundle.8c1ff2e0faaa7d2f4716.js → 2701.bundle.caa28a0b2f7e0b79088a.js} +14 -22
  7. package/dist/{149.bundle.b8d177954628f4631fc0.js → 3022.bundle.51a7056ea0e39b06e095.js} +2095 -389
  8. package/dist/{3198.bundle.3b22ad50fb086338b85e.js → 3198.bundle.a27ad30339285ee88574.js} +2 -2
  9. package/dist/3198.css +1 -1
  10. package/dist/{3200.bundle.768571169c3d6e603324.js → 3200.bundle.eff6d0c695d962fe4b5b.js} +17 -9
  11. package/dist/3200.css +1 -1
  12. package/dist/{3677.bundle.7d9110e8c5682b56a456.js → 3677.bundle.d3c30c37d00fc58b4442.js} +876 -18
  13. package/dist/{3970.bundle.31942cc0c12a008e7ba0.js → 3970.bundle.216ca9d37288f34b8f0b.js} +15 -5
  14. package/dist/4182.css +1 -1
  15. package/dist/{4571.bundle.3b1691730b3c57bf4d35.js → 4571.bundle.142e8f6150bf81f1b7d2.js} +129 -107
  16. package/dist/5139.css +1 -1
  17. package/dist/{5247.bundle.17495c3d97cf29e44e73.js → 5247.bundle.affc956197b6220e3c94.js} +4 -4
  18. package/dist/{5252.bundle.5ec502c53a9cc877ed8d.js → 5252.bundle.9d1855f7fb56235709ec.js} +713 -280
  19. package/dist/{1520.bundle.83586195deb9d61702d9.js → 5630.bundle.d206792a2f04f7156442.js} +90 -70
  20. package/dist/{5687.bundle.2665d32af98b253b78fd.js → 5687.bundle.022f94286f70741366b3.js} +4 -4
  21. package/dist/{5823.bundle.cb588e5e33eea80cd49f.js → 573.bundle.d08dcb8e65e3b7729b58.js} +27 -865
  22. package/dist/{1436.bundle.773756cd51b69e887bac.js → 6498.bundle.02f5b640a94509a11180.js} +1057 -536
  23. package/dist/{717.bundle.ba680e992f721c5d8b4a.js → 717.bundle.0b47b3dba812d4554266.js} +2 -2
  24. package/dist/717.css +1 -1
  25. package/dist/{7197.bundle.c4ff7a71122131167cbb.js → 7197.bundle.580576f8db68a65a10ce.js} +4 -4
  26. package/dist/{5717.bundle.848e13f256818475f57f.js → 727.bundle.f93673c292647f58ee1e.js} +1833 -817
  27. package/dist/{7955.bundle.dd665937d280f9427909.js → 7955.bundle.70fe7524bf3c8b78cd15.js} +1 -1
  28. package/dist/{8228.bundle.55ac03d7165248f47d4e.js → 8228.bundle.22df751df68b512fc6fb.js} +2 -2
  29. package/dist/8228.css +2 -2
  30. package/dist/{8558.bundle.dfedfd13f3845ea7104a.js → 8558.bundle.487a5e67207aa1f91da9.js} +3 -0
  31. package/dist/{9551.bundle.01a1567f174986f74fcf.js → 9551.bundle.26cea86f50cb4800bdaa.js} +1 -1
  32. package/dist/{9611.bundle.767595c93877e5166c03.js → 9611.bundle.0feebcae79e65852d610.js} +14 -9
  33. package/dist/{5807.bundle.dac5ce36534a71c77723.js → 967.bundle.fee0d6c1e9e244ad5bb3.js} +1134 -1128
  34. package/dist/{8523.bundle.648334132159465cdc41.js → 9809.bundle.9d3afbcc67703574e298.js} +1265 -185
  35. package/dist/{9862.bundle.7146682e56aa66130ae6.js → 9862.bundle.6ea7e474a390b386e2b2.js} +1 -1
  36. package/dist/{app.bundle.b81b47f20105288797e2.js → app.bundle.64d91e75036855d4e31a.js} +9080 -8397
  37. package/dist/app.bundle.css +18 -18
  38. package/dist/{histogram-worker.bundle.f0e060cf2637a2ca94b7.js → histogram-worker.bundle.f978654858500a3080cc.js} +3 -3
  39. package/dist/index.html +1 -1
  40. package/dist/{polySeg.bundle.b79ae514989e86301c71.js → polySeg.bundle.70ed683f467a47e3c92d.js} +3 -3
  41. package/dist/serve.json +1 -10
  42. package/dist/{suv-peak-worker.bundle.76dd4fdf82aaa2c3ad41.js → suv-peak-worker.bundle.8c83e6e99d48223569b6.js} +4 -4
  43. package/dist/sw.js +1 -1
  44. package/package.json +19 -19
  45. /package/dist/{1374.bundle.e5b05fd7e1295bf06867.js → 1374.bundle.afdb21e02ca5a08f8060.js} +0 -0
  46. /package/dist/{213.bundle.68c723cdf7de1ebb18f2.js → 213.bundle.2e20b24ab08945ba56bb.js} +0 -0
  47. /package/dist/{2424.bundle.acefd29e9b3948544119.js → 2424.bundle.a72e288e00a909f3930b.js} +0 -0
  48. /package/dist/{2825.bundle.9b280fd4de22a0b2b729.js → 2825.bundle.9fcf88214bf70b49356f.js} +0 -0
  49. /package/dist/{3121.bundle.d3e7092e305cf6cecdb5.js → 3121.bundle.67ff7e799683191bb324.js} +0 -0
  50. /package/dist/{3334.bundle.0e6ba24024018199ab66.js → 3334.bundle.e36011d0fd5fcb7e8b84.js} +0 -0
  51. /package/dist/{4202.bundle.5c8120ed4841da0af211.js → 4202.bundle.1311396ecdb6c0b09eb0.js} +0 -0
  52. /package/dist/{4834.bundle.1deb034b995ef76461a3.js → 4834.bundle.71f72158944e5afd94e8.js} +0 -0
  53. /package/dist/{5139.bundle.61d9101ea220a8382f2b.js → 5139.bundle.36ec15905a109af39099.js} +0 -0
  54. /package/dist/{5261.bundle.74682659cce85f3ae592.js → 5261.bundle.54d7af66923a3bae707d.js} +0 -0
  55. /package/dist/{6939.bundle.9b79da82315a25f37d96.js → 6939.bundle.5e77a634e8784085c00e.js} +0 -0
  56. /package/dist/{7159.bundle.9f4856182f1eda29c59d.js → 7159.bundle.4ee84ebbce84383e30d4.js} +0 -0
  57. /package/dist/{8008.bundle.d24be79eebc455c4512a.js → 8008.bundle.6be72115a1d79d69e7ab.js} +0 -0
  58. /package/dist/{8259.bundle.a91eb7639bc72f522c16.js → 8259.bundle.127e657e46bcff886565.js} +0 -0
  59. /package/dist/{8295.bundle.4ecb27f9e58526f12bcb.js → 8295.bundle.14cddaccdcd3a7093398.js} +0 -0
@@ -1,4 +1,4 @@
1
- (self["webpackChunk"] = self["webpackChunk"] || []).push([[149],{
1
+ (self["webpackChunk"] = self["webpackChunk"] || []).push([[3022],{
2
2
 
3
3
  /***/ 97181:
4
4
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
@@ -1959,14 +1959,17 @@ function wheelListener(evt) {
1959
1959
 
1960
1960
  /***/ }),
1961
1961
 
1962
- /***/ 82107:
1962
+ /***/ 97:
1963
1963
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1964
1964
 
1965
1965
  "use strict";
1966
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1967
- /* harmony export */ Q: () => (/* binding */ checkAndDefineTextBoxProperty),
1968
- /* harmony export */ d: () => (/* binding */ checkAndDefineCachedStatsProperty)
1969
- /* harmony export */ });
1966
+
1967
+ // EXPORTS
1968
+ __webpack_require__.d(__webpack_exports__, {
1969
+ c: () => (/* binding */ resetAnnotationManager)
1970
+ });
1971
+
1972
+ ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/annotation/utilities/defineProperties.js
1970
1973
  const checkAndDefineTextBoxProperty = (annotation) => {
1971
1974
  if (!annotation.data) {
1972
1975
  annotation.data = {};
@@ -1990,6 +1993,37 @@ const checkAndDefineCachedStatsProperty = (annotation) => {
1990
1993
  };
1991
1994
 
1992
1995
 
1996
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/annotation/annotationLocking.js
1997
+ var annotationLocking = __webpack_require__(2076);
1998
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/annotation/annotationVisibility.js
1999
+ var annotationVisibility = __webpack_require__(29601);
2000
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.js
2001
+ var FrameOfReferenceSpecificAnnotationManager = __webpack_require__(67013);
2002
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/annotation/annotationState.js
2003
+ var annotationState = __webpack_require__(82056);
2004
+ ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/annotation/resetAnnotationManager.js
2005
+
2006
+
2007
+
2008
+
2009
+
2010
+ const defaultManager = FrameOfReferenceSpecificAnnotationManager/* defaultFrameOfReferenceSpecificAnnotationManager */.H;
2011
+ const preprocessingFn = (annotation) => {
2012
+ annotation = checkAndDefineTextBoxProperty(annotation);
2013
+ annotation = checkAndDefineCachedStatsProperty(annotation);
2014
+ const uid = annotation.annotationUID;
2015
+ const isLocked = (0,annotationLocking.checkAndSetAnnotationLocked)(uid);
2016
+ annotation.isLocked = isLocked;
2017
+ const isVisible = (0,annotationVisibility.checkAndSetAnnotationVisibility)(uid);
2018
+ annotation.isVisible = isVisible;
2019
+ return annotation;
2020
+ };
2021
+ defaultManager.setPreprocessingFn(preprocessingFn);
2022
+ (0,annotationState.setAnnotationManager)(defaultManager);
2023
+ function resetAnnotationManager() {
2024
+ (0,annotationState.setAnnotationManager)(defaultManager);
2025
+ }
2026
+
1993
2027
 
1994
2028
  /***/ }),
1995
2029
 
@@ -2007,6 +2041,8 @@ const checkAndDefineCachedStatsProperty = (annotation) => {
2007
2041
  /* harmony import */ var _annotation_annotationLocking__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2076);
2008
2042
  /* harmony import */ var _annotation_annotationSelection__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(17343);
2009
2043
  /* harmony import */ var _annotation_annotationState__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(82056);
2044
+ /* harmony import */ var _annotation_resetAnnotationManager__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(97);
2045
+
2010
2046
 
2011
2047
 
2012
2048
 
@@ -2096,7 +2132,7 @@ function triggerSegmentationRepresentationModified(viewportId, segmentationId, t
2096
2132
  type,
2097
2133
  viewportId,
2098
2134
  };
2099
- (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.triggerEvent)(_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.eventTarget, _enums__WEBPACK_IMPORTED_MODULE_1__.Events.SEGMENTATION_REPRESENTATION_ADDED, eventDetail);
2135
+ (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.triggerEvent)(_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.eventTarget, _enums__WEBPACK_IMPORTED_MODULE_1__.Events.SEGMENTATION_REPRESENTATION_MODIFIED, eventDetail);
2100
2136
  }
2101
2137
 
2102
2138
 
@@ -2125,18 +2161,35 @@ function triggerSegmentationRepresentationRemoved(viewportId, segmentationId, ty
2125
2161
 
2126
2162
  /***/ }),
2127
2163
 
2128
- /***/ 33283:
2164
+ /***/ 50409:
2165
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2166
+
2167
+ "use strict";
2168
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2169
+ /* harmony export */ B: () => (/* binding */ getColorLUT)
2170
+ /* harmony export */ });
2171
+ /* harmony import */ var _SegmentationStateManager__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(59475);
2172
+
2173
+ function getColorLUT(index) {
2174
+ const segmentationStateManager = _SegmentationStateManager__WEBPACK_IMPORTED_MODULE_0__/* .defaultSegmentationStateManager */ ._6;
2175
+ return segmentationStateManager.getColorLUT(index);
2176
+ }
2177
+
2178
+
2179
+ /***/ }),
2180
+
2181
+ /***/ 70906:
2129
2182
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2130
2183
 
2131
2184
  "use strict";
2132
2185
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2133
- /* harmony export */ T: () => (/* binding */ getSegmentation)
2186
+ /* harmony export */ u: () => (/* binding */ getNextColorLUTIndex)
2134
2187
  /* harmony export */ });
2135
2188
  /* harmony import */ var _SegmentationStateManager__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(59475);
2136
2189
 
2137
- function getSegmentation(segmentationId) {
2190
+ function getNextColorLUTIndex() {
2138
2191
  const segmentationStateManager = _SegmentationStateManager__WEBPACK_IMPORTED_MODULE_0__/* .defaultSegmentationStateManager */ ._6;
2139
- return segmentationStateManager.getSegmentation(segmentationId);
2192
+ return segmentationStateManager.getNextColorLUTIndex();
2140
2193
  }
2141
2194
 
2142
2195
 
@@ -2248,6 +2301,7 @@ async function convertStackToVolumeLabelmap(args) {
2248
2301
 
2249
2302
  "use strict";
2250
2303
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2304
+ /* harmony export */ DU: () => (/* binding */ getSurfaceRepresentationUID),
2251
2305
  /* harmony export */ Qe: () => (/* binding */ getLabelmapActorUID),
2252
2306
  /* harmony export */ Th: () => (/* binding */ getSurfaceActorEntry),
2253
2307
  /* harmony export */ jU: () => (/* binding */ getSurfaceActorUID),
@@ -2278,13 +2332,16 @@ function getLabelmapActorEntry(viewportId, segmentationId) {
2278
2332
  return getActorEntry(viewportId, segmentationId, (actor) => actor.representationUID?.startsWith(`${segmentationId}-${_enums__WEBPACK_IMPORTED_MODULE_1__.SegmentationRepresentations.Labelmap}`));
2279
2333
  }
2280
2334
  function getSurfaceActorEntry(viewportId, segmentationId, segmentIndex) {
2281
- return getActorEntry(viewportId, segmentationId, (actor) => actor.representationUID?.startsWith(`${segmentationId}-${_enums__WEBPACK_IMPORTED_MODULE_1__.SegmentationRepresentations.Surface}-${segmentIndex}`));
2335
+ return getActorEntry(viewportId, segmentationId, (actor) => actor.representationUID?.startsWith(getSurfaceRepresentationUID(segmentationId, segmentIndex)));
2282
2336
  }
2283
2337
  function getSurfaceActorUID(viewportId, segmentationId, segmentIndex) {
2284
2338
  const segIndex = segmentIndex ? segmentIndex.toString() : '';
2285
2339
  const actorEntry = getSurfaceActorEntry(viewportId, segmentationId, segIndex);
2286
2340
  return actorEntry?.uid;
2287
2341
  }
2342
+ function getSurfaceRepresentationUID(segmentationId, segmentIndex) {
2343
+ return `${segmentationId}-${_enums__WEBPACK_IMPORTED_MODULE_1__.SegmentationRepresentations.Surface}-${segmentIndex}`;
2344
+ }
2288
2345
 
2289
2346
 
2290
2347
  /***/ }),
@@ -3029,7 +3086,8 @@ async function computeLabelmapFromSurfaceSegmentation(segmentationId, options =
3029
3086
  let segmentationVolume;
3030
3087
  if (isVolume) {
3031
3088
  const volumeId = viewport.getVolumeId();
3032
- segmentationVolume = await esm.volumeLoader.createAndCacheDerivedLabelmapVolume(volumeId);
3089
+ segmentationVolume =
3090
+ esm.volumeLoader.createAndCacheDerivedLabelmapVolume(volumeId);
3033
3091
  }
3034
3092
  else {
3035
3093
  const imageIds = options.viewport.getImageIds();
@@ -3141,7 +3199,7 @@ function filterToolsWithAnnotationsForElement(element, tools) {
3141
3199
  if (typeof tool.filterInteractableAnnotationsForElement === 'function') {
3142
3200
  annotations = tool.filterInteractableAnnotationsForElement(element, annotations);
3143
3201
  }
3144
- if (annotations.length > 0) {
3202
+ if (annotations?.length > 0) {
3145
3203
  result.push({ tool, annotations });
3146
3204
  }
3147
3205
  }
@@ -3352,6 +3410,7 @@ function activateClosedContourEdit(evt, annotation, viewportIdsToRender) {
3352
3410
  editCanvasPoints: [canvasPos],
3353
3411
  startCrossingIndex: undefined,
3354
3412
  editIndex: 0,
3413
+ annotation,
3355
3414
  };
3356
3415
  this.commonData = {
3357
3416
  annotation,
@@ -3386,9 +3445,10 @@ function mouseDragClosedContourEditCallback(evt) {
3386
3445
  const worldPos = currentPoints.world;
3387
3446
  const canvasPos = currentPoints.canvas;
3388
3447
  const enabledElement = (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_1__.getEnabledElement)(element);
3389
- const { renderingEngine, viewport } = enabledElement;
3448
+ const { viewport } = enabledElement;
3390
3449
  const { viewportIdsToRender, xDir, yDir, spacing } = this.commonData;
3391
- const { editIndex, editCanvasPoints, startCrossingIndex } = this.editData;
3450
+ const { editIndex, editCanvasPoints, startCrossingIndex, annotation } = this.editData;
3451
+ this.createMemo(element, annotation);
3392
3452
  const lastCanvasPoint = editCanvasPoints[editCanvasPoints.length - 1];
3393
3453
  const lastWorldPoint = viewport.canvasToWorld(lastCanvasPoint);
3394
3454
  const worldPosDiff = gl_matrix__WEBPACK_IMPORTED_MODULE_0__/* .vec3.create */ .eR.create();
@@ -3443,6 +3503,7 @@ function finishEditAndStartNewEdit(evt) {
3443
3503
  startCrossingIndex: undefined,
3444
3504
  editIndex: 0,
3445
3505
  snapIndex: undefined,
3506
+ annotation,
3446
3507
  };
3447
3508
  (0,_utilities_triggerAnnotationRenderForViewportIds__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A)(viewportIdsToRender);
3448
3509
  }
@@ -3528,8 +3589,9 @@ function mouseUpClosedContourEditCallback(evt) {
3528
3589
  }
3529
3590
  function completeClosedContourEdit(element) {
3530
3591
  const enabledElement = (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_1__.getEnabledElement)(element);
3531
- const { viewport, renderingEngine } = enabledElement;
3592
+ const { viewport } = enabledElement;
3532
3593
  const { annotation, viewportIdsToRender } = this.commonData;
3594
+ this.doneEditMemo();
3533
3595
  const { fusedCanvasPoints, prevCanvasPoints } = this.editData;
3534
3596
  if (fusedCanvasPoints) {
3535
3597
  const updatedPoints = (0,_utilities_planarFreehandROITool_smoothPoints__WEBPACK_IMPORTED_MODULE_7__/* .shouldSmooth */ .Q)(this.configuration, annotation)
@@ -3631,6 +3693,7 @@ function activateDraw(evt, annotation, viewportIdsToRender) {
3631
3693
  canvasPoints: [canvasPos],
3632
3694
  polylineIndex: 0,
3633
3695
  contourHoleProcessingEnabled,
3696
+ newAnnotation: true,
3634
3697
  };
3635
3698
  this.commonData = {
3636
3699
  annotation,
@@ -3665,9 +3728,10 @@ function mouseDragDrawCallback(evt) {
3665
3728
  const worldPos = currentPoints.world;
3666
3729
  const canvasPos = currentPoints.canvas;
3667
3730
  const enabledElement = (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.getEnabledElement)(element);
3668
- const { renderingEngine, viewport } = enabledElement;
3731
+ const { viewport } = enabledElement;
3669
3732
  const { annotation, viewportIdsToRender, xDir, yDir, spacing, movingTextBox, } = this.commonData;
3670
- const { polylineIndex, canvasPoints } = this.drawData;
3733
+ const { polylineIndex, canvasPoints, newAnnotation } = this.drawData;
3734
+ this.createMemo(element, annotation, { newAnnotation });
3671
3735
  const lastCanvasPoint = canvasPoints[canvasPoints.length - 1];
3672
3736
  const lastWorldPoint = viewport.canvasToWorld(lastCanvasPoint);
3673
3737
  const worldPosDiff = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.create */ .eR.create();
@@ -3707,6 +3771,8 @@ function mouseUpDrawCallback(evt) {
3707
3771
  const lastPoint = canvasPoints[canvasPoints.length - 1];
3708
3772
  const eventDetail = evt.detail;
3709
3773
  const { element } = eventDetail;
3774
+ this.doneEditMemo();
3775
+ this.drawData.newAnnotation = false;
3710
3776
  if (allowOpenContours &&
3711
3777
  !pointsAreWithinCloseContourProximity(firstPoint, lastPoint, this.configuration.closeContourProximity)) {
3712
3778
  this.completeDrawOpenContour(element, { contourHoleProcessingEnabled });
@@ -4137,6 +4203,7 @@ function activateOpenContourEdit(evt, annotation, viewportIdsToRender) {
4137
4203
  const canvasPos = currentPoints.canvas;
4138
4204
  const enabledElement = (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_1__.getEnabledElement)(element);
4139
4205
  const { viewport } = enabledElement;
4206
+ this.doneEditMemo();
4140
4207
  const prevCanvasPoints = annotation.data.contour.polyline.map(viewport.worldToCanvas);
4141
4208
  const { spacing, xDir, yDir } = getSubPixelSpacingAndXYDirections(viewport, this.configuration.subPixelResolution);
4142
4209
  this.editData = {
@@ -4178,12 +4245,13 @@ function mouseDragOpenContourEditCallback(evt) {
4178
4245
  const worldPos = currentPoints.world;
4179
4246
  const canvasPos = currentPoints.canvas;
4180
4247
  const enabledElement = (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_1__.getEnabledElement)(element);
4181
- const { renderingEngine, viewport } = enabledElement;
4248
+ const { viewport } = enabledElement;
4182
4249
  const { viewportIdsToRender, xDir, yDir, spacing } = this.commonData;
4183
4250
  const { editIndex, editCanvasPoints, startCrossingIndex } = this.editData;
4184
4251
  const lastCanvasPoint = editCanvasPoints[editCanvasPoints.length - 1];
4185
4252
  const lastWorldPoint = viewport.canvasToWorld(lastCanvasPoint);
4186
4253
  const worldPosDiff = gl_matrix__WEBPACK_IMPORTED_MODULE_0__/* .vec3.create */ .eR.create();
4254
+ this.createMemo(element, this.commonData.annotation);
4187
4255
  gl_matrix__WEBPACK_IMPORTED_MODULE_0__/* .vec3.subtract */ .eR.subtract(worldPosDiff, worldPos, lastWorldPoint);
4188
4256
  const xDist = Math.abs(gl_matrix__WEBPACK_IMPORTED_MODULE_0__/* .vec3.dot */ .eR.dot(worldPosDiff, xDir));
4189
4257
  const yDist = Math.abs(gl_matrix__WEBPACK_IMPORTED_MODULE_0__/* .vec3.dot */ .eR.dot(worldPosDiff, yDir));
@@ -4232,6 +4300,7 @@ function openContourEditOverwriteEnd(evt) {
4232
4300
  this.isEditingOpen = false;
4233
4301
  this.editData = undefined;
4234
4302
  this.commonData = undefined;
4303
+ this.doneEditMemo();
4235
4304
  this.deactivateOpenContourEdit(element);
4236
4305
  this.activateOpenContourEndEdit(evt, annotation, viewportIdsToRender, null);
4237
4306
  }
@@ -4382,8 +4451,9 @@ function mouseUpOpenContourEditCallback(evt) {
4382
4451
  }
4383
4452
  function completeOpenContourEdit(element) {
4384
4453
  const enabledElement = (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_1__.getEnabledElement)(element);
4385
- const { viewport, renderingEngine } = enabledElement;
4454
+ const { viewport } = enabledElement;
4386
4455
  const { annotation, viewportIdsToRender } = this.commonData;
4456
+ this.doneEditMemo();
4387
4457
  const { fusedCanvasPoints, prevCanvasPoints } = this.editData;
4388
4458
  if (fusedCanvasPoints) {
4389
4459
  const updatedPoints = (0,_utilities_planarFreehandROITool_smoothPoints__WEBPACK_IMPORTED_MODULE_6__/* .shouldSmooth */ .Q)(this.configuration)
@@ -5446,6 +5516,11 @@ class LinearSpline extends _CardinalSpline__WEBPACK_IMPORTED_MODULE_0__/* .Cardi
5446
5516
  /* harmony import */ var _stateManagement_annotation_annotationVisibility__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(29601);
5447
5517
  /* harmony import */ var _stateManagement_annotation_annotationState__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(82056);
5448
5518
  /* harmony import */ var _stateManagement_annotation_helpers_state__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(44049);
5519
+ /* harmony import */ var _enums_ChangeTypes__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(75183);
5520
+ /* harmony import */ var _stateManagement_annotation_annotationSelection__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(17343);
5521
+ /* harmony import */ var _utilities_contourSegmentation__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(64843);
5522
+
5523
+
5449
5524
 
5450
5525
 
5451
5526
 
@@ -5453,6 +5528,9 @@ class LinearSpline extends _CardinalSpline__WEBPACK_IMPORTED_MODULE_0__/* .Cardi
5453
5528
 
5454
5529
 
5455
5530
 
5531
+
5532
+ const { DefaultHistoryMemo } = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities.HistoryMemo;
5533
+ const { PointsManager } = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities;
5456
5534
  class AnnotationTool extends _AnnotationDisplayTool__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A {
5457
5535
  static createAnnotation(...annotationBaseData) {
5458
5536
  let annotation = {
@@ -5625,6 +5703,85 @@ class AnnotationTool extends _AnnotationDisplayTool__WEBPACK_IMPORTED_MODULE_2__
5625
5703
  return true;
5626
5704
  }
5627
5705
  }
5706
+ static createAnnotationState(annotation, deleting) {
5707
+ const { data, annotationUID } = annotation;
5708
+ const cloneData = {
5709
+ ...data,
5710
+ cachedStats: {},
5711
+ };
5712
+ delete cloneData.contour;
5713
+ delete cloneData.spline;
5714
+ const state = {
5715
+ annotationUID,
5716
+ data: structuredClone(cloneData),
5717
+ deleting,
5718
+ };
5719
+ const contour = data.contour;
5720
+ if (contour) {
5721
+ state.data.contour = {
5722
+ ...contour,
5723
+ polyline: null,
5724
+ pointsManager: PointsManager.create3(contour.polyline.length, contour.polyline),
5725
+ };
5726
+ }
5727
+ return state;
5728
+ }
5729
+ static createAnnotationMemo(element, annotation, options) {
5730
+ if (!annotation) {
5731
+ return;
5732
+ }
5733
+ const { newAnnotation, deleting = newAnnotation ? false : undefined } = options || {};
5734
+ const { annotationUID } = annotation;
5735
+ const state = AnnotationTool.createAnnotationState(annotation, deleting);
5736
+ const annotationMemo = {
5737
+ restoreMemo: () => {
5738
+ const newState = AnnotationTool.createAnnotationState(annotation, deleting);
5739
+ if (state.deleting === true) {
5740
+ state.deleting = false;
5741
+ Object.assign(annotation.data, state.data);
5742
+ if (annotation.data.contour) {
5743
+ const annotationData = annotation.data;
5744
+ annotationData.contour.polyline = state.data.contour.pointsManager.points;
5745
+ delete state.data.contour.pointsManager;
5746
+ if (annotationData.segmentation) {
5747
+ (0,_utilities_contourSegmentation__WEBPACK_IMPORTED_MODULE_9__.addContourSegmentationAnnotation)(annotation);
5748
+ }
5749
+ }
5750
+ state.data = newState.data;
5751
+ (0,_stateManagement_annotation_annotationState__WEBPACK_IMPORTED_MODULE_5__.addAnnotation)(annotation, element);
5752
+ (0,_stateManagement_annotation_annotationSelection__WEBPACK_IMPORTED_MODULE_8__.setAnnotationSelected)(annotation.annotationUID, true);
5753
+ (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.getEnabledElement)(element)?.viewport.render();
5754
+ return;
5755
+ }
5756
+ if (state.deleting === false) {
5757
+ state.deleting = true;
5758
+ state.data = newState.data;
5759
+ (0,_stateManagement_annotation_annotationSelection__WEBPACK_IMPORTED_MODULE_8__.setAnnotationSelected)(annotation.annotationUID);
5760
+ (0,_stateManagement_annotation_annotationState__WEBPACK_IMPORTED_MODULE_5__.removeAnnotation)(annotation.annotationUID);
5761
+ (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.getEnabledElement)(element)?.viewport.render();
5762
+ return;
5763
+ }
5764
+ const currentAnnotation = (0,_stateManagement_annotation_annotationState__WEBPACK_IMPORTED_MODULE_5__.getAnnotation)(annotationUID);
5765
+ if (!currentAnnotation) {
5766
+ console.warn('No current annotation');
5767
+ return;
5768
+ }
5769
+ Object.assign(currentAnnotation.data, state.data);
5770
+ if (currentAnnotation.data.contour) {
5771
+ currentAnnotation.data
5772
+ .contour.polyline = state.data.contour.pointsManager.points;
5773
+ }
5774
+ state.data = newState.data;
5775
+ currentAnnotation.invalidated = true;
5776
+ (0,_stateManagement_annotation_helpers_state__WEBPACK_IMPORTED_MODULE_6__/* .triggerAnnotationModified */ .XF)(currentAnnotation, element, _enums_ChangeTypes__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A.History);
5777
+ },
5778
+ };
5779
+ DefaultHistoryMemo.push(annotationMemo);
5780
+ return annotationMemo;
5781
+ }
5782
+ createMemo(element, annotation, options) {
5783
+ this.memo ||= AnnotationTool.createAnnotationMemo(element, annotation, options);
5784
+ }
5628
5785
  }
5629
5786
  AnnotationTool.toolName = 'AnnotationTool';
5630
5787
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AnnotationTool);
@@ -5646,8 +5803,6 @@ __webpack_require__.d(__webpack_exports__, {
5646
5803
 
5647
5804
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js
5648
5805
  var esm = __webpack_require__(81985);
5649
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/getSegmentation.js
5650
- var getSegmentation = __webpack_require__(33283);
5651
5806
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/enums/index.js + 2 modules
5652
5807
  var enums = __webpack_require__(99737);
5653
5808
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/annotation/annotationState.js
@@ -5716,48 +5871,18 @@ class ContourBaseTool extends AnnotationTool/* default */.A {
5716
5871
  return renderStatus;
5717
5872
  }
5718
5873
  createAnnotation(evt) {
5719
- const eventDetail = evt.detail;
5720
- const { currentPoints, element } = eventDetail;
5721
- const { world: worldPos } = currentPoints;
5722
- const enabledElement = (0,esm.getEnabledElement)(element);
5723
- const { viewport } = enabledElement;
5724
- const camera = viewport.getCamera();
5725
- const { viewPlaneNormal, viewUp, position: cameraPosition } = camera;
5726
- const referencedImageId = this.getReferencedImageId(viewport, worldPos, viewPlaneNormal, viewUp);
5727
- const viewReference = viewport.getViewReference({ points: [worldPos] });
5728
- return {
5729
- highlighted: true,
5730
- invalidated: true,
5731
- metadata: {
5732
- toolName: this.getToolName(),
5733
- ...viewReference,
5734
- referencedImageId,
5735
- viewUp,
5736
- cameraPosition,
5737
- },
5738
- data: {
5739
- handles: {
5740
- points: [],
5741
- activeHandleIndex: null,
5742
- textBox: {
5743
- hasMoved: false,
5744
- worldPosition: [0, 0, 0],
5745
- worldBoundingBox: {
5746
- topLeft: [0, 0, 0],
5747
- topRight: [0, 0, 0],
5748
- bottomLeft: [0, 0, 0],
5749
- bottomRight: [0, 0, 0],
5750
- },
5751
- },
5752
- },
5753
- contour: {
5754
- polyline: [],
5755
- closed: false,
5756
- },
5874
+ const annotation = super.createAnnotation(evt);
5875
+ Object.assign(annotation.data, {
5876
+ contour: {
5877
+ polyline: [],
5878
+ closed: false,
5757
5879
  },
5880
+ });
5881
+ Object.assign(annotation, {
5758
5882
  interpolationUID: '',
5759
5883
  autoGenerated: false,
5760
- };
5884
+ });
5885
+ return annotation;
5761
5886
  }
5762
5887
  addAnnotation(annotation, element) {
5763
5888
  return (0,annotationState.addAnnotation)(annotation, element);
@@ -5823,24 +5948,18 @@ var contourSegmentation = __webpack_require__(64843);
5823
5948
  var triggerAnnotationRenderForToolGroupIds = __webpack_require__(94779);
5824
5949
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/store/ToolGroupManager/index.js + 7 modules
5825
5950
  var ToolGroupManager = __webpack_require__(7754);
5826
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/config/segmentationColor.js
5827
- var segmentationColor = __webpack_require__(93733);
5828
5951
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/getSegmentationRepresentation.js
5829
5952
  var getSegmentationRepresentation = __webpack_require__(93210);
5830
5953
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/getActiveSegmentation.js
5831
5954
  var getActiveSegmentation = __webpack_require__(67165);
5832
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/getSegmentationRepresentationVisibility.js
5833
- var getSegmentationRepresentationVisibility = __webpack_require__(33658);
5834
5955
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/getViewportIdsWithSegmentation.js
5835
5956
  var getViewportIdsWithSegmentation = __webpack_require__(58859);
5836
5957
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/getActiveSegmentIndex.js
5837
5958
  var getActiveSegmentIndex = __webpack_require__(60740);
5838
5959
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/segmentLocking.js
5839
5960
  var segmentLocking = __webpack_require__(26795);
5840
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/SegmentationStyle.js
5841
- var SegmentationStyle = __webpack_require__(92686);
5842
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/helpers/internalGetHiddenSegmentIndices.js
5843
- var internalGetHiddenSegmentIndices = __webpack_require__(47098);
5961
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/getSVGStyleForSegment.js
5962
+ var getSVGStyleForSegment = __webpack_require__(86644);
5844
5963
  ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/base/ContourSegmentationBaseTool.js
5845
5964
 
5846
5965
 
@@ -5856,10 +5975,6 @@ var internalGetHiddenSegmentIndices = __webpack_require__(47098);
5856
5975
 
5857
5976
 
5858
5977
 
5859
-
5860
-
5861
-
5862
-
5863
5978
  class ContourSegmentationBaseTool extends ContourBaseTool {
5864
5979
  constructor(toolProps, defaultToolProps) {
5865
5980
  super(toolProps, defaultToolProps);
@@ -5957,54 +6072,12 @@ class ContourSegmentationBaseTool extends ContourBaseTool {
5957
6072
  const { autoGenerated } = annotation;
5958
6073
  const segmentsLocked = (0,segmentLocking.getLockedSegmentIndices)(segmentationId);
5959
6074
  const annotationLocked = segmentsLocked.includes(segmentIndex);
5960
- const segmentColor = (0,segmentationColor.getSegmentIndexColor)(context.styleSpecifier.viewportId, segmentationId, segmentIndex);
5961
- const segmentationVisible = (0,getSegmentationRepresentationVisibility/* getSegmentationRepresentationVisibility */.I)(viewportId, {
5962
- segmentationId,
5963
- type: enums.SegmentationRepresentations.Contour,
5964
- });
5965
- const activeSegmentation = (0,getActiveSegmentation/* getActiveSegmentation */.T)(viewportId);
5966
- const isActive = activeSegmentation?.segmentationId === segmentationId;
5967
- const style = SegmentationStyle/* segmentationStyle */.Y.getStyle({
5968
- viewportId,
6075
+ const { color, fillColor, lineWidth, fillOpacity, lineDash, visibility } = (0,getSVGStyleForSegment/* getSVGStyleForSegment */.u)({
5969
6076
  segmentationId,
5970
- type: enums.SegmentationRepresentations.Contour,
5971
6077
  segmentIndex,
6078
+ viewportId,
6079
+ autoGenerated,
5972
6080
  });
5973
- const mergedConfig = style;
5974
- let lineWidth = 1;
5975
- let lineDash = undefined;
5976
- let lineOpacity = 1;
5977
- let fillOpacity = 0;
5978
- if (autoGenerated) {
5979
- lineWidth = mergedConfig.outlineWidthAutoGenerated ?? lineWidth;
5980
- lineDash = mergedConfig.outlineDashAutoGenerated ?? lineDash;
5981
- lineOpacity = mergedConfig.outlineOpacity ?? lineOpacity;
5982
- fillOpacity = mergedConfig.fillAlphaAutoGenerated ?? fillOpacity;
5983
- }
5984
- else if (isActive) {
5985
- lineWidth = mergedConfig.outlineWidth ?? lineWidth;
5986
- lineDash = mergedConfig.outlineDash ?? lineDash;
5987
- lineOpacity = mergedConfig.outlineOpacity ?? lineOpacity;
5988
- fillOpacity = mergedConfig.fillAlpha ?? fillOpacity;
5989
- }
5990
- else {
5991
- lineWidth = mergedConfig.outlineWidthInactive ?? lineWidth;
5992
- lineDash = mergedConfig.outlineDashInactive ?? lineDash;
5993
- lineOpacity = mergedConfig.outlineOpacityInactive ?? lineOpacity;
5994
- fillOpacity = mergedConfig.fillAlphaInactive ?? fillOpacity;
5995
- }
5996
- if ((0,getActiveSegmentIndex/* getActiveSegmentIndex */.Q)(segmentationId) === segmentIndex) {
5997
- lineWidth += mergedConfig.activeSegmentOutlineWidthDelta;
5998
- }
5999
- lineWidth = mergedConfig.renderOutline ? lineWidth : 0;
6000
- fillOpacity = mergedConfig.renderFill ? fillOpacity : 0;
6001
- const color = `rgba(${segmentColor[0]}, ${segmentColor[1]}, ${segmentColor[2]}, ${lineOpacity})`;
6002
- const fillColor = `rgb(${segmentColor[0]}, ${segmentColor[1]}, ${segmentColor[2]})`;
6003
- const hiddenSegments = (0,internalGetHiddenSegmentIndices/* internalGetHiddenSegmentIndices */.s)(viewportId, {
6004
- segmentationId,
6005
- type: enums.SegmentationRepresentations.Contour,
6006
- });
6007
- const isVisible = !hiddenSegments.has(segmentIndex);
6008
6081
  return {
6009
6082
  color,
6010
6083
  fillColor,
@@ -6014,7 +6087,7 @@ class ContourSegmentationBaseTool extends ContourBaseTool {
6014
6087
  textbox: {
6015
6088
  color,
6016
6089
  },
6017
- visibility: segmentationVisible && isVisible,
6090
+ visibility,
6018
6091
  locked: annotationLocked,
6019
6092
  };
6020
6093
  }
@@ -6022,6 +6095,129 @@ class ContourSegmentationBaseTool extends ContourBaseTool {
6022
6095
 
6023
6096
 
6024
6097
 
6098
+ /***/ }),
6099
+
6100
+ /***/ 10639:
6101
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
6102
+
6103
+ "use strict";
6104
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
6105
+ /* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
6106
+ /* harmony export */ });
6107
+ /* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(81985);
6108
+ /* harmony import */ var _base__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(85817);
6109
+ /* harmony import */ var _enums__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(99737);
6110
+ /* harmony import */ var _stateManagement_segmentation__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1300);
6111
+ /* harmony import */ var _stateManagement_segmentation_triggerSegmentationEvents__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(49906);
6112
+ /* harmony import */ var _utilities_segmentation_getSVGStyleForSegment__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(86644);
6113
+
6114
+
6115
+
6116
+
6117
+
6118
+
6119
+ const { transformWorldToIndex, transformIndexToWorld } = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities;
6120
+ class GrowCutBaseTool extends _base__WEBPACK_IMPORTED_MODULE_1__/* .BaseTool */ .oS {
6121
+ constructor(toolProps, defaultToolProps) {
6122
+ super(toolProps, defaultToolProps);
6123
+ }
6124
+ async preMouseDownCallback(evt) {
6125
+ const eventData = evt.detail;
6126
+ const { element, currentPoints } = eventData;
6127
+ const { world: worldPoint } = currentPoints;
6128
+ const enabledElement = (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.getEnabledElement)(element);
6129
+ const { viewport, renderingEngine } = enabledElement;
6130
+ const { viewUp } = viewport.getCamera();
6131
+ const { segmentationId, segmentIndex, labelmapVolumeId, referencedVolumeId, } = this.getLabelmapSegmentationData(viewport);
6132
+ if (!this._isOrthogonalView(viewport, referencedVolumeId)) {
6133
+ throw new Error('Oblique view is not supported yet');
6134
+ }
6135
+ this.growCutData = {
6136
+ metadata: {
6137
+ ...viewport.getViewReference({ points: [worldPoint] }),
6138
+ viewUp,
6139
+ },
6140
+ segmentation: {
6141
+ segmentationId,
6142
+ segmentIndex,
6143
+ labelmapVolumeId,
6144
+ referencedVolumeId,
6145
+ },
6146
+ viewportId: viewport.id,
6147
+ renderingEngineId: renderingEngine.id,
6148
+ };
6149
+ evt.preventDefault();
6150
+ return true;
6151
+ }
6152
+ async getGrowCutLabelmap() {
6153
+ throw new Error('Not implemented');
6154
+ }
6155
+ async runGrowCut() {
6156
+ const { segmentation: { segmentationId, segmentIndex, labelmapVolumeId }, } = this.growCutData;
6157
+ const labelmap = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.cache.getVolume(labelmapVolumeId);
6158
+ const growcutLabelmap = await this.getGrowCutLabelmap();
6159
+ this.applyGrowCutLabelmap(segmentationId, segmentIndex, labelmap, growcutLabelmap);
6160
+ }
6161
+ applyGrowCutLabelmap(segmentationId, segmentIndex, targetLabelmap, sourceLabelmap) {
6162
+ const srcLabelmapData = sourceLabelmap.voxelManager.getCompleteScalarDataArray();
6163
+ const targetLabelmapData = targetLabelmap.voxelManager.getCompleteScalarDataArray();
6164
+ const [srcColumns, srcRows, srcNumSlices] = sourceLabelmap.dimensions;
6165
+ const [tgtColumns, tgtRows] = targetLabelmap.dimensions;
6166
+ const srcPixelsPerSlice = srcColumns * srcRows;
6167
+ const tgtPixelsPerSlice = tgtColumns * tgtRows;
6168
+ for (let srcSlice = 0; srcSlice < srcNumSlices; srcSlice++) {
6169
+ for (let srcRow = 0; srcRow < srcRows; srcRow++) {
6170
+ const srcRowIJK = [0, srcRow, srcSlice];
6171
+ const rowVoxelWorld = transformIndexToWorld(sourceLabelmap.imageData, srcRowIJK);
6172
+ const tgtRowIJK = transformWorldToIndex(targetLabelmap.imageData, rowVoxelWorld);
6173
+ const [tgtColumn, tgtRow, tgtSlice] = tgtRowIJK;
6174
+ const srcOffset = srcRow * srcColumns + srcSlice * srcPixelsPerSlice;
6175
+ const tgtOffset = tgtColumn + tgtRow * tgtColumns + tgtSlice * tgtPixelsPerSlice;
6176
+ for (let column = 0; column < srcColumns; column++) {
6177
+ targetLabelmapData[tgtOffset + column] =
6178
+ srcLabelmapData[srcOffset + column] === segmentIndex
6179
+ ? segmentIndex
6180
+ : 0;
6181
+ }
6182
+ }
6183
+ }
6184
+ targetLabelmap.voxelManager.setCompleteScalarDataArray(targetLabelmapData);
6185
+ (0,_stateManagement_segmentation_triggerSegmentationEvents__WEBPACK_IMPORTED_MODULE_4__.triggerSegmentationDataModified)(segmentationId);
6186
+ }
6187
+ getSegmentStyle({ segmentationId, viewportId, segmentIndex }) {
6188
+ return (0,_utilities_segmentation_getSVGStyleForSegment__WEBPACK_IMPORTED_MODULE_5__/* .getSVGStyleForSegment */ .u)({
6189
+ segmentationId,
6190
+ segmentIndex,
6191
+ viewportId,
6192
+ });
6193
+ }
6194
+ getLabelmapSegmentationData(viewport) {
6195
+ const { segmentationId } = _stateManagement_segmentation__WEBPACK_IMPORTED_MODULE_3__.activeSegmentation.getActiveSegmentation(viewport.id);
6196
+ const segmentIndex = _stateManagement_segmentation__WEBPACK_IMPORTED_MODULE_3__.segmentIndex.getActiveSegmentIndex(segmentationId);
6197
+ const { representationData } = _stateManagement_segmentation__WEBPACK_IMPORTED_MODULE_3__.state.getSegmentation(segmentationId);
6198
+ const labelmapData = representationData[_enums__WEBPACK_IMPORTED_MODULE_2__.SegmentationRepresentations.Labelmap];
6199
+ const { volumeId: labelmapVolumeId, referencedVolumeId } = labelmapData;
6200
+ return {
6201
+ segmentationId,
6202
+ segmentIndex,
6203
+ labelmapVolumeId,
6204
+ referencedVolumeId,
6205
+ };
6206
+ }
6207
+ _isOrthogonalView(viewport, referencedVolumeId) {
6208
+ const volume = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.cache.getVolume(referencedVolumeId);
6209
+ const volumeImageData = volume.imageData;
6210
+ const camera = viewport.getCamera();
6211
+ const { ijkVecColDir, ijkVecSliceDir } = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities.getVolumeDirectionVectors(volumeImageData, camera);
6212
+ return [ijkVecColDir, ijkVecSliceDir].every((vec) => _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities.isEqual(Math.abs(vec[0]), 1) ||
6213
+ _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities.isEqual(Math.abs(vec[1]), 1) ||
6214
+ _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities.isEqual(Math.abs(vec[2]), 1));
6215
+ }
6216
+ }
6217
+ GrowCutBaseTool.toolName = 'GrowCutBaseTool';
6218
+ /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (GrowCutBaseTool);
6219
+
6220
+
6025
6221
  /***/ }),
6026
6222
 
6027
6223
  /***/ 67772:
@@ -6284,7 +6480,7 @@ async function addLabelmapToElement(element, labelMapData, segmentationId) {
6284
6480
  representationUID: `${segmentationId}-${_enums__WEBPACK_IMPORTED_MODULE_4__.SegmentationRepresentations.Labelmap}`,
6285
6481
  },
6286
6482
  ];
6287
- await (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.addImageSlicesToViewports)(renderingEngine, stackInputs, [viewportId]);
6483
+ (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.addImageSlicesToViewports)(renderingEngine, stackInputs, [viewportId]);
6288
6484
  }
6289
6485
  (0,_stateManagement_segmentation_triggerSegmentationEvents__WEBPACK_IMPORTED_MODULE_3__.triggerSegmentationDataModified)(segmentationId);
6290
6486
  }
@@ -6433,7 +6629,6 @@ function validate(segmentationRepresentationData) {
6433
6629
  function addOrUpdateSurfaceToElement(element, surface, segmentationId) {
6434
6630
  const enabledElement = (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.getEnabledElement)(element);
6435
6631
  const { viewport } = enabledElement;
6436
- const representationUID = (0,_stateManagement_segmentation_helpers_getSegmentationActor__WEBPACK_IMPORTED_MODULE_5__/* .getSurfaceActorUID */ .jU)(viewport.id, segmentationId, surface.segmentIndex);
6437
6632
  const surfaceActorEntry = (0,_stateManagement_segmentation_helpers_getSegmentationActor__WEBPACK_IMPORTED_MODULE_5__/* .getSurfaceActorEntry */ .Th)(viewport.id, segmentationId, surface.segmentIndex);
6438
6633
  const surfaceActor = surfaceActorEntry?.actor;
6439
6634
  if (surfaceActor) {
@@ -6474,6 +6669,7 @@ function addOrUpdateSurfaceToElement(element, surface, segmentationId) {
6474
6669
  actor.setMapper(mapper);
6475
6670
  actor.getProperty().setColor(color[0] / 255, color[1] / 255, color[2] / 255);
6476
6671
  actor.getProperty().setLineWidth(2);
6672
+ const representationUID = (0,_stateManagement_segmentation_helpers_getSegmentationActor__WEBPACK_IMPORTED_MODULE_5__/* .getSurfaceRepresentationUID */ .DU)(segmentationId, surface.segmentIndex);
6477
6673
  viewport.addActor({
6478
6674
  uid: _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities.uuidv4(),
6479
6675
  actor: actor,
@@ -6542,60 +6738,310 @@ const distancePointToContour = (viewport, annotation, coords) => {
6542
6738
 
6543
6739
  /***/ }),
6544
6740
 
6545
- /***/ 55887:
6741
+ /***/ 23631:
6546
6742
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
6547
6743
 
6548
6744
  "use strict";
6549
6745
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
6550
- /* harmony export */ A: () => (/* binding */ BrushStrategy)
6746
+ /* harmony export */ A: () => (/* binding */ LabelmapBaseTool)
6551
6747
  /* harmony export */ });
6552
6748
  /* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(81985);
6553
- /* harmony import */ var _stateManagement_segmentation_triggerSegmentationEvents__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(49906);
6554
- /* harmony import */ var _compositions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(21553);
6555
- /* harmony import */ var _utils_getStrategyData__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(40905);
6556
- /* harmony import */ var _enums__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(99737);
6749
+ /* harmony import */ var _base__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(85817);
6750
+ /* harmony import */ var _enums_SegmentationRepresentations__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(18682);
6751
+ /* harmony import */ var _stateManagement_segmentation_getActiveSegmentation__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(67165);
6752
+ /* harmony import */ var _stateManagement_segmentation_segmentLocking__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(26795);
6753
+ /* harmony import */ var _stateManagement_segmentation_getSegmentation__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(33283);
6754
+ /* harmony import */ var _utilities_annotationHydration__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(64485);
6755
+ /* harmony import */ var _stateManagement_segmentation_getCurrentLabelmapImageIdForViewport__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(97577);
6756
+ /* harmony import */ var _stateManagement_segmentation_getStackSegmentationImageIdsForViewport__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(71309);
6757
+ /* harmony import */ var _stateManagement_segmentation_config_segmentationColor__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(93733);
6758
+ /* harmony import */ var _stateManagement_segmentation_getActiveSegmentIndex__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(60740);
6759
+ /* harmony import */ var _enums__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(99737);
6760
+ /* harmony import */ var _utilities_segmentation_createLabelmapMemo__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(2397);
6557
6761
 
6558
6762
 
6559
6763
 
6560
6764
 
6561
6765
 
6562
- const { VoxelManager } = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities;
6563
- class BrushStrategy {
6564
- static { this.COMPOSITIONS = _compositions__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; }
6565
- static { this.childFunctions = {
6566
- [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.OnInteractionStart]: addListMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.OnInteractionStart, _enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Initialize),
6567
- [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.OnInteractionEnd]: addListMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.OnInteractionEnd, _enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Initialize),
6568
- [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Fill]: addListMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Fill),
6569
- [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Initialize]: addListMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Initialize),
6570
- [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.CreateIsInThreshold]: addSingletonMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.CreateIsInThreshold),
6571
- [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.AcceptPreview]: addListMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.AcceptPreview, _enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Initialize),
6572
- [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.RejectPreview]: addListMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.RejectPreview, _enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Initialize),
6573
- [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.INTERNAL_setValue]: addSingletonMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.INTERNAL_setValue),
6574
- [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Preview]: addSingletonMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Preview, false),
6575
- [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.ComputeInnerCircleRadius]: addListMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.ComputeInnerCircleRadius),
6576
- compositions: null,
6577
- }; }
6578
- constructor(name, ...initializers) {
6579
- this._initialize = [];
6580
- this._fill = [];
6581
- this._onInteractionStart = [];
6582
- this.fill = (enabledElement, operationData) => {
6583
- const initializedData = this.initialize(enabledElement, operationData, _enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Fill);
6584
- if (!initializedData) {
6766
+
6767
+
6768
+
6769
+
6770
+
6771
+
6772
+
6773
+
6774
+ class LabelmapBaseTool extends _base__WEBPACK_IMPORTED_MODULE_1__/* .BaseTool */ .oS {
6775
+ constructor(toolProps, defaultToolProps) {
6776
+ super(toolProps, defaultToolProps);
6777
+ this._previewData = {
6778
+ preview: null,
6779
+ element: null,
6780
+ timerStart: 0,
6781
+ timer: null,
6782
+ startPoint: [NaN, NaN],
6783
+ isDrag: false,
6784
+ };
6785
+ }
6786
+ createMemo(segmentId, segmentationVoxelManager, preview) {
6787
+ this.memo ||= _utilities_segmentation_createLabelmapMemo__WEBPACK_IMPORTED_MODULE_12__.createLabelmapMemo(segmentId, segmentationVoxelManager, preview);
6788
+ return this.memo;
6789
+ }
6790
+ createEditData(element) {
6791
+ const enabledElement = (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.getEnabledElement)(element);
6792
+ const { viewport } = enabledElement;
6793
+ const activeSegmentation = (0,_stateManagement_segmentation_getActiveSegmentation__WEBPACK_IMPORTED_MODULE_3__/* .getActiveSegmentation */ .T)(viewport.id);
6794
+ if (!activeSegmentation) {
6795
+ const event = new CustomEvent(_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.Enums.Events.ERROR_EVENT, {
6796
+ detail: {
6797
+ type: 'Segmentation',
6798
+ message: 'No active segmentation detected, create a segmentation representation before using the brush tool',
6799
+ },
6800
+ cancelable: true,
6801
+ });
6802
+ _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.eventTarget.dispatchEvent(event);
6803
+ return null;
6804
+ }
6805
+ const { segmentationId } = activeSegmentation;
6806
+ const segmentsLocked = (0,_stateManagement_segmentation_segmentLocking__WEBPACK_IMPORTED_MODULE_4__.getLockedSegmentIndices)(segmentationId);
6807
+ const { representationData } = (0,_stateManagement_segmentation_getSegmentation__WEBPACK_IMPORTED_MODULE_5__/* .getSegmentation */ .T)(segmentationId);
6808
+ if (viewport instanceof _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.BaseVolumeViewport) {
6809
+ const { volumeId } = representationData[_enums_SegmentationRepresentations__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A.Labelmap];
6810
+ const actors = viewport.getActors();
6811
+ const isStackViewport = viewport instanceof _utilities_annotationHydration__WEBPACK_IMPORTED_MODULE_6__/* .getClosestImageIdForStackViewport */ .x;
6812
+ if (isStackViewport) {
6813
+ const event = new CustomEvent(_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.Enums.Events.ERROR_EVENT, {
6814
+ detail: {
6815
+ type: 'Segmentation',
6816
+ message: 'Cannot perform brush operation on the selected viewport',
6817
+ },
6818
+ cancelable: true,
6819
+ });
6820
+ _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.eventTarget.dispatchEvent(event);
6821
+ return null;
6822
+ }
6823
+ const volumes = actors.map((actorEntry) => _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.cache.getVolume(actorEntry.referencedId));
6824
+ const segmentationVolume = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.cache.getVolume(volumeId);
6825
+ const referencedVolumeIdToThreshold = volumes.find((volume) => _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities.isEqual(volume.dimensions, segmentationVolume.dimensions))?.volumeId || volumes[0]?.volumeId;
6826
+ return {
6827
+ volumeId,
6828
+ referencedVolumeId: this.configuration.thresholdVolumeId ?? referencedVolumeIdToThreshold,
6829
+ segmentsLocked,
6830
+ };
6831
+ }
6832
+ else {
6833
+ const segmentationImageId = (0,_stateManagement_segmentation_getCurrentLabelmapImageIdForViewport__WEBPACK_IMPORTED_MODULE_7__/* .getCurrentLabelmapImageIdForViewport */ .v)(viewport.id, segmentationId);
6834
+ if (!segmentationImageId) {
6585
6835
  return;
6586
6836
  }
6587
- const { strategySpecificConfiguration = {}, centerIJK } = initializedData;
6588
- if (_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities.isEqual(centerIJK, strategySpecificConfiguration.centerIJK)) {
6589
- return operationData.preview;
6837
+ if (this.configuration.activeStrategy.includes('SPHERE')) {
6838
+ const referencedImageIds = viewport.getImageIds();
6839
+ const isValidVolumeForSphere = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities.isValidVolume(referencedImageIds);
6840
+ if (!isValidVolumeForSphere) {
6841
+ throw new Error('Volume is not reconstructable for sphere manipulation');
6842
+ }
6843
+ const volumeId = `${segmentationId}_${viewport.id}`;
6844
+ const volume = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.cache.getVolume(volumeId);
6845
+ if (volume) {
6846
+ return {
6847
+ imageId: segmentationImageId,
6848
+ segmentsLocked,
6849
+ override: {
6850
+ voxelManager: volume.voxelManager,
6851
+ imageData: volume.imageData,
6852
+ },
6853
+ };
6854
+ }
6855
+ else {
6856
+ const labelmapImageIds = (0,_stateManagement_segmentation_getStackSegmentationImageIdsForViewport__WEBPACK_IMPORTED_MODULE_8__/* .getStackSegmentationImageIdsForViewport */ .B)(viewport.id, segmentationId);
6857
+ if (!labelmapImageIds || labelmapImageIds.length === 1) {
6858
+ return {
6859
+ imageId: segmentationImageId,
6860
+ segmentsLocked,
6861
+ };
6862
+ }
6863
+ const volume = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.volumeLoader.createAndCacheVolumeFromImagesSync(volumeId, labelmapImageIds);
6864
+ return {
6865
+ imageId: segmentationImageId,
6866
+ segmentsLocked,
6867
+ override: {
6868
+ voxelManager: volume.voxelManager,
6869
+ imageData: volume.imageData,
6870
+ },
6871
+ };
6872
+ }
6590
6873
  }
6591
6874
  else {
6592
- strategySpecificConfiguration.centerIJK = centerIJK;
6875
+ return {
6876
+ imageId: segmentationImageId,
6877
+ segmentsLocked,
6878
+ };
6593
6879
  }
6594
- this._fill.forEach((func) => func(initializedData));
6595
- const { segmentationVoxelManager, previewVoxelManager, previewSegmentIndex, } = initializedData;
6596
- (0,_stateManagement_segmentation_triggerSegmentationEvents__WEBPACK_IMPORTED_MODULE_1__.triggerSegmentationDataModified)(initializedData.segmentationId, segmentationVoxelManager.getArrayOfModifiedSlices());
6597
- if (!previewSegmentIndex || !previewVoxelManager.modifiedSlices.size) {
6598
- segmentationVoxelManager.resetModifiedSlices();
6880
+ }
6881
+ }
6882
+ createHoverData(element, centerCanvas) {
6883
+ const enabledElement = (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.getEnabledElement)(element);
6884
+ const { viewport } = enabledElement;
6885
+ const camera = viewport.getCamera();
6886
+ const { viewPlaneNormal, viewUp } = camera;
6887
+ const viewportIdsToRender = [viewport.id];
6888
+ const { segmentIndex, segmentationId, segmentColor } = this.getActiveSegmentationData(viewport) || {};
6889
+ const brushCursor = {
6890
+ metadata: {
6891
+ viewPlaneNormal: [...viewPlaneNormal],
6892
+ viewUp: [...viewUp],
6893
+ FrameOfReferenceUID: viewport.getFrameOfReferenceUID(),
6894
+ referencedImageId: '',
6895
+ toolName: this.getToolName(),
6896
+ segmentColor,
6897
+ },
6898
+ data: {},
6899
+ };
6900
+ return {
6901
+ brushCursor,
6902
+ centerCanvas,
6903
+ segmentIndex,
6904
+ viewport,
6905
+ segmentationId,
6906
+ segmentColor,
6907
+ viewportIdsToRender,
6908
+ };
6909
+ }
6910
+ getActiveSegmentationData(viewport) {
6911
+ const viewportId = viewport.id;
6912
+ const activeRepresentation = (0,_stateManagement_segmentation_getActiveSegmentation__WEBPACK_IMPORTED_MODULE_3__/* .getActiveSegmentation */ .T)(viewportId);
6913
+ if (!activeRepresentation) {
6914
+ return;
6915
+ }
6916
+ const { segmentationId } = activeRepresentation;
6917
+ const segmentIndex = (0,_stateManagement_segmentation_getActiveSegmentIndex__WEBPACK_IMPORTED_MODULE_10__/* .getActiveSegmentIndex */ .Q)(segmentationId);
6918
+ if (!segmentIndex) {
6919
+ return;
6920
+ }
6921
+ const segmentColor = (0,_stateManagement_segmentation_config_segmentationColor__WEBPACK_IMPORTED_MODULE_9__.getSegmentIndexColor)(viewportId, segmentationId, segmentIndex);
6922
+ return {
6923
+ segmentIndex,
6924
+ segmentationId,
6925
+ segmentColor,
6926
+ };
6927
+ }
6928
+ getOperationData(element) {
6929
+ const editData = this._editData || this.createEditData(element);
6930
+ const { segmentIndex, segmentationId, brushCursor } = this._hoverData || this.createHoverData(element);
6931
+ const { data, metadata = {} } = brushCursor || {};
6932
+ const { viewPlaneNormal, viewUp } = metadata;
6933
+ const operationData = {
6934
+ ...editData,
6935
+ points: data?.handles?.points,
6936
+ segmentIndex,
6937
+ previewColors: this.configuration.preview?.enabled || this._previewData.preview
6938
+ ? this.configuration.preview.previewColors
6939
+ : null,
6940
+ viewPlaneNormal,
6941
+ toolGroupId: this.toolGroupId,
6942
+ segmentationId,
6943
+ viewUp,
6944
+ strategySpecificConfiguration: this.configuration.strategySpecificConfiguration,
6945
+ preview: this._previewData?.preview,
6946
+ createMemo: this.createMemo.bind(this),
6947
+ };
6948
+ return operationData;
6949
+ }
6950
+ addPreview(element = this._previewData.element, options) {
6951
+ const acceptReject = options?.acceptReject;
6952
+ if (acceptReject === true) {
6953
+ this.acceptPreview(element);
6954
+ }
6955
+ else if (acceptReject === false) {
6956
+ this.rejectPreview(element);
6957
+ }
6958
+ const enabledElement = (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.getEnabledElement)(element);
6959
+ this._previewData.preview = this.applyActiveStrategyCallback(enabledElement, this.getOperationData(element), _enums__WEBPACK_IMPORTED_MODULE_11__.StrategyCallbacks.AddPreview);
6960
+ this._previewData.isDrag = true;
6961
+ return this._previewData.preview;
6962
+ }
6963
+ rejectPreview(element = this._previewData.element) {
6964
+ if (!element || !this._previewData.preview) {
6965
+ return;
6966
+ }
6967
+ const enabledElement = (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.getEnabledElement)(element);
6968
+ this.applyActiveStrategyCallback(enabledElement, this.getOperationData(element), _enums__WEBPACK_IMPORTED_MODULE_11__.StrategyCallbacks.RejectPreview);
6969
+ this._previewData.preview = null;
6970
+ this._previewData.isDrag = false;
6971
+ }
6972
+ acceptPreview(element = this._previewData.element) {
6973
+ if (!element) {
6974
+ return;
6975
+ }
6976
+ this.doneEditMemo();
6977
+ const enabledElement = (0,_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.getEnabledElement)(element);
6978
+ this.applyActiveStrategyCallback(enabledElement, this.getOperationData(element), _enums__WEBPACK_IMPORTED_MODULE_11__.StrategyCallbacks.AcceptPreview);
6979
+ this._previewData.isDrag = false;
6980
+ this._previewData.preview = null;
6981
+ this.doneEditMemo();
6982
+ }
6983
+ }
6984
+
6985
+
6986
+ /***/ }),
6987
+
6988
+ /***/ 55887:
6989
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
6990
+
6991
+ "use strict";
6992
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
6993
+ /* harmony export */ A: () => (/* binding */ BrushStrategy)
6994
+ /* harmony export */ });
6995
+ /* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(81985);
6996
+ /* harmony import */ var _stateManagement_segmentation_triggerSegmentationEvents__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(49906);
6997
+ /* harmony import */ var _compositions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(96814);
6998
+ /* harmony import */ var _utils_getStrategyData__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(40905);
6999
+ /* harmony import */ var _enums__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(99737);
7000
+
7001
+
7002
+
7003
+
7004
+
7005
+ const { VoxelManager } = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities;
7006
+ class BrushStrategy {
7007
+ static { this.COMPOSITIONS = _compositions__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; }
7008
+ static { this.childFunctions = {
7009
+ [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.OnInteractionStart]: addListMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.OnInteractionStart, _enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Initialize),
7010
+ [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.OnInteractionEnd]: addListMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.OnInteractionEnd, _enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Initialize),
7011
+ [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Fill]: addListMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Fill),
7012
+ [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Initialize]: addListMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Initialize),
7013
+ [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.CreateIsInThreshold]: addSingletonMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.CreateIsInThreshold),
7014
+ [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.AcceptPreview]: addListMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.AcceptPreview, _enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Initialize),
7015
+ [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.RejectPreview]: addListMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.RejectPreview, _enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Initialize),
7016
+ [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.INTERNAL_setValue]: addSingletonMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.INTERNAL_setValue),
7017
+ [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Preview]: addSingletonMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Preview, false),
7018
+ [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.ComputeInnerCircleRadius]: addListMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.ComputeInnerCircleRadius),
7019
+ [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.AddPreview]: addListMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.AddPreview),
7020
+ [_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.GetStatistics]: addSingletonMethod(_enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.GetStatistics),
7021
+ compositions: null,
7022
+ }; }
7023
+ constructor(name, ...initializers) {
7024
+ this._initialize = [];
7025
+ this._fill = [];
7026
+ this._onInteractionStart = [];
7027
+ this.fill = (enabledElement, operationData) => {
7028
+ const initializedData = this.initialize(enabledElement, operationData, _enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.Fill);
7029
+ if (!initializedData) {
7030
+ return;
7031
+ }
7032
+ const { strategySpecificConfiguration = {}, centerIJK } = initializedData;
7033
+ if (_cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities.isEqual(centerIJK, strategySpecificConfiguration.centerIJK)) {
7034
+ return operationData.preview;
7035
+ }
7036
+ else {
7037
+ strategySpecificConfiguration.centerIJK = centerIJK;
7038
+ }
7039
+ this._fill.forEach((func) => func(initializedData));
7040
+ const { segmentationVoxelManager, previewVoxelManager, previewSegmentIndex, segmentIndex, } = initializedData;
7041
+ const isPreview = previewSegmentIndex && previewVoxelManager.modifiedSlices.size;
7042
+ (0,_stateManagement_segmentation_triggerSegmentationEvents__WEBPACK_IMPORTED_MODULE_1__.triggerSegmentationDataModified)(initializedData.segmentationId, segmentationVoxelManager.getArrayOfModifiedSlices(), isPreview ? previewSegmentIndex : segmentIndex);
7043
+ if (!previewSegmentIndex || !previewVoxelManager.modifiedSlices.size) {
7044
+ segmentationVoxelManager.resetModifiedSlices();
6599
7045
  return null;
6600
7046
  }
6601
7047
  return initializedData.preview || initializedData;
@@ -6612,6 +7058,13 @@ class BrushStrategy {
6612
7058
  }
6613
7059
  this._onInteractionStart.forEach((func) => func.call(this, initializedData));
6614
7060
  };
7061
+ this.addPreview = (enabledElement, operationData) => {
7062
+ const initializedData = this.initialize(enabledElement, operationData, _enums__WEBPACK_IMPORTED_MODULE_4__.StrategyCallbacks.AddPreview);
7063
+ if (!initializedData) {
7064
+ return;
7065
+ }
7066
+ return initializedData.preview || initializedData;
7067
+ };
6615
7068
  this.configurationName = name;
6616
7069
  this.compositions = initializers;
6617
7070
  initializers.forEach((initializer) => {
@@ -6644,9 +7097,7 @@ class BrushStrategy {
6644
7097
  const segmentationVoxelManagerToUse = operationData.override?.voxelManager || segmentationVoxelManager;
6645
7098
  const segmentationImageDataToUse = operationData.override?.imageData || segmentationImageData;
6646
7099
  const previewVoxelManager = operationData.preview?.previewVoxelManager ||
6647
- VoxelManager.createHistoryVoxelManager({
6648
- sourceVoxelManager: segmentationVoxelManagerToUse,
6649
- });
7100
+ VoxelManager.createRLEHistoryVoxelManager(segmentationVoxelManager);
6650
7101
  const previewEnabled = !!operationData.previewColors;
6651
7102
  const previewSegmentIndex = previewEnabled ? 255 : undefined;
6652
7103
  const initializedData = {
@@ -6690,9 +7141,9 @@ function addSingletonMethod(name, isInitialized = true) {
6690
7141
  }
6691
7142
  brushStrategy[name] = isInitialized
6692
7143
  ? func
6693
- : (enabledElement, operationData) => {
7144
+ : (enabledElement, operationData, ...args) => {
6694
7145
  operationData.enabledElement = enabledElement;
6695
- return func.call(brushStrategy, operationData);
7146
+ return func.call(brushStrategy, operationData, ...args);
6696
7147
  };
6697
7148
  };
6698
7149
  }
@@ -6700,7 +7151,7 @@ function addSingletonMethod(name, isInitialized = true) {
6700
7151
 
6701
7152
  /***/ }),
6702
7153
 
6703
- /***/ 21553:
7154
+ /***/ 96814:
6704
7155
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
6705
7156
 
6706
7157
  "use strict";
@@ -6726,20 +7177,33 @@ var StrategyCallbacks = __webpack_require__(84093);
6726
7177
  }
6727
7178
  },
6728
7179
  [StrategyCallbacks/* default */.A.OnInteractionStart]: (operationData) => {
6729
- const { segmentIndex, previewSegmentIndex, segmentationVoxelManager, centerIJK, strategySpecificConfiguration, imageVoxelManager, segmentationImageData, preview, } = operationData;
7180
+ const { segmentIndex, previewSegmentIndex, segmentationVoxelManager, centerIJK, strategySpecificConfiguration, viewPlaneNormal, segmentationImageData, preview, } = operationData;
6730
7181
  if (!strategySpecificConfiguration?.useCenterSegmentIndex) {
6731
7182
  return;
6732
7183
  }
6733
7184
  delete strategySpecificConfiguration.centerSegmentIndex;
6734
7185
  let hasSegmentIndex = false;
6735
7186
  let hasPreviewIndex = false;
7187
+ const nestedBounds = [
7188
+ ...segmentationVoxelManager.getBoundsIJK(),
7189
+ ];
7190
+ if (Math.abs(viewPlaneNormal[0]) > 0.8) {
7191
+ nestedBounds[0] = [centerIJK[0], centerIJK[0]];
7192
+ }
7193
+ else if (Math.abs(viewPlaneNormal[1]) > 0.8) {
7194
+ nestedBounds[1] = [centerIJK[1], centerIJK[1]];
7195
+ }
7196
+ else if (Math.abs(viewPlaneNormal[2]) > 0.8) {
7197
+ nestedBounds[2] = [centerIJK[2], centerIJK[2]];
7198
+ }
6736
7199
  const callback = ({ value }) => {
6737
7200
  hasSegmentIndex ||= value === segmentIndex;
6738
7201
  hasPreviewIndex ||= value === previewSegmentIndex;
6739
7202
  };
6740
- imageVoxelManager.forEach(callback, {
7203
+ segmentationVoxelManager.forEach(callback, {
6741
7204
  imageData: segmentationImageData,
6742
7205
  isInObject: operationData.isInObject,
7206
+ boundsIJK: nestedBounds,
6743
7207
  });
6744
7208
  if (!hasSegmentIndex && !hasPreviewIndex) {
6745
7209
  return;
@@ -6770,7 +7234,7 @@ var esm = __webpack_require__(3823);
6770
7234
 
6771
7235
  /* harmony default export */ const dynamicThreshold = ({
6772
7236
  [StrategyCallbacks/* default */.A.Initialize]: (operationData) => {
6773
- const { operationName, centerIJK, strategySpecificConfiguration, segmentationVoxelManager, imageVoxelManager, segmentIndex, } = operationData;
7237
+ const { operationName, centerIJK, strategySpecificConfiguration, segmentationVoxelManager, imageVoxelManager, segmentIndex, viewport, } = operationData;
6774
7238
  const { THRESHOLD } = strategySpecificConfiguration;
6775
7239
  if (!THRESHOLD?.isDynamic || !centerIJK || !segmentIndex) {
6776
7240
  return;
@@ -6782,6 +7246,7 @@ var esm = __webpack_require__(3823);
6782
7246
  const boundsIJK = segmentationVoxelManager.getBoundsIJK();
6783
7247
  const { threshold: oldThreshold, dynamicRadius = 0 } = THRESHOLD;
6784
7248
  const useDelta = oldThreshold ? 0 : dynamicRadius;
7249
+ const { viewPlaneNormal } = viewport.getCamera();
6785
7250
  const nestedBounds = boundsIJK.map((ijk, idx) => {
6786
7251
  const [min, max] = ijk;
6787
7252
  return [
@@ -6789,8 +7254,22 @@ var esm = __webpack_require__(3823);
6789
7254
  Math.min(max, centerIJK[idx] + useDelta),
6790
7255
  ];
6791
7256
  });
7257
+ if (Math.abs(viewPlaneNormal[0]) > 0.8) {
7258
+ nestedBounds[0] = [centerIJK[0], centerIJK[0]];
7259
+ }
7260
+ else if (Math.abs(viewPlaneNormal[1]) > 0.8) {
7261
+ nestedBounds[1] = [centerIJK[1], centerIJK[1]];
7262
+ }
7263
+ else if (Math.abs(viewPlaneNormal[2]) > 0.8) {
7264
+ nestedBounds[2] = [centerIJK[2], centerIJK[2]];
7265
+ }
6792
7266
  const threshold = oldThreshold || [Infinity, -Infinity];
6793
- const callback = ({ value }) => {
7267
+ const useDeltaSqr = useDelta * useDelta;
7268
+ const callback = ({ value, pointIJK }) => {
7269
+ const distance = esm/* vec3.sqrDist */.eR.sqrDist(centerIJK, pointIJK);
7270
+ if (distance > useDeltaSqr) {
7271
+ return;
7272
+ }
6794
7273
  const gray = Array.isArray(value) ? esm/* vec3.len */.eR.len(value) : value;
6795
7274
  threshold[0] = Math.min(gray, threshold[0]);
6796
7275
  threshold[1] = Math.max(gray, threshold[1]);
@@ -6830,7 +7309,7 @@ var esm = __webpack_require__(3823);
6830
7309
  strategySpecificConfiguration[activeStrategy] = {};
6831
7310
  }
6832
7311
  strategySpecificConfiguration[activeStrategy].dynamicRadiusInCanvas =
6833
- dynamicRadiusInCanvas;
7312
+ 3 + dynamicRadiusInCanvas;
6834
7313
  },
6835
7314
  });
6836
7315
 
@@ -6842,134 +7321,207 @@ var esm = __webpack_require__(3823);
6842
7321
  },
6843
7322
  });
6844
7323
 
6845
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/floodFill.js
6846
- var floodFill = __webpack_require__(84882);
7324
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js
7325
+ var dist_esm = __webpack_require__(81985);
6847
7326
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/triggerSegmentationEvents.js
6848
7327
  var triggerSegmentationEvents = __webpack_require__(49906);
7328
+ ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/segmentation/strategies/utils/normalizeViewportPlane.js
7329
+
7330
+ const { isEqual } = dist_esm.utilities;
7331
+ const acquisitionMapping = {
7332
+ toIJK: (ijkPrime) => ijkPrime,
7333
+ fromIJK: (ijk) => ijk,
7334
+ type: 'acquistion',
7335
+ };
7336
+ const jkMapping = {
7337
+ toIJK: ([j, k, i]) => [i, j, k],
7338
+ fromIJK: ([i, j, k]) => [j, k, i],
7339
+ type: 'jk',
7340
+ };
7341
+ const ikMapping = {
7342
+ toIJK: ([i, k, j]) => [i, j, k],
7343
+ fromIJK: ([i, j, k]) => [i, k, j],
7344
+ type: 'ik',
7345
+ };
7346
+ function normalizeViewportPlane(viewport, boundsIJK) {
7347
+ if (!(viewport instanceof dist_esm.BaseVolumeViewport)) {
7348
+ return { ...acquisitionMapping, boundsIJKPrime: boundsIJK };
7349
+ }
7350
+ const { viewPlaneNormal } = viewport.getCamera();
7351
+ const mapping = (isEqual(Math.abs(viewPlaneNormal[0]), 1) && jkMapping) ||
7352
+ (isEqual(Math.abs(viewPlaneNormal[1]), 1) && ikMapping) ||
7353
+ (isEqual(Math.abs(viewPlaneNormal[2]), 1) && acquisitionMapping);
7354
+ if (!mapping) {
7355
+ return {
7356
+ toIJK: null,
7357
+ boundsIJKPrime: null,
7358
+ fromIJK: null,
7359
+ error: `Only mappings orthogonal to acquisition plane are permitted, but requested ${viewPlaneNormal}`,
7360
+ };
7361
+ }
7362
+ return { ...mapping, boundsIJKPrime: mapping.fromIJK(boundsIJK) };
7363
+ }
7364
+
6849
7365
  ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/segmentation/strategies/compositions/islandRemoval.js
6850
7366
 
6851
7367
 
6852
7368
 
7369
+
7370
+ const { RLEVoxelMap } = dist_esm.utilities;
7371
+ const MAX_IMAGE_SIZE = 65535;
7372
+ var SegmentationEnum;
7373
+ (function (SegmentationEnum) {
7374
+ SegmentationEnum[SegmentationEnum["SEGMENT"] = 1] = "SEGMENT";
7375
+ SegmentationEnum[SegmentationEnum["ISLAND"] = 2] = "ISLAND";
7376
+ SegmentationEnum[SegmentationEnum["INTERIOR"] = 3] = "INTERIOR";
7377
+ SegmentationEnum[SegmentationEnum["EXTERIOR"] = 4] = "EXTERIOR";
7378
+ SegmentationEnum[SegmentationEnum["INTERIOR_SMALL"] = -5] = "INTERIOR_SMALL";
7379
+ SegmentationEnum[SegmentationEnum["INTERIOR_TEST"] = -6] = "INTERIOR_TEST";
7380
+ })(SegmentationEnum || (SegmentationEnum = {}));
6853
7381
  /* harmony default export */ const islandRemoval = ({
6854
7382
  [StrategyCallbacks/* default */.A.OnInteractionEnd]: (operationData) => {
6855
- const { previewVoxelManager: previewVoxelManager, segmentationVoxelManager, strategySpecificConfiguration, previewSegmentIndex, segmentIndex, } = operationData;
6856
- if (!strategySpecificConfiguration.THRESHOLD || segmentIndex === null) {
7383
+ const { strategySpecificConfiguration, previewSegmentIndex, segmentIndex } = operationData;
7384
+ if (!strategySpecificConfiguration.THRESHOLD ||
7385
+ segmentIndex === null ||
7386
+ previewSegmentIndex === undefined) {
6857
7387
  return;
6858
7388
  }
6859
- const clickedPoints = previewVoxelManager.getPoints();
6860
- if (!clickedPoints?.length) {
7389
+ const segmentSet = createSegmentSet(operationData);
7390
+ if (!segmentSet) {
6861
7391
  return;
6862
7392
  }
6863
- if (previewSegmentIndex === undefined) {
7393
+ const externalRemoved = removeExternalIslands(operationData, segmentSet);
7394
+ if (externalRemoved === undefined) {
6864
7395
  return;
6865
7396
  }
6866
- const boundsIJK = previewVoxelManager
6867
- .getBoundsIJK()
6868
- .map((bound, i) => [
6869
- Math.min(bound[0], ...clickedPoints.map((point) => point[i])),
6870
- Math.max(bound[1], ...clickedPoints.map((point) => point[i])),
6871
- ]);
6872
- if (boundsIJK.find((it) => it[0] < 0 || it[1] > 65535)) {
7397
+ const arrayOfSlices = removeInternalIslands(operationData, segmentSet);
7398
+ if (!arrayOfSlices) {
6873
7399
  return;
6874
7400
  }
6875
- const floodedSet = new Set();
6876
- const getter = (i, j, k) => {
6877
- if (i < boundsIJK[0][0] ||
6878
- i > boundsIJK[0][1] ||
6879
- j < boundsIJK[1][0] ||
6880
- j > boundsIJK[1][1] ||
6881
- k < boundsIJK[2][0] ||
6882
- k > boundsIJK[2][1]) {
6883
- return -1;
6884
- }
6885
- const index = segmentationVoxelManager.toIndex([i, j, k]);
6886
- if (floodedSet.has(index)) {
6887
- return -2;
6888
- }
6889
- const oldVal = segmentationVoxelManager.getAtIndex(index);
6890
- const isIn = oldVal === previewSegmentIndex || oldVal === segmentIndex ? 1 : 0;
6891
- if (!isIn) {
6892
- segmentationVoxelManager.addPoint(index);
6893
- }
6894
- return isIn;
6895
- };
6896
- let floodedCount = 0;
6897
- const onFlood = (i, j, k) => {
6898
- const index = segmentationVoxelManager.toIndex([i, j, k]);
6899
- if (floodedSet.has(index)) {
6900
- return;
6901
- }
6902
- previewVoxelManager.setAtIJK(i, j, k, previewSegmentIndex);
6903
- floodedSet.add(index);
6904
- floodedCount++;
6905
- };
6906
- clickedPoints.forEach((clickedPoint) => {
6907
- if (getter(...clickedPoint) === 1) {
6908
- (0,floodFill/* default */.A)(getter, clickedPoint, {
6909
- onFlood,
6910
- diagonals: true,
6911
- });
6912
- }
6913
- });
6914
- let clearedCount = 0;
6915
- let previewCount = 0;
6916
- const callback = ({ index, pointIJK, value: trackValue }) => {
6917
- const value = segmentationVoxelManager.getAtIndex(index);
6918
- if (floodedSet.has(index)) {
6919
- previewCount++;
6920
- const newValue = trackValue === segmentIndex ? segmentIndex : previewSegmentIndex;
6921
- previewVoxelManager.setAtIJKPoint(pointIJK, newValue);
6922
- }
6923
- else if (value === previewSegmentIndex) {
6924
- clearedCount++;
6925
- const newValue = trackValue ?? 0;
6926
- previewVoxelManager.setAtIJKPoint(pointIJK, newValue);
6927
- }
6928
- };
6929
- previewVoxelManager.forEach(callback, {});
6930
- if (floodedCount - previewCount !== 0) {
6931
- console.warn('There were flooded=', floodedCount, 'cleared=', clearedCount, 'preview count=', previewCount, 'not handled', floodedCount - previewCount);
7401
+ (0,triggerSegmentationEvents.triggerSegmentationDataModified)(operationData.segmentationId, arrayOfSlices, previewSegmentIndex);
7402
+ },
7403
+ });
7404
+ function createSegmentSet(operationData) {
7405
+ const { segmentationVoxelManager, previewSegmentIndex, previewVoxelManager, segmentIndex, viewport, } = operationData;
7406
+ const clickedPoints = previewVoxelManager.getPoints();
7407
+ if (!clickedPoints?.length) {
7408
+ return;
7409
+ }
7410
+ const boundsIJK = previewVoxelManager
7411
+ .getBoundsIJK()
7412
+ .map((bound, i) => [
7413
+ Math.min(bound[0], ...clickedPoints.map((point) => point[i])),
7414
+ Math.max(bound[1], ...clickedPoints.map((point) => point[i])),
7415
+ ]);
7416
+ if (boundsIJK.find((it) => it[0] < 0 || it[1] > MAX_IMAGE_SIZE)) {
7417
+ return;
7418
+ }
7419
+ const { toIJK, fromIJK, boundsIJKPrime, error } = normalizeViewportPlane(viewport, boundsIJK);
7420
+ if (error) {
7421
+ console.warn('Not performing island removal for planes not orthogonal to acquisition plane', error);
7422
+ return;
7423
+ }
7424
+ const [width, height, depth] = fromIJK(segmentationVoxelManager.dimensions);
7425
+ const floodedSet = new RLEVoxelMap(width, height, depth);
7426
+ const getter = (i, j, k) => {
7427
+ const index = segmentationVoxelManager.toIndex(toIJK([i, j, k]));
7428
+ const oldVal = segmentationVoxelManager.getAtIndex(index);
7429
+ if (oldVal === previewSegmentIndex || oldVal === segmentIndex) {
7430
+ return SegmentationEnum.SEGMENT;
6932
7431
  }
6933
- const islandMap = new Set(segmentationVoxelManager.points || []);
6934
- floodedSet.clear();
6935
- for (const index of islandMap.keys()) {
6936
- if (floodedSet.has(index)) {
7432
+ };
7433
+ floodedSet.fillFrom(getter, boundsIJKPrime);
7434
+ floodedSet.normalizer = { toIJK, fromIJK, boundsIJKPrime };
7435
+ return floodedSet;
7436
+ }
7437
+ function removeInternalIslands(operationData, floodedSet) {
7438
+ const { height, normalizer } = floodedSet;
7439
+ const { toIJK } = normalizer;
7440
+ const { previewVoxelManager, previewSegmentIndex } = operationData;
7441
+ floodedSet.forEachRow((baseIndex, row) => {
7442
+ let lastRle;
7443
+ for (const rle of [...row]) {
7444
+ if (rle.value !== SegmentationEnum.ISLAND) {
6937
7445
  continue;
6938
7446
  }
6939
- let isInternal = true;
6940
- const internalSet = new Set();
6941
- const onFloodInternal = (i, j, k) => {
6942
- const floodIndex = previewVoxelManager.toIndex([i, j, k]);
6943
- floodedSet.add(floodIndex);
6944
- if ((boundsIJK[0][0] !== boundsIJK[0][1] &&
6945
- (i === boundsIJK[0][0] || i === boundsIJK[0][1])) ||
6946
- (boundsIJK[1][0] !== boundsIJK[1][1] &&
6947
- (j === boundsIJK[1][0] || j === boundsIJK[1][1])) ||
6948
- (boundsIJK[2][0] !== boundsIJK[2][1] &&
6949
- (k === boundsIJK[2][0] || k === boundsIJK[2][1]))) {
6950
- isInternal = false;
6951
- }
6952
- if (isInternal) {
6953
- internalSet.add(floodIndex);
6954
- }
6955
- };
6956
- const pointIJK = previewVoxelManager.toIJK(index);
6957
- if (getter(...pointIJK) !== 0) {
7447
+ if (!lastRle) {
7448
+ lastRle = rle;
6958
7449
  continue;
6959
7450
  }
6960
- (0,floodFill/* default */.A)(getter, pointIJK, {
6961
- onFlood: onFloodInternal,
6962
- diagonals: false,
6963
- });
6964
- if (isInternal) {
6965
- for (const index of internalSet) {
6966
- previewVoxelManager.setAtIndex(index, previewSegmentIndex);
6967
- }
7451
+ for (let iPrime = lastRle.end; iPrime < rle.start; iPrime++) {
7452
+ floodedSet.set(baseIndex + iPrime, SegmentationEnum.INTERIOR);
6968
7453
  }
7454
+ lastRle = rle;
6969
7455
  }
6970
- (0,triggerSegmentationEvents.triggerSegmentationDataModified)(operationData.segmentationId, previewVoxelManager.getArrayOfModifiedSlices());
6971
- },
6972
- });
7456
+ });
7457
+ floodedSet.forEach((baseIndex, rle) => {
7458
+ if (rle.value !== SegmentationEnum.INTERIOR) {
7459
+ return;
7460
+ }
7461
+ const [, jPrime, kPrime] = floodedSet.toIJK(baseIndex);
7462
+ const rowPrev = jPrime > 0 ? floodedSet.getRun(jPrime - 1, kPrime) : null;
7463
+ const rowNext = jPrime + 1 < height ? floodedSet.getRun(jPrime + 1, kPrime) : null;
7464
+ const prevCovers = covers(rle, rowPrev);
7465
+ const nextCovers = covers(rle, rowNext);
7466
+ if (rle.end - rle.start > 2 && (!prevCovers || !nextCovers)) {
7467
+ floodedSet.floodFill(rle.start, jPrime, kPrime, SegmentationEnum.EXTERIOR, { singlePlane: true });
7468
+ }
7469
+ });
7470
+ floodedSet.forEach((baseIndex, rle) => {
7471
+ if (rle.value !== SegmentationEnum.INTERIOR) {
7472
+ return;
7473
+ }
7474
+ for (let iPrime = rle.start; iPrime < rle.end; iPrime++) {
7475
+ const clearPoint = toIJK(floodedSet.toIJK(baseIndex + iPrime));
7476
+ previewVoxelManager.setAtIJKPoint(clearPoint, previewSegmentIndex);
7477
+ }
7478
+ });
7479
+ return previewVoxelManager.getArrayOfModifiedSlices();
7480
+ }
7481
+ function removeExternalIslands(operationData, floodedSet) {
7482
+ const { previewVoxelManager } = operationData;
7483
+ const { toIJK, fromIJK } = floodedSet.normalizer;
7484
+ const clickedPoints = previewVoxelManager.getPoints();
7485
+ let floodedCount = 0;
7486
+ clickedPoints.forEach((clickedPoint) => {
7487
+ const ijkPrime = fromIJK(clickedPoint);
7488
+ const index = floodedSet.toIndex(ijkPrime);
7489
+ const [iPrime, jPrime, kPrime] = ijkPrime;
7490
+ if (floodedSet.get(index) === SegmentationEnum.SEGMENT) {
7491
+ floodedCount += floodedSet.floodFill(iPrime, jPrime, kPrime, SegmentationEnum.ISLAND);
7492
+ }
7493
+ });
7494
+ if (floodedCount === 0) {
7495
+ return;
7496
+ }
7497
+ const callback = (index, rle) => {
7498
+ const [, jPrime, kPrime] = floodedSet.toIJK(index);
7499
+ if (rle.value !== SegmentationEnum.ISLAND) {
7500
+ for (let iPrime = rle.start; iPrime < rle.end; iPrime++) {
7501
+ const clearPoint = toIJK([iPrime, jPrime, kPrime]);
7502
+ previewVoxelManager.setAtIJKPoint(clearPoint, null);
7503
+ }
7504
+ }
7505
+ };
7506
+ floodedSet.forEach(callback, { rowModified: true });
7507
+ return floodedCount;
7508
+ }
7509
+ function covers(rle, row) {
7510
+ if (!row) {
7511
+ return false;
7512
+ }
7513
+ let { start } = rle;
7514
+ const { end } = rle;
7515
+ for (const rowRle of row) {
7516
+ if (start >= rowRle.start && start < rowRle.end) {
7517
+ start = rowRle.end;
7518
+ if (start >= end) {
7519
+ return true;
7520
+ }
7521
+ }
7522
+ }
7523
+ return false;
7524
+ }
6973
7525
 
6974
7526
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/events/triggerSegmentationDataModified.js
6975
7527
  var triggerSegmentationDataModified = __webpack_require__(98798);
@@ -7007,8 +7559,9 @@ function lightenColor(r, g, b, a, factor = 0.4) {
7007
7559
  return preview;
7008
7560
  },
7009
7561
  [StrategyCallbacks/* default */.A.Initialize]: (operationData) => {
7010
- const { segmentIndex, previewSegmentIndex, previewColors, preview } = operationData;
7011
- if (previewColors === undefined) {
7562
+ const { segmentIndex, previewSegmentIndex, previewColors, preview, segmentationId, segmentationVoxelManager, } = operationData;
7563
+ if (previewColors === undefined || !previewSegmentIndex) {
7564
+ operationData.memo = operationData.createMemo(segmentationId, segmentationVoxelManager);
7012
7565
  return;
7013
7566
  }
7014
7567
  if (preview) {
@@ -7016,7 +7569,7 @@ function lightenColor(r, g, b, a, factor = 0.4) {
7016
7569
  operationData.segmentationVoxelManager;
7017
7570
  operationData.previewVoxelManager = preview.previewVoxelManager;
7018
7571
  }
7019
- if (segmentIndex === null || !previewSegmentIndex) {
7572
+ if (segmentIndex === null) {
7020
7573
  return;
7021
7574
  }
7022
7575
  const configColor = previewColors?.[segmentIndex];
@@ -7028,24 +7581,27 @@ function lightenColor(r, g, b, a, factor = 0.4) {
7028
7581
  (0,segmentationColor.setSegmentIndexColor)(operationData.viewport.id, operationData.segmentationId, previewSegmentIndex, previewColor);
7029
7582
  },
7030
7583
  [StrategyCallbacks/* default */.A.AcceptPreview]: (operationData) => {
7031
- const { segmentationVoxelManager, previewVoxelManager: previewVoxelManager, previewSegmentIndex, preview, } = operationData || {};
7584
+ const { segmentationVoxelManager, previewVoxelManager: previewVoxelManager, previewSegmentIndex, segmentationId, preview, } = operationData || {};
7032
7585
  if (previewSegmentIndex === undefined) {
7033
7586
  return;
7034
7587
  }
7035
7588
  const segmentIndex = preview?.segmentIndex ?? operationData.segmentIndex;
7036
- const tracking = previewVoxelManager;
7037
- if (!tracking || tracking.modifiedSlices.size === 0) {
7589
+ if (!previewVoxelManager || previewVoxelManager.modifiedSlices.size === 0) {
7038
7590
  return;
7039
7591
  }
7040
- const callback = ({ index }) => {
7592
+ const memo = operationData.createMemo(segmentationId, segmentationVoxelManager);
7593
+ operationData.memo = memo;
7594
+ const { voxelManager } = memo;
7595
+ const callback = ({ index, value }) => {
7041
7596
  const oldValue = segmentationVoxelManager.getAtIndex(index);
7042
7597
  if (oldValue === previewSegmentIndex) {
7043
- segmentationVoxelManager.setAtIndex(index, segmentIndex);
7598
+ segmentationVoxelManager.setAtIndex(index, value);
7599
+ voxelManager.setAtIndex(index, segmentIndex);
7044
7600
  }
7045
7601
  };
7046
- tracking.forEach(callback, {});
7047
- (0,triggerSegmentationDataModified/* triggerSegmentationDataModified */.Q)(operationData.segmentationId, tracking.getArrayOfModifiedSlices());
7048
- tracking.clear();
7602
+ previewVoxelManager.forEach(callback, {});
7603
+ (0,triggerSegmentationDataModified/* triggerSegmentationDataModified */.Q)(operationData.segmentationId, previewVoxelManager.getArrayOfModifiedSlices(), preview.segmentIndex);
7604
+ previewVoxelManager.clear();
7049
7605
  },
7050
7606
  [StrategyCallbacks/* default */.A.RejectPreview]: (operationData) => {
7051
7607
  const { previewVoxelManager: previewVoxelManager, segmentationVoxelManager, } = operationData;
@@ -7056,7 +7612,7 @@ function lightenColor(r, g, b, a, factor = 0.4) {
7056
7612
  segmentationVoxelManager.setAtIndex(index, value);
7057
7613
  };
7058
7614
  previewVoxelManager.forEach(callback);
7059
- (0,triggerSegmentationDataModified/* triggerSegmentationDataModified */.Q)(operationData.segmentationId, previewVoxelManager.getArrayOfModifiedSlices());
7615
+ (0,triggerSegmentationDataModified/* triggerSegmentationDataModified */.Q)(operationData.segmentationId, previewVoxelManager.getArrayOfModifiedSlices(), 0);
7060
7616
  previewVoxelManager.clear();
7061
7617
  },
7062
7618
  });
@@ -7065,7 +7621,7 @@ function lightenColor(r, g, b, a, factor = 0.4) {
7065
7621
 
7066
7622
  /* harmony default export */ const regionFill = ({
7067
7623
  [StrategyCallbacks/* default */.A.Fill]: (operationData) => {
7068
- const { segmentsLocked, segmentationImageData, segmentationVoxelManager, previewVoxelManager: previewVoxelManager, brushStrategy, centerIJK, } = operationData;
7624
+ const { segmentsLocked, segmentationImageData, segmentationVoxelManager, previewVoxelManager, brushStrategy, centerIJK, } = operationData;
7069
7625
  const isWithinThreshold = brushStrategy.createIsInThreshold?.(operationData);
7070
7626
  const { setValue } = brushStrategy;
7071
7627
  const callback = isWithinThreshold
@@ -7086,14 +7642,12 @@ function lightenColor(r, g, b, a, factor = 0.4) {
7086
7642
  },
7087
7643
  });
7088
7644
 
7089
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js
7090
- var dist_esm = __webpack_require__(81985);
7091
7645
  ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/segmentation/strategies/compositions/setValue.js
7092
7646
 
7093
-
7094
7647
  /* harmony default export */ const setValue = ({
7095
7648
  [StrategyCallbacks/* default */.A.INTERNAL_setValue]: (operationData, { value, index }) => {
7096
- const { segmentsLocked, segmentIndex, previewVoxelManager, previewSegmentIndex, segmentationVoxelManager, } = operationData;
7649
+ const { segmentsLocked, segmentIndex, previewSegmentIndex, segmentationVoxelManager, memo, } = operationData;
7650
+ const previewVoxelManager = memo?.voxelManager || operationData.previewVoxelManager;
7097
7651
  const existingValue = segmentationVoxelManager.getAtIndex(index);
7098
7652
  let changed = false;
7099
7653
  if (segmentIndex === null) {
@@ -7143,6 +7697,50 @@ var dist_esm = __webpack_require__(81985);
7143
7697
  },
7144
7698
  });
7145
7699
 
7700
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/VolumetricCalculator.js
7701
+ var VolumetricCalculator = __webpack_require__(68915);
7702
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/getActiveSegmentIndex.js
7703
+ var getActiveSegmentIndex = __webpack_require__(60740);
7704
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/segmentation/strategies/utils/getStrategyData.js
7705
+ var getStrategyData = __webpack_require__(40905);
7706
+ ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/segmentation/strategies/compositions/labelmapStatistics.js
7707
+
7708
+
7709
+
7710
+
7711
+ /* harmony default export */ const labelmapStatistics = ({
7712
+ [StrategyCallbacks/* default */.A.GetStatistics]: function (enabledElement, operationData, options) {
7713
+ const { viewport } = enabledElement;
7714
+ let { indices } = options;
7715
+ const { segmentationId } = operationData;
7716
+ if (!indices) {
7717
+ indices = [(0,getActiveSegmentIndex/* getActiveSegmentIndex */.Q)(segmentationId)];
7718
+ }
7719
+ else if (!Array.isArray(indices)) {
7720
+ indices = [indices, 255];
7721
+ }
7722
+ const indicesArr = indices;
7723
+ const { segmentationVoxelManager, imageVoxelManager, segmentationImageData, } = (0,getStrategyData/* getStrategyData */.S)({
7724
+ operationData,
7725
+ viewport,
7726
+ });
7727
+ const spacing = segmentationImageData.getSpacing();
7728
+ const { boundsIJK: boundsOrig } = segmentationVoxelManager;
7729
+ if (!boundsOrig) {
7730
+ return VolumetricCalculator/* default */.A.getStatistics({ spacing });
7731
+ }
7732
+ segmentationVoxelManager.forEach((voxel) => {
7733
+ const { value, pointIJK } = voxel;
7734
+ if (indicesArr.indexOf(value) === -1) {
7735
+ return;
7736
+ }
7737
+ const imageValue = imageVoxelManager.getAtIJKPoint(pointIJK);
7738
+ VolumetricCalculator/* default */.A.statsCallback({ value: imageValue });
7739
+ });
7740
+ return VolumetricCalculator/* default */.A.getStatistics({ spacing });
7741
+ },
7742
+ });
7743
+
7146
7744
  ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/segmentation/strategies/compositions/index.js
7147
7745
 
7148
7746
 
@@ -7152,6 +7750,7 @@ var dist_esm = __webpack_require__(81985);
7152
7750
 
7153
7751
 
7154
7752
 
7753
+
7155
7754
  /* harmony default export */ const compositions = ({
7156
7755
  determineSegmentIndex: determineSegmentIndex,
7157
7756
  dynamicThreshold: dynamicThreshold,
@@ -7161,6 +7760,7 @@ var dist_esm = __webpack_require__(81985);
7161
7760
  regionFill: regionFill,
7162
7761
  setValue: setValue,
7163
7762
  threshold: threshold,
7763
+ labelmapStatistics: labelmapStatistics,
7164
7764
  });
7165
7765
 
7166
7766
 
@@ -7175,7 +7775,7 @@ var dist_esm = __webpack_require__(81985);
7175
7775
  /* harmony export */ });
7176
7776
  /* harmony import */ var _BrushStrategy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55887);
7177
7777
  /* harmony import */ var _fillCircle__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(56789);
7178
- /* harmony import */ var _compositions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(21553);
7778
+ /* harmony import */ var _compositions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(96814);
7179
7779
 
7180
7780
 
7181
7781
 
@@ -7200,7 +7800,7 @@ function eraseRectangle(enabledElement, operationData, inside = true) {
7200
7800
  const eraseOperationData = Object.assign({}, operationData, {
7201
7801
  segmentIndex: 0,
7202
7802
  });
7203
- (0,_fillRectangle__WEBPACK_IMPORTED_MODULE_0__/* .fillInsideRectangle */ .p)(enabledElement, eraseOperationData);
7803
+ (0,_fillRectangle__WEBPACK_IMPORTED_MODULE_0__/* .fillInsideRectangle */ .pY)(enabledElement, eraseOperationData);
7204
7804
  }
7205
7805
  function eraseInsideRectangle(enabledElement, operationData) {
7206
7806
  eraseRectangle(enabledElement, operationData, true);
@@ -7221,7 +7821,7 @@ function eraseOutsideRectangle(enabledElement, operationData) {
7221
7821
  /* harmony export */ });
7222
7822
  /* harmony import */ var _BrushStrategy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55887);
7223
7823
  /* harmony import */ var _fillSphere__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17492);
7224
- /* harmony import */ var _compositions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(21553);
7824
+ /* harmony import */ var _compositions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(96814);
7225
7825
 
7226
7826
 
7227
7827
 
@@ -7249,7 +7849,7 @@ const eraseInsideSphere = ERASE_SPHERE_STRATEGY.strategyFunction;
7249
7849
  /* harmony import */ var _utilities_boundingBox__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(72282);
7250
7850
  /* harmony import */ var _BrushStrategy__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(55887);
7251
7851
  /* harmony import */ var _enums__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(99737);
7252
- /* harmony import */ var _compositions__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(21553);
7852
+ /* harmony import */ var _compositions__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(96814);
7253
7853
  /* harmony import */ var _utilities_math_sphere__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(62783);
7254
7854
 
7255
7855
 
@@ -7314,8 +7914,8 @@ function createPointInEllipse(worldInfo) {
7314
7914
  const { precalculated } = (0,_utilities_math_ellipse__WEBPACK_IMPORTED_MODULE_2__.precalculatePointInEllipse)(ellipseObj, {});
7315
7915
  return precalculated;
7316
7916
  }
7317
- const CIRCLE_STRATEGY = new _BrushStrategy__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A('Circle', _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.regionFill, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.setValue, initializeCircle, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.determineSegmentIndex, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.preview);
7318
- const CIRCLE_THRESHOLD_STRATEGY = new _BrushStrategy__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A('CircleThreshold', _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.regionFill, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.setValue, initializeCircle, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.determineSegmentIndex, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.dynamicThreshold, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.threshold, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.preview, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.islandRemoval);
7917
+ const CIRCLE_STRATEGY = new _BrushStrategy__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A('Circle', _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.regionFill, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.setValue, initializeCircle, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.determineSegmentIndex, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.preview, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.labelmapStatistics);
7918
+ const CIRCLE_THRESHOLD_STRATEGY = new _BrushStrategy__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A('CircleThreshold', _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.regionFill, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.setValue, initializeCircle, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.determineSegmentIndex, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.dynamicThreshold, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.threshold, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.preview, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.islandRemoval, _compositions__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.labelmapStatistics);
7319
7919
  const fillInsideCircle = CIRCLE_STRATEGY.strategyFunction;
7320
7920
  const thresholdInsideCircle = CIRCLE_THRESHOLD_STRATEGY.strategyFunction;
7321
7921
  function fillOutsideCircle() {
@@ -7331,32 +7931,47 @@ function fillOutsideCircle() {
7331
7931
 
7332
7932
  "use strict";
7333
7933
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
7334
- /* harmony export */ p: () => (/* binding */ fillInsideRectangle)
7934
+ /* harmony export */ pY: () => (/* binding */ fillInsideRectangle)
7335
7935
  /* harmony export */ });
7336
- /* unused harmony export fillOutsideRectangle */
7337
- /* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(81985);
7338
- /* harmony import */ var _utilities_boundingBox__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72282);
7339
- /* harmony import */ var _stateManagement_segmentation_triggerSegmentationEvents__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(49906);
7340
- /* harmony import */ var _utils_getStrategyData__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(40905);
7341
- /* harmony import */ var _utilities_rectangleROITool_isAxisAlignedRectangle__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(26384);
7936
+ /* unused harmony exports RECTANGLE_STRATEGY, RECTANGLE_THRESHOLD_STRATEGY, thresholdInsideRectangle */
7937
+ /* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3823);
7938
+ /* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(81985);
7939
+ /* harmony import */ var _utilities_boundingBox__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(72282);
7940
+ /* harmony import */ var _stateManagement_segmentation_triggerSegmentationEvents__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(49906);
7941
+ /* harmony import */ var _utils_getStrategyData__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(40905);
7942
+ /* harmony import */ var _utilities_rectangleROITool_isAxisAlignedRectangle__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(26384);
7943
+ /* harmony import */ var _BrushStrategy__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(55887);
7944
+ /* harmony import */ var _enums__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(99737);
7945
+ /* harmony import */ var _compositions__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(96814);
7342
7946
 
7343
7947
 
7344
7948
 
7345
7949
 
7346
7950
 
7347
- const { transformWorldToIndex } = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities;
7348
- function fillRectangle(enabledElement, operationData) {
7349
- const { points, segmentsLocked, segmentIndex, segmentationId } = operationData;
7350
- const { viewport } = enabledElement;
7351
- const strategyData = (0,_utils_getStrategyData__WEBPACK_IMPORTED_MODULE_3__/* .getStrategyData */ .S)({
7352
- operationData,
7353
- viewport: enabledElement.viewport,
7354
- });
7355
- if (!strategyData) {
7356
- console.warn('No data found for fillRectangle');
7357
- return;
7358
- }
7359
- const { segmentationImageData, segmentationVoxelManager } = strategyData;
7951
+
7952
+
7953
+
7954
+
7955
+ const { transformWorldToIndex } = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_1__.utilities;
7956
+ const initializeRectangle = {
7957
+ [_enums__WEBPACK_IMPORTED_MODULE_7__.StrategyCallbacks.Initialize]: (operationData) => {
7958
+ const { points, imageVoxelManager, viewport, segmentationImageData, segmentationVoxelManager, } = operationData;
7959
+ if (!points) {
7960
+ return;
7961
+ }
7962
+ const center = gl_matrix__WEBPACK_IMPORTED_MODULE_0__/* .vec3.fromValues */ .eR.fromValues(0, 0, 0);
7963
+ points.forEach((point) => {
7964
+ gl_matrix__WEBPACK_IMPORTED_MODULE_0__/* .vec3.add */ .eR.add(center, center, point);
7965
+ });
7966
+ gl_matrix__WEBPACK_IMPORTED_MODULE_0__/* .vec3.scale */ .eR.scale(center, center, 1 / points.length);
7967
+ operationData.centerWorld = center;
7968
+ operationData.centerIJK = transformWorldToIndex(segmentationImageData, center);
7969
+ const { boundsIJK, pointInShapeFn } = createPointInRectangle(viewport, points, segmentationImageData);
7970
+ operationData.isInObject = pointInShapeFn;
7971
+ operationData.isInObjectBoundsIJK = boundsIJK;
7972
+ },
7973
+ };
7974
+ function createPointInRectangle(viewport, points, segmentationImageData) {
7360
7975
  let rectangleCornersIJK = points.map((world) => {
7361
7976
  return transformWorldToIndex(segmentationImageData, world);
7362
7977
  });
@@ -7365,17 +7980,17 @@ function fillRectangle(enabledElement, operationData) {
7365
7980
  return Math.round(coord);
7366
7981
  });
7367
7982
  });
7368
- const boundsIJK = (0,_utilities_boundingBox__WEBPACK_IMPORTED_MODULE_1__.getBoundingBoxAroundShapeIJK)(rectangleCornersIJK, segmentationImageData.getDimensions());
7369
- const isStackViewport = viewport instanceof _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.StackViewport;
7370
- const isAligned = isStackViewport || (0,_utilities_rectangleROITool_isAxisAlignedRectangle__WEBPACK_IMPORTED_MODULE_4__/* .isAxisAlignedRectangle */ .l)(rectangleCornersIJK);
7983
+ const boundsIJK = (0,_utilities_boundingBox__WEBPACK_IMPORTED_MODULE_2__.getBoundingBoxAroundShapeIJK)(rectangleCornersIJK, segmentationImageData.getDimensions());
7984
+ const isStackViewport = viewport instanceof _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_1__.StackViewport;
7985
+ const isAligned = isStackViewport || (0,_utilities_rectangleROITool_isAxisAlignedRectangle__WEBPACK_IMPORTED_MODULE_5__/* .isAxisAlignedRectangle */ .l)(rectangleCornersIJK);
7371
7986
  const direction = segmentationImageData.getDirection();
7372
7987
  const spacing = segmentationImageData.getSpacing();
7373
7988
  const { viewPlaneNormal } = viewport.getCamera();
7374
- const EPS = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities.getSpacingInNormalDirection({
7989
+ const EPS = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_1__.utilities.getSpacingInNormalDirection({
7375
7990
  direction,
7376
7991
  spacing,
7377
7992
  }, viewPlaneNormal);
7378
- const pointsBoundsLPS = (0,_utilities_boundingBox__WEBPACK_IMPORTED_MODULE_1__.getBoundingBoxAroundShapeWorld)(points);
7993
+ const pointsBoundsLPS = (0,_utilities_boundingBox__WEBPACK_IMPORTED_MODULE_2__.getBoundingBoxAroundShapeWorld)(points);
7379
7994
  let [[xMin, xMax], [yMin, yMax], [zMin, zMax]] = pointsBoundsLPS;
7380
7995
  xMin -= EPS;
7381
7996
  xMax += EPS;
@@ -7392,25 +8007,13 @@ function fillRectangle(enabledElement, operationData) {
7392
8007
  const zInside = z >= zMin && z <= zMax;
7393
8008
  return xInside && yInside && zInside;
7394
8009
  };
7395
- const callback = ({ value, index }) => {
7396
- if (segmentsLocked.includes(value)) {
7397
- return;
7398
- }
7399
- segmentationVoxelManager.setAtIndex(index, segmentIndex);
7400
- };
7401
- segmentationVoxelManager.forEach(callback, {
7402
- isInObject: pointInShapeFn,
7403
- boundsIJK,
7404
- imageData: segmentationImageData,
7405
- });
7406
- (0,_stateManagement_segmentation_triggerSegmentationEvents__WEBPACK_IMPORTED_MODULE_2__.triggerSegmentationDataModified)(segmentationId);
7407
- }
7408
- function fillInsideRectangle(enabledElement, operationData) {
7409
- fillRectangle(enabledElement, operationData);
7410
- }
7411
- function fillOutsideRectangle(enabledElement, operationData) {
7412
- fillRectangle(enabledElement, operationData);
8010
+ return { boundsIJK, pointInShapeFn };
7413
8011
  }
8012
+ const RECTANGLE_STRATEGY = new _BrushStrategy__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A('Rectangle', _compositions__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A.regionFill, _compositions__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A.setValue, initializeRectangle, _compositions__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A.determineSegmentIndex, _compositions__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A.preview, _compositions__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A.labelmapStatistics);
8013
+ const RECTANGLE_THRESHOLD_STRATEGY = new _BrushStrategy__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A('RectangleThreshold', _compositions__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A.regionFill, _compositions__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A.setValue, initializeRectangle, _compositions__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A.determineSegmentIndex, _compositions__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A.dynamicThreshold, _compositions__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A.threshold, _compositions__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A.preview, _compositions__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A.islandRemoval, _compositions__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A.labelmapStatistics);
8014
+ const fillInsideRectangle = RECTANGLE_STRATEGY.strategyFunction;
8015
+ const thresholdInsideRectangle = RECTANGLE_THRESHOLD_STRATEGY.strategyFunction;
8016
+
7414
8017
 
7415
8018
 
7416
8019
  /***/ }),
@@ -7421,6 +8024,7 @@ function fillOutsideRectangle(enabledElement, operationData) {
7421
8024
  "use strict";
7422
8025
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
7423
8026
  /* harmony export */ Jq: () => (/* binding */ fillInsideSphere),
8027
+ /* harmony export */ Sw: () => (/* binding */ thresholdInsideSphereIsland),
7424
8028
  /* harmony export */ rd: () => (/* binding */ thresholdInsideSphere),
7425
8029
  /* harmony export */ u8: () => (/* binding */ SPHERE_STRATEGY)
7426
8030
  /* harmony export */ });
@@ -7428,7 +8032,7 @@ function fillOutsideRectangle(enabledElement, operationData) {
7428
8032
  /* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(81985);
7429
8033
  /* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3823);
7430
8034
  /* harmony import */ var _BrushStrategy__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(55887);
7431
- /* harmony import */ var _compositions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(21553);
8035
+ /* harmony import */ var _compositions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(96814);
7432
8036
  /* harmony import */ var _enums_StrategyCallbacks__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(84093);
7433
8037
  /* harmony import */ var _fillCircle__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(56789);
7434
8038
  /* harmony import */ var _utilities_getSphereBoundsInfo__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(4296);
@@ -7453,7 +8057,7 @@ const sphereComposition = {
7453
8057
  gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.scale */ .eR.scale(center, center, 1 / points.length);
7454
8058
  operationData.centerWorld = center;
7455
8059
  operationData.centerIJK = transformWorldToIndex(segmentationImageData, center);
7456
- const { boundsIJK: newBoundsIJK, topLeftWorld, bottomRightWorld, } = (0,_utilities_getSphereBoundsInfo__WEBPACK_IMPORTED_MODULE_6__/* .getSphereBoundsInfo */ .R)(points.slice(0, 2), segmentationImageData, viewport);
8060
+ const { boundsIJK: newBoundsIJK, topLeftWorld, bottomRightWorld, } = (0,_utilities_getSphereBoundsInfo__WEBPACK_IMPORTED_MODULE_6__/* .getSphereBoundsInfoFromViewport */ .l)(points.slice(0, 2), segmentationImageData, viewport);
7457
8061
  operationData.isInObjectBoundsIJK = newBoundsIJK;
7458
8062
  operationData.isInObject = (0,_fillCircle__WEBPACK_IMPORTED_MODULE_5__/* .createEllipseInPoint */ .mu)({
7459
8063
  topLeftWorld,
@@ -7462,10 +8066,12 @@ const sphereComposition = {
7462
8066
  });
7463
8067
  },
7464
8068
  };
7465
- const SPHERE_STRATEGY = new _BrushStrategy__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A('Sphere', _compositions__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.regionFill, _compositions__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.setValue, sphereComposition, _compositions__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.determineSegmentIndex, _compositions__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.preview);
8069
+ const SPHERE_STRATEGY = new _BrushStrategy__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A('Sphere', _compositions__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.regionFill, _compositions__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.setValue, sphereComposition, _compositions__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.determineSegmentIndex, _compositions__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.preview, _compositions__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.labelmapStatistics);
7466
8070
  const fillInsideSphere = SPHERE_STRATEGY.strategyFunction;
7467
- const SPHERE_THRESHOLD_STRATEGY = new _BrushStrategy__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A('SphereThreshold', ...SPHERE_STRATEGY.compositions, _compositions__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.dynamicThreshold, _compositions__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.threshold, _compositions__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.islandRemoval);
8071
+ const SPHERE_THRESHOLD_STRATEGY = new _BrushStrategy__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A('SphereThreshold', ...SPHERE_STRATEGY.compositions, _compositions__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.dynamicThreshold, _compositions__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.threshold);
8072
+ const SPHERE_THRESHOLD_STRATEGY_ISLAND = new _BrushStrategy__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A('SphereThreshold', ...SPHERE_STRATEGY.compositions, _compositions__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.dynamicThreshold, _compositions__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.threshold, _compositions__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.islandRemoval);
7468
8073
  const thresholdInsideSphere = SPHERE_THRESHOLD_STRATEGY.strategyFunction;
8074
+ const thresholdInsideSphereIsland = SPHERE_THRESHOLD_STRATEGY_ISLAND.strategyFunction;
7469
8075
  function fillOutsideSphere() {
7470
8076
  throw new Error('fill outside sphere not implemented');
7471
8077
  }
@@ -7482,7 +8088,7 @@ function fillOutsideSphere() {
7482
8088
  /* harmony export */ S: () => (/* binding */ getStrategyData)
7483
8089
  /* harmony export */ });
7484
8090
  /* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(81985);
7485
- /* harmony import */ var _stateManagement_segmentation_segmentationState__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(98870);
8091
+ /* harmony import */ var _stateManagement_segmentation_segmentationState__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(83243);
7486
8092
  /* harmony import */ var _stateManagement_segmentation_helpers__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(27108);
7487
8093
 
7488
8094
 
@@ -8053,12 +8659,14 @@ function _stopClip(element, options = { stopDynamicCine: true, viewportId: undef
8053
8659
  }
8054
8660
  function _stopDynamicVolumeCine(element) {
8055
8661
  const { viewport } = (0,dist_esm.getEnabledElement)(element);
8056
- const volume = _getVolumeFromViewport(viewport);
8057
- if (volume?.isDynamicVolume()) {
8058
- const dynamicCineElement = dynamicVolumesPlayingMap.get(volume.volumeId);
8059
- dynamicVolumesPlayingMap.delete(volume.volumeId);
8060
- if (dynamicCineElement && dynamicCineElement !== element) {
8061
- stopClip(dynamicCineElement);
8662
+ if (viewport instanceof dist_esm.VolumeViewport) {
8663
+ const volume = _getVolumeFromViewport(viewport);
8664
+ if (volume?.isDynamicVolume()) {
8665
+ const dynamicCineElement = dynamicVolumesPlayingMap.get(volume.volumeId);
8666
+ dynamicVolumesPlayingMap.delete(volume.volumeId);
8667
+ if (dynamicCineElement && dynamicCineElement !== element) {
8668
+ stopClip(dynamicCineElement);
8669
+ }
8062
8670
  }
8063
8671
  }
8064
8672
  }
@@ -8108,6 +8716,9 @@ function _stopClipWithData(playClipData) {
8108
8716
  }
8109
8717
  }
8110
8718
  function _getVolumeFromViewport(viewport) {
8719
+ if (!(viewport instanceof dist_esm.VolumeViewport)) {
8720
+ return undefined;
8721
+ }
8111
8722
  const volumeIds = viewport.getAllVolumeIds();
8112
8723
  if (!volumeIds?.length) {
8113
8724
  return undefined;
@@ -8713,14 +9324,15 @@ function generateContourSetsFromLabelmap({ segmentations }) {
8713
9324
  console.warn(`No volume found for ${segVolumeId}`);
8714
9325
  return;
8715
9326
  }
8716
- const numSlices = vol.dimensions[2];
8717
9327
  const voxelManager = vol.voxelManager;
9328
+ const segData = voxelManager.getCompleteScalarDataArray();
9329
+ const numSlices = vol.dimensions[2];
8718
9330
  const pixelsPerSlice = vol.dimensions[0] * vol.dimensions[1];
8719
9331
  for (let z = 0; z < numSlices; z++) {
8720
9332
  for (let y = 0; y < vol.dimensions[1]; y++) {
8721
9333
  const index = y * vol.dimensions[0] + z * pixelsPerSlice;
8722
- voxelManager.setAtIndex(index, 0);
8723
- voxelManager.setAtIndex(index + vol.dimensions[0] - 1, 0);
9334
+ segData[index] = 0;
9335
+ segData[index + vol.dimensions[0] - 1] = 0;
8724
9336
  }
8725
9337
  }
8726
9338
  const ContourSets = [];
@@ -8740,13 +9352,13 @@ function generateContourSetsFromLabelmap({ segmentations }) {
8740
9352
  });
8741
9353
  const { containedSegmentIndices } = segment;
8742
9354
  for (let sliceIndex = 0; sliceIndex < numSlices; sliceIndex++) {
8743
- if (isSliceEmptyForSegment(sliceIndex, voxelManager, pixelsPerSlice, segIndex)) {
9355
+ if (isSliceEmptyForSegment(sliceIndex, segData, pixelsPerSlice, segIndex)) {
8744
9356
  continue;
8745
9357
  }
8746
9358
  const frameStart = sliceIndex * pixelsPerSlice;
8747
9359
  try {
8748
9360
  for (let i = 0; i < pixelsPerSlice; i++) {
8749
- const value = voxelManager.getAtIndex(i + frameStart);
9361
+ const value = segData[i + frameStart];
8750
9362
  if (value === segIndex || containedSegmentIndices?.has(value)) {
8751
9363
  scalars.setValue(i + frameStart, 1);
8752
9364
  }
@@ -8795,11 +9407,11 @@ function generateContourSetsFromLabelmap({ segmentations }) {
8795
9407
  }
8796
9408
  return ContourSets;
8797
9409
  }
8798
- function isSliceEmptyForSegment(sliceIndex, voxelManager, pixelsPerSlice, segIndex) {
9410
+ function isSliceEmptyForSegment(sliceIndex, segData, pixelsPerSlice, segIndex) {
8799
9411
  const startIdx = sliceIndex * pixelsPerSlice;
8800
9412
  const endIdx = startIdx + pixelsPerSlice;
8801
9413
  for (let i = startIdx; i < endIdx; i++) {
8802
- if (voxelManager.getAtIndex(i) === segIndex) {
9414
+ if (segData[i] === segIndex) {
8803
9415
  return false;
8804
9416
  }
8805
9417
  }
@@ -9657,7 +10269,8 @@ function _handlePTModality(imageId, options) {
9657
10269
 
9658
10270
  "use strict";
9659
10271
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
9660
- /* harmony export */ R: () => (/* binding */ getSphereBoundsInfo)
10272
+ /* harmony export */ R: () => (/* binding */ getSphereBoundsInfo),
10273
+ /* harmony export */ l: () => (/* binding */ getSphereBoundsInfoFromViewport)
9661
10274
  /* harmony export */ });
9662
10275
  /* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(81985);
9663
10276
  /* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3823);
@@ -9666,14 +10279,11 @@ function _handlePTModality(imageId, options) {
9666
10279
 
9667
10280
 
9668
10281
  const { transformWorldToIndex } = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities;
9669
- function getSphereBoundsInfo(circlePoints, imageData, viewport) {
10282
+ function _getSphereBoundsInfo(circlePoints, imageData, directionVectors) {
9670
10283
  const [bottom, top] = circlePoints;
9671
10284
  const centerWorld = gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.fromValues */ .eR.fromValues((bottom[0] + top[0]) / 2, (bottom[1] + top[1]) / 2, (bottom[2] + top[2]) / 2);
9672
10285
  const radiusWorld = gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.distance */ .eR.distance(bottom, top) / 2;
9673
- if (!viewport) {
9674
- throw new Error('viewport is required in order to calculate the sphere bounds');
9675
- }
9676
- const { boundsIJK, topLeftWorld, bottomRightWorld } = _computeBoundsIJKWithCamera(imageData, viewport, circlePoints, centerWorld, radiusWorld);
10286
+ const { boundsIJK, topLeftWorld, bottomRightWorld } = _computeBoundsIJK(imageData, directionVectors, circlePoints, centerWorld, radiusWorld);
9677
10287
  return {
9678
10288
  boundsIJK,
9679
10289
  centerWorld: centerWorld,
@@ -9682,20 +10292,46 @@ function getSphereBoundsInfo(circlePoints, imageData, viewport) {
9682
10292
  bottomRightWorld: bottomRightWorld,
9683
10293
  };
9684
10294
  }
9685
- function _computeBoundsIJKWithCamera(imageData, viewport, circlePoints, centerWorld, radiusWorld) {
9686
- const [bottom, top] = circlePoints;
9687
- const dimensions = imageData.getDimensions();
10295
+ function getSphereBoundsInfo(circlePoints, imageData) {
10296
+ const direction = imageData.getDirection();
10297
+ const rowCosine = gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.fromValues */ .eR.fromValues(direction[0], direction[1], direction[2]);
10298
+ const columnCosine = gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.fromValues */ .eR.fromValues(direction[3], direction[4], direction[5]);
10299
+ const scanAxis = gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.fromValues */ .eR.fromValues(direction[6], direction[7], direction[8]);
10300
+ const viewPlaneNormal = gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.negate */ .eR.negate(gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.create */ .eR.create(), scanAxis);
10301
+ const directionVectors = {
10302
+ row: rowCosine,
10303
+ column: columnCosine,
10304
+ normal: viewPlaneNormal,
10305
+ };
10306
+ return _getSphereBoundsInfo(circlePoints, imageData, directionVectors);
10307
+ }
10308
+ function getSphereBoundsInfoFromViewport(circlePoints, imageData, viewport) {
10309
+ if (!viewport) {
10310
+ throw new Error('viewport is required in order to calculate the sphere bounds');
10311
+ }
9688
10312
  const camera = viewport.getCamera();
9689
10313
  const viewUp = gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.fromValues */ .eR.fromValues(camera.viewUp[0], camera.viewUp[1], camera.viewUp[2]);
9690
10314
  const viewPlaneNormal = gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.fromValues */ .eR.fromValues(camera.viewPlaneNormal[0], camera.viewPlaneNormal[1], camera.viewPlaneNormal[2]);
9691
10315
  const viewRight = gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.create */ .eR.create();
9692
10316
  gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.cross */ .eR.cross(viewRight, viewUp, viewPlaneNormal);
10317
+ const directionVectors = {
10318
+ row: viewRight,
10319
+ normal: viewPlaneNormal,
10320
+ column: gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.negate */ .eR.negate(gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.create */ .eR.create(), viewUp),
10321
+ };
10322
+ return _getSphereBoundsInfo(circlePoints, imageData, directionVectors);
10323
+ }
10324
+ function _computeBoundsIJK(imageData, directionVectors, circlePoints, centerWorld, radiusWorld) {
10325
+ const dimensions = imageData.getDimensions();
10326
+ const { row: rowCosine, column: columnCosine, normal: vecNormal, } = directionVectors;
9693
10327
  const topLeftWorld = gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.create */ .eR.create();
9694
10328
  const bottomRightWorld = gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.create */ .eR.create();
9695
- gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.scaleAndAdd */ .eR.scaleAndAdd(topLeftWorld, top, viewPlaneNormal, radiusWorld);
9696
- gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.scaleAndAdd */ .eR.scaleAndAdd(bottomRightWorld, bottom, viewPlaneNormal, -radiusWorld);
9697
- gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.scaleAndAdd */ .eR.scaleAndAdd(topLeftWorld, topLeftWorld, viewRight, -radiusWorld);
9698
- gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.scaleAndAdd */ .eR.scaleAndAdd(bottomRightWorld, bottomRightWorld, viewRight, radiusWorld);
10329
+ gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.scaleAndAdd */ .eR.scaleAndAdd(topLeftWorld, centerWorld, vecNormal, radiusWorld);
10330
+ gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.scaleAndAdd */ .eR.scaleAndAdd(bottomRightWorld, centerWorld, vecNormal, -radiusWorld);
10331
+ gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.scaleAndAdd */ .eR.scaleAndAdd(topLeftWorld, topLeftWorld, columnCosine, -radiusWorld);
10332
+ gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.scaleAndAdd */ .eR.scaleAndAdd(bottomRightWorld, bottomRightWorld, columnCosine, radiusWorld);
10333
+ gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.scaleAndAdd */ .eR.scaleAndAdd(topLeftWorld, topLeftWorld, rowCosine, -radiusWorld);
10334
+ gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.scaleAndAdd */ .eR.scaleAndAdd(bottomRightWorld, bottomRightWorld, rowCosine, radiusWorld);
9699
10335
  const topLeftIJK = transformWorldToIndex(imageData, topLeftWorld);
9700
10336
  const bottomRightIJK = transformWorldToIndex(imageData, bottomRightWorld);
9701
10337
  const pointsIJK = circlePoints.map((p) => transformWorldToIndex(imageData, p));
@@ -10408,7 +11044,9 @@ class BasicStatsCalculator extends basic_Calculator {
10408
11044
  this.runMean.push(0, 0);
10409
11045
  this.m2.push(this.m2[0], this.m2[0]);
10410
11046
  }
10411
- this.pointsInShape?.push(pointLPS);
11047
+ if (this.pointsInShape && pointLPS) {
11048
+ this.pointsInShape?.push(pointLPS);
11049
+ }
10412
11050
  const newArray = Array.isArray(newValue) ? newValue : [newValue];
10413
11051
  this.count += 1;
10414
11052
  this.max.map((it, idx) => {
@@ -12424,6 +13062,10 @@ function filterAnnotationsWithinSlice(annotations, camera, spacingInNormalDirect
12424
13062
  continue;
12425
13063
  }
12426
13064
  const dir = gl_matrix__WEBPACK_IMPORTED_MODULE_0__/* .vec3.create */ .eR.create();
13065
+ if (!point) {
13066
+ annotationsWithinSlice.push(annotation);
13067
+ return;
13068
+ }
12427
13069
  gl_matrix__WEBPACK_IMPORTED_MODULE_0__/* .vec3.sub */ .eR.sub(dir, focalPoint, point);
12428
13070
  const dot = gl_matrix__WEBPACK_IMPORTED_MODULE_0__/* .vec3.dot */ .eR.dot(dir, viewPlaneNormal);
12429
13071
  if (Math.abs(dot) < halfSpacingInNormalDirection) {
@@ -14191,6 +14833,123 @@ function getSliceData(viewport) {
14191
14833
  }
14192
14834
 
14193
14835
 
14836
+ /***/ }),
14837
+
14838
+ /***/ 68915:
14839
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
14840
+
14841
+ "use strict";
14842
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
14843
+ /* harmony export */ A: () => (/* binding */ VolumetricCalculator)
14844
+ /* harmony export */ });
14845
+ /* harmony import */ var _math_basic__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(79362);
14846
+
14847
+ class VolumetricCalculator extends _math_basic__WEBPACK_IMPORTED_MODULE_0__.BasicStatsCalculator {
14848
+ static getStatistics(options) {
14849
+ const { spacing } = options;
14850
+ const stats = _math_basic__WEBPACK_IMPORTED_MODULE_0__.BasicStatsCalculator.getStatistics();
14851
+ const volumeUnit = spacing ? 'mm\xb3' : 'voxels\xb3';
14852
+ const volumeScale = spacing
14853
+ ? spacing[0] * spacing[1] * spacing[2] * 1000
14854
+ : 1;
14855
+ stats.volume = {
14856
+ value: Array.isArray(stats.count.value)
14857
+ ? stats.count.value.map((v) => v * volumeScale)
14858
+ : stats.count.value * volumeScale,
14859
+ unit: volumeUnit,
14860
+ name: 'volume',
14861
+ };
14862
+ stats.array.push(stats.volume);
14863
+ return stats;
14864
+ }
14865
+ }
14866
+
14867
+
14868
+ /***/ }),
14869
+
14870
+ /***/ 2397:
14871
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
14872
+
14873
+ "use strict";
14874
+ __webpack_require__.r(__webpack_exports__);
14875
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
14876
+ /* harmony export */ createLabelmapMemo: () => (/* binding */ createLabelmapMemo),
14877
+ /* harmony export */ createPreviewMemo: () => (/* binding */ createPreviewMemo),
14878
+ /* harmony export */ createRleMemo: () => (/* binding */ createRleMemo),
14879
+ /* harmony export */ restoreMemo: () => (/* binding */ restoreMemo)
14880
+ /* harmony export */ });
14881
+ /* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(81985);
14882
+ /* harmony import */ var _stateManagement_segmentation_triggerSegmentationEvents__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(49906);
14883
+
14884
+
14885
+ const { VoxelManager, RLEVoxelMap } = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__.utilities;
14886
+ function createLabelmapMemo(segmentationId, segmentationVoxelManager, preview) {
14887
+ return preview
14888
+ ? createPreviewMemo(segmentationId, preview)
14889
+ : createRleMemo(segmentationId, segmentationVoxelManager);
14890
+ }
14891
+ function restoreMemo(isUndo) {
14892
+ const { segmentationVoxelManager, undoVoxelManager, redoVoxelManager } = this;
14893
+ const useVoxelManager = isUndo === false ? redoVoxelManager : undoVoxelManager;
14894
+ useVoxelManager.forEach(({ value, pointIJK }) => {
14895
+ segmentationVoxelManager.setAtIJKPoint(pointIJK, value);
14896
+ });
14897
+ const slices = useVoxelManager.getArrayOfModifiedSlices();
14898
+ (0,_stateManagement_segmentation_triggerSegmentationEvents__WEBPACK_IMPORTED_MODULE_1__.triggerSegmentationDataModified)(this.segmentationId, slices);
14899
+ }
14900
+ function createRleMemo(segmentationId, segmentationVoxelManager) {
14901
+ const voxelManager = VoxelManager.createRLEHistoryVoxelManager(segmentationVoxelManager);
14902
+ const state = {
14903
+ segmentationId,
14904
+ restoreMemo,
14905
+ commitMemo,
14906
+ segmentationVoxelManager,
14907
+ voxelManager,
14908
+ };
14909
+ return state;
14910
+ }
14911
+ function createPreviewMemo(segmentationId, preview) {
14912
+ const { memo: previewMemo, segmentationVoxelManager, previewVoxelManager, } = preview;
14913
+ const state = {
14914
+ segmentationId,
14915
+ restoreMemo,
14916
+ commitMemo,
14917
+ segmentationVoxelManager,
14918
+ voxelManager: previewVoxelManager,
14919
+ memo: previewMemo,
14920
+ preview,
14921
+ };
14922
+ return state;
14923
+ }
14924
+ function commitMemo() {
14925
+ if (this.redoVoxelManager) {
14926
+ return true;
14927
+ }
14928
+ if (!this.voxelManager.modifiedSlices.size) {
14929
+ return false;
14930
+ }
14931
+ const { segmentationVoxelManager } = this;
14932
+ const undoVoxelManager = VoxelManager.createRLEHistoryVoxelManager(segmentationVoxelManager);
14933
+ RLEVoxelMap.copyMap(undoVoxelManager.map, this.voxelManager.map);
14934
+ for (const key of this.voxelManager.modifiedSlices.keys()) {
14935
+ undoVoxelManager.modifiedSlices.add(key);
14936
+ }
14937
+ this.undoVoxelManager = undoVoxelManager;
14938
+ const redoVoxelManager = VoxelManager.createRLEVolumeVoxelManager({
14939
+ dimensions: this.segmentationVoxelManager.dimensions,
14940
+ });
14941
+ this.redoVoxelManager = redoVoxelManager;
14942
+ undoVoxelManager.forEach(({ index, pointIJK, value }) => {
14943
+ const currentValue = segmentationVoxelManager.getAtIJKPoint(pointIJK);
14944
+ if (currentValue === value) {
14945
+ return;
14946
+ }
14947
+ redoVoxelManager.setAtIndex(index, currentValue);
14948
+ });
14949
+ return true;
14950
+ }
14951
+
14952
+
14194
14953
  /***/ }),
14195
14954
 
14196
14955
  /***/ 84882:
@@ -14204,20 +14963,20 @@ function floodFill(getter, seed, options = {}) {
14204
14963
  const onFlood = options.onFlood;
14205
14964
  const onBoundary = options.onBoundary;
14206
14965
  const equals = options.equals;
14966
+ const filter = options.filter;
14207
14967
  const diagonals = options.diagonals || false;
14208
14968
  const startNode = get(seed);
14209
14969
  const permutations = prunedPermutations();
14210
14970
  const stack = [];
14211
14971
  const flooded = [];
14212
14972
  const visits = new Set();
14213
- const bounds = new Map();
14973
+ const bounds = options.bounds;
14214
14974
  stack.push({ currentArgs: seed });
14215
14975
  while (stack.length > 0) {
14216
14976
  flood(stack.pop());
14217
14977
  }
14218
14978
  return {
14219
14979
  flooded,
14220
- boundaries: boundaries(),
14221
14980
  };
14222
14981
  function flood(job) {
14223
14982
  const getArgs = job.currentArgs;
@@ -14257,7 +15016,7 @@ function floodFill(getter, seed, options = {}) {
14257
15016
  function markAsBoundary(prevArgs) {
14258
15017
  const [x, y, z = 0] = prevArgs;
14259
15018
  const iKey = x + 32768 + 65536 * (y + 32768 + 65536 * (z + 32768));
14260
- bounds.set(iKey, prevArgs);
15019
+ bounds?.set(iKey, prevArgs);
14261
15020
  if (onBoundary) {
14262
15021
  onBoundary(...prevArgs);
14263
15022
  }
@@ -14269,6 +15028,12 @@ function floodFill(getter, seed, options = {}) {
14269
15028
  for (let j = 0; j < getArgs.length; j += 1) {
14270
15029
  nextArgs[j] += perm[j];
14271
15030
  }
15031
+ if (filter?.(nextArgs) === false) {
15032
+ continue;
15033
+ }
15034
+ if (visited(nextArgs)) {
15035
+ continue;
15036
+ }
14272
15037
  stack.push({
14273
15038
  currentArgs: nextArgs,
14274
15039
  previousArgs: getArgs,
@@ -14298,14 +15063,6 @@ function floodFill(getter, seed, options = {}) {
14298
15063
  }
14299
15064
  return perms;
14300
15065
  }
14301
- function boundaries() {
14302
- const array = Array.from(bounds.values());
14303
- array.reverse();
14304
- return array;
14305
- }
14306
- }
14307
- function defaultEquals(a, b) {
14308
- return a === b;
14309
15066
  }
14310
15067
  function countNonZeroes(array) {
14311
15068
  let count = 0;
@@ -14356,7 +15113,93 @@ function getBrushToolInstances(toolGroupId, toolName) {
14356
15113
 
14357
15114
  /***/ }),
14358
15115
 
14359
- /***/ 67470:
15116
+ /***/ 86644:
15117
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
15118
+
15119
+ "use strict";
15120
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
15121
+ /* harmony export */ u: () => (/* binding */ getSVGStyleForSegment)
15122
+ /* harmony export */ });
15123
+ /* harmony import */ var _enums__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(99737);
15124
+ /* harmony import */ var _stateManagement_segmentation_config_segmentationColor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(93733);
15125
+ /* harmony import */ var _stateManagement_segmentation_getActiveSegmentation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(67165);
15126
+ /* harmony import */ var _stateManagement_segmentation_getActiveSegmentIndex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(60740);
15127
+ /* harmony import */ var _stateManagement_segmentation_getSegmentationRepresentationVisibility__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(33658);
15128
+ /* harmony import */ var _stateManagement_segmentation_helpers_internalGetHiddenSegmentIndices__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(47098);
15129
+ /* harmony import */ var _stateManagement_segmentation_SegmentationStyle__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(92686);
15130
+
15131
+
15132
+
15133
+
15134
+
15135
+
15136
+
15137
+ function getSVGStyleForSegment({ segmentationId, segmentIndex, viewportId, autoGenerated = false, }) {
15138
+ const segmentColor = (0,_stateManagement_segmentation_config_segmentationColor__WEBPACK_IMPORTED_MODULE_1__.getSegmentIndexColor)(viewportId, segmentationId, segmentIndex);
15139
+ const segmentationVisible = (0,_stateManagement_segmentation_getSegmentationRepresentationVisibility__WEBPACK_IMPORTED_MODULE_4__/* .getSegmentationRepresentationVisibility */ .I)(viewportId, {
15140
+ segmentationId,
15141
+ type: _enums__WEBPACK_IMPORTED_MODULE_0__.SegmentationRepresentations.Contour,
15142
+ });
15143
+ const activeSegmentation = (0,_stateManagement_segmentation_getActiveSegmentation__WEBPACK_IMPORTED_MODULE_2__/* .getActiveSegmentation */ .T)(viewportId);
15144
+ const isActive = activeSegmentation?.segmentationId === segmentationId;
15145
+ const style = _stateManagement_segmentation_SegmentationStyle__WEBPACK_IMPORTED_MODULE_6__/* .segmentationStyle */ .Y.getStyle({
15146
+ viewportId,
15147
+ segmentationId,
15148
+ type: _enums__WEBPACK_IMPORTED_MODULE_0__.SegmentationRepresentations.Contour,
15149
+ segmentIndex,
15150
+ });
15151
+ const mergedConfig = style;
15152
+ let lineWidth = 1;
15153
+ let lineDash = undefined;
15154
+ let lineOpacity = 1;
15155
+ let fillOpacity = 0;
15156
+ if (autoGenerated) {
15157
+ lineWidth = mergedConfig.outlineWidthAutoGenerated ?? lineWidth;
15158
+ lineDash = mergedConfig.outlineDashAutoGenerated ?? lineDash;
15159
+ lineOpacity = mergedConfig.outlineOpacity ?? lineOpacity;
15160
+ fillOpacity = mergedConfig.fillAlphaAutoGenerated ?? fillOpacity;
15161
+ }
15162
+ else if (isActive) {
15163
+ lineWidth = mergedConfig.outlineWidth ?? lineWidth;
15164
+ lineDash = mergedConfig.outlineDash ?? lineDash;
15165
+ lineOpacity = mergedConfig.outlineOpacity ?? lineOpacity;
15166
+ fillOpacity = mergedConfig.fillAlpha ?? fillOpacity;
15167
+ }
15168
+ else {
15169
+ lineWidth = mergedConfig.outlineWidthInactive ?? lineWidth;
15170
+ lineDash = mergedConfig.outlineDashInactive ?? lineDash;
15171
+ lineOpacity = mergedConfig.outlineOpacityInactive ?? lineOpacity;
15172
+ fillOpacity = mergedConfig.fillAlphaInactive ?? fillOpacity;
15173
+ }
15174
+ if ((0,_stateManagement_segmentation_getActiveSegmentIndex__WEBPACK_IMPORTED_MODULE_3__/* .getActiveSegmentIndex */ .Q)(segmentationId) === segmentIndex) {
15175
+ lineWidth += mergedConfig.activeSegmentOutlineWidthDelta;
15176
+ }
15177
+ lineWidth = mergedConfig.renderOutline ? lineWidth : 0;
15178
+ fillOpacity = mergedConfig.renderFill ? fillOpacity : 0;
15179
+ const color = `rgba(${segmentColor[0]}, ${segmentColor[1]}, ${segmentColor[2]}, ${lineOpacity})`;
15180
+ const fillColor = `rgb(${segmentColor[0]}, ${segmentColor[1]}, ${segmentColor[2]})`;
15181
+ const hiddenSegments = (0,_stateManagement_segmentation_helpers_internalGetHiddenSegmentIndices__WEBPACK_IMPORTED_MODULE_5__/* .internalGetHiddenSegmentIndices */ .s)(viewportId, {
15182
+ segmentationId,
15183
+ type: _enums__WEBPACK_IMPORTED_MODULE_0__.SegmentationRepresentations.Contour,
15184
+ });
15185
+ const isVisible = !hiddenSegments.has(segmentIndex);
15186
+ return {
15187
+ color,
15188
+ fillColor,
15189
+ lineWidth,
15190
+ fillOpacity,
15191
+ lineDash,
15192
+ textbox: {
15193
+ color,
15194
+ },
15195
+ visibility: segmentationVisible && isVisible,
15196
+ };
15197
+ }
15198
+
15199
+
15200
+ /***/ }),
15201
+
15202
+ /***/ 26971:
14360
15203
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
14361
15204
 
14362
15205
  "use strict";
@@ -14365,6 +15208,8 @@ __webpack_require__.r(__webpack_exports__);
14365
15208
 
14366
15209
  // EXPORTS
14367
15210
  __webpack_require__.d(__webpack_exports__, {
15211
+ LabelmapMemo: () => (/* reexport */ createLabelmapMemo),
15212
+ VolumetricCalculator: () => (/* reexport */ VolumetricCalculator/* default */.A),
14368
15213
  contourAndFindLargestBidirectional: () => (/* reexport */ contourAndFindLargestBidirectional),
14369
15214
  createBidirectionalToolData: () => (/* reexport */ createBidirectionalToolData),
14370
15215
  createLabelmapVolumeForViewport: () => (/* reexport */ createLabelmapVolumeForViewport),
@@ -14377,6 +15222,7 @@ __webpack_require__.d(__webpack_exports__, {
14377
15222
  getSegmentIndexAtLabelmapBorder: () => (/* reexport */ getSegmentIndexAtLabelmapBorder),
14378
15223
  getSegmentIndexAtWorldPoint: () => (/* reexport */ getSegmentIndexAtWorldPoint),
14379
15224
  getUniqueSegmentIndices: () => (/* reexport */ getUniqueSegmentIndices/* getUniqueSegmentIndices */.O),
15225
+ growCut: () => (/* reexport */ growCut_namespaceObject),
14380
15226
  invalidateBrushCursor: () => (/* reexport */ invalidateBrushCursor/* invalidateBrushCursor */.E),
14381
15227
  rectangleROIThresholdVolumeByRange: () => (/* reexport */ segmentation_rectangleROIThresholdVolumeByRange),
14382
15228
  segmentContourAction: () => (/* reexport */ segmentContourAction),
@@ -14388,6 +15234,16 @@ __webpack_require__.d(__webpack_exports__, {
14388
15234
  triggerSegmentationRenderBySegmentationId: () => (/* reexport */ SegmentationRenderingEngine/* triggerSegmentationRenderBySegmentationId */.fy)
14389
15235
  });
14390
15236
 
15237
+ // NAMESPACE OBJECT: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/growCut/index.js
15238
+ var growCut_namespaceObject = {};
15239
+ __webpack_require__.r(growCut_namespaceObject);
15240
+ __webpack_require__.d(growCut_namespaceObject, {
15241
+ run: () => (runGrowCut),
15242
+ runGrowCutForBoundingBox: () => (runGrowCutForBoundingBox),
15243
+ runGrowCutForSphere: () => (runGrowCutForSphere),
15244
+ runOneClickGrowCut: () => (runOneClickGrowCut)
15245
+ });
15246
+
14391
15247
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/triggerSegmentationEvents.js
14392
15248
  var triggerSegmentationEvents = __webpack_require__(49906);
14393
15249
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/utilities.js
@@ -14579,7 +15435,7 @@ async function createLabelmapVolumeForViewport(input) {
14579
15435
  }
14580
15436
  else {
14581
15437
  const volumeId = viewport.getVolumeId();
14582
- await esm.volumeLoader.createAndCacheDerivedLabelmapVolume(volumeId, {
15438
+ esm.volumeLoader.createAndCacheDerivedLabelmapVolume(volumeId, {
14583
15439
  volumeId: segmentationId,
14584
15440
  });
14585
15441
  }
@@ -14686,6 +15542,8 @@ function getBrushThresholdForToolGroup(toolGroupId) {
14686
15542
  .threshold;
14687
15543
  }
14688
15544
 
15545
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/VolumetricCalculator.js
15546
+ var VolumetricCalculator = __webpack_require__(68915);
14689
15547
  ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/thresholdSegmentationByRange.js
14690
15548
 
14691
15549
 
@@ -15071,8 +15929,8 @@ var invalidateBrushCursor = __webpack_require__(35706);
15071
15929
  var getUniqueSegmentIndices = __webpack_require__(25758);
15072
15930
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/enums/index.js + 2 modules
15073
15931
  var enums = __webpack_require__(99737);
15074
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/segmentationState.js + 2 modules
15075
- var segmentationState = __webpack_require__(98870);
15932
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/segmentationState.js + 1 modules
15933
+ var segmentationState = __webpack_require__(83243);
15076
15934
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/index.js
15077
15935
  var stateManagement = __webpack_require__(6802);
15078
15936
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/math/polyline/index.js
@@ -15250,6 +16108,851 @@ function getHoveredContourSegmentationAnnotation(segmentationId) {
15250
16108
  return undefined;
15251
16109
  }
15252
16110
 
16111
+ ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/growCut/growCutShader.js
16112
+ const shader = `
16113
+ const MAX_STRENGTH = 65535f;
16114
+
16115
+ // Workgroup soze - X*Y*Z must be multiple of 32 for better performance
16116
+ // otherwise warps are sub allocated and some threads will not process anything
16117
+ override workGroupSizeX = 1u;
16118
+ override workGroupSizeY = 1u;
16119
+ override workGroupSizeZ = 1u;
16120
+
16121
+ // Compare the current voxel to neighbors using a 9x9x9 window
16122
+ override windowSize = 9i;
16123
+
16124
+ struct Params {
16125
+ size: vec3u,
16126
+ iteration: u32,
16127
+ }
16128
+
16129
+ @group(0) @binding(0) var<uniform> params: Params;
16130
+ @group(0) @binding(1) var<storage> volumePixelData: array<f32>;
16131
+ @group(0) @binding(2) var<storage, read_write> labelmap: array<u32>;
16132
+ @group(0) @binding(3) var<storage, read_write> strengthData: array<f32>;
16133
+ @group(0) @binding(4) var<storage> prevLabelmap: array<u32>;
16134
+ @group(0) @binding(5) var<storage> prevStrengthData: array<f32>;
16135
+ @group(0) @binding(6) var<storage, read_write> updatedVoxelsCounter: array<atomic<u32>>;
16136
+
16137
+ fn getPixelIndex(ijkPos: vec3u) -> u32 {
16138
+ let numPixelsPerSlice = params.size.x * params.size.y;
16139
+ return ijkPos.x + ijkPos.y * params.size.x + ijkPos.z * numPixelsPerSlice;
16140
+ }
16141
+
16142
+ @compute @workgroup_size(workGroupSizeX, workGroupSizeY, workGroupSizeZ)
16143
+ fn main(
16144
+ @builtin(global_invocation_id) globalId: vec3u,
16145
+ ) {
16146
+ // Make sure it will not get out of bounds for volume with sizes that
16147
+ // are not multiple of workGroupSize
16148
+ if (
16149
+ globalId.x >= params.size.x ||
16150
+ globalId.y >= params.size.y ||
16151
+ globalId.z >= params.size.z
16152
+ ) {
16153
+ return;
16154
+ }
16155
+
16156
+ let currentCoord = vec3i(globalId);
16157
+ let currentPixelIndex = getPixelIndex(globalId);
16158
+
16159
+ let numPixels = arrayLength(&volumePixelData);
16160
+ let currentPixelValue = volumePixelData[currentPixelIndex];
16161
+
16162
+ if (params.iteration == 0) {
16163
+ // All non-zero initial labels are given maximum strength
16164
+ strengthData[currentPixelIndex] = select(MAX_STRENGTH, 0., labelmap[currentPixelIndex] == 0);
16165
+ return;
16166
+ }
16167
+
16168
+ // It should at least copy the values from previous state
16169
+ var newLabel = prevLabelmap[currentPixelIndex];
16170
+ var newStrength = prevStrengthData[currentPixelIndex];
16171
+
16172
+ let window = i32(ceil(f32(windowSize - 1) * .5));
16173
+ let minWindow = -1i * window;
16174
+ let maxWindow = 1i * window;
16175
+
16176
+ for (var k = minWindow; k <= maxWindow; k++) {
16177
+ for (var j = minWindow; j <= maxWindow; j++) {
16178
+ for (var i = minWindow; i <= maxWindow; i++) {
16179
+ // Skip current voxel
16180
+ if (i == 0 && j == 0 && k == 0) {
16181
+ continue;
16182
+ }
16183
+
16184
+ let neighborCoord = currentCoord + vec3i(i, j, k);
16185
+
16186
+ // Boundary conditions. Do not grow outside of the volume
16187
+ if (
16188
+ neighborCoord.x < 0i || neighborCoord.x >= i32(params.size.x) ||
16189
+ neighborCoord.y < 0i || neighborCoord.y >= i32(params.size.y) ||
16190
+ neighborCoord.z < 0i || neighborCoord.z >= i32(params.size.z)
16191
+ ) {
16192
+ continue;
16193
+ }
16194
+
16195
+ let neighborIndex = getPixelIndex(vec3u(neighborCoord));
16196
+ let neighborPixelValue = volumePixelData[neighborIndex];
16197
+ let prevNeighborStrength = prevStrengthData[neighborIndex];
16198
+ let strengthCost = abs(neighborPixelValue - currentPixelValue);
16199
+ let takeoverStrength = prevNeighborStrength - strengthCost;
16200
+
16201
+ if (takeoverStrength > newStrength) {
16202
+ newLabel = prevLabelmap[neighborIndex];
16203
+ newStrength = takeoverStrength;
16204
+ }
16205
+ }
16206
+ }
16207
+ }
16208
+
16209
+ if (labelmap[currentPixelIndex] != newLabel) {
16210
+ atomicAdd(&updatedVoxelsCounter[params.iteration], 1u);
16211
+ }
16212
+
16213
+ labelmap[currentPixelIndex] = newLabel;
16214
+ strengthData[currentPixelIndex] = newStrength;
16215
+ }
16216
+ `;
16217
+ /* harmony default export */ const growCutShader = (shader);
16218
+
16219
+ ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/growCut/runGrowCut.js
16220
+
16221
+
16222
+ const GB = 1024 * 1024 * 1024;
16223
+ const WEBGPU_MEMORY_LIMIT = 1.99 * GB;
16224
+ const DEFAULT_GROWCUT_OPTIONS = {
16225
+ windowSize: 3,
16226
+ maxProcessingTime: 30000,
16227
+ inspection: {
16228
+ numCyclesInterval: 5,
16229
+ numCyclesBelowThreshold: 3,
16230
+ threshold: 1e-4,
16231
+ },
16232
+ };
16233
+ async function runGrowCut(referenceVolumeId, labelmapVolumeId, options = DEFAULT_GROWCUT_OPTIONS) {
16234
+ const workGroupSize = [8, 8, 4];
16235
+ const { windowSize, maxProcessingTime } = Object.assign({}, DEFAULT_GROWCUT_OPTIONS, options);
16236
+ const inspection = Object.assign({}, DEFAULT_GROWCUT_OPTIONS.inspection, options.inspection);
16237
+ const volume = esm.cache.getVolume(referenceVolumeId);
16238
+ const labelmap = esm.cache.getVolume(labelmapVolumeId);
16239
+ const [columns, rows, numSlices] = volume.dimensions;
16240
+ if (labelmap.dimensions[0] !== columns ||
16241
+ labelmap.dimensions[1] !== rows ||
16242
+ labelmap.dimensions[2] !== numSlices) {
16243
+ throw new Error('Volume and labelmap must have the same size');
16244
+ }
16245
+ const numIterations = Math.floor(Math.sqrt(rows ** 2 + columns ** 2 + numSlices ** 2) / 2);
16246
+ const labelmapData = labelmap.voxelManager.getCompleteScalarDataArray();
16247
+ let volumePixelData = volume.voxelManager.getCompleteScalarDataArray();
16248
+ if (!(volumePixelData instanceof Float32Array)) {
16249
+ volumePixelData = new Float32Array(volumePixelData);
16250
+ }
16251
+ const requiredLimits = {
16252
+ maxStorageBufferBindingSize: WEBGPU_MEMORY_LIMIT,
16253
+ maxBufferSize: WEBGPU_MEMORY_LIMIT,
16254
+ };
16255
+ const adapter = await navigator.gpu?.requestAdapter();
16256
+ const device = await adapter.requestDevice({ requiredLimits });
16257
+ const BUFFER_SIZE = volumePixelData.byteLength;
16258
+ const UPDATED_VOXELS_COUNTER_BUFFER_SIZE = numIterations * Uint32Array.BYTES_PER_ELEMENT;
16259
+ const shaderModule = device.createShaderModule({
16260
+ code: growCutShader,
16261
+ });
16262
+ const numIterationIndex = 3;
16263
+ const paramsArrayValues = new Uint32Array([
16264
+ columns,
16265
+ rows,
16266
+ numSlices,
16267
+ 0,
16268
+ ]);
16269
+ const gpuParamsBuffer = device.createBuffer({
16270
+ size: paramsArrayValues.byteLength,
16271
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
16272
+ });
16273
+ const gpuVolumePixelDataBuffer = device.createBuffer({
16274
+ size: BUFFER_SIZE,
16275
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
16276
+ });
16277
+ device.queue.writeBuffer(gpuVolumePixelDataBuffer, 0, volumePixelData);
16278
+ const gpuLabelmapBuffers = [0, 1].map(() => device.createBuffer({
16279
+ size: BUFFER_SIZE,
16280
+ usage: GPUBufferUsage.STORAGE |
16281
+ GPUBufferUsage.COPY_SRC |
16282
+ GPUBufferUsage.COPY_DST,
16283
+ }));
16284
+ device.queue.writeBuffer(gpuLabelmapBuffers[0], 0, new Uint32Array(labelmapData));
16285
+ const gpuStrengthBuffers = [0, 1].map(() => {
16286
+ const strengthBuffer = device.createBuffer({
16287
+ size: BUFFER_SIZE,
16288
+ usage: GPUBufferUsage.STORAGE |
16289
+ GPUBufferUsage.COPY_SRC |
16290
+ GPUBufferUsage.COPY_DST,
16291
+ });
16292
+ return strengthBuffer;
16293
+ });
16294
+ const gpuCounterBuffer = device.createBuffer({
16295
+ size: UPDATED_VOXELS_COUNTER_BUFFER_SIZE,
16296
+ usage: GPUBufferUsage.STORAGE |
16297
+ GPUBufferUsage.COPY_SRC |
16298
+ GPUBufferUsage.COPY_DST,
16299
+ });
16300
+ const bindGroupLayout = device.createBindGroupLayout({
16301
+ entries: [
16302
+ {
16303
+ binding: 0,
16304
+ visibility: GPUShaderStage.COMPUTE,
16305
+ buffer: {
16306
+ type: 'uniform',
16307
+ },
16308
+ },
16309
+ {
16310
+ binding: 1,
16311
+ visibility: GPUShaderStage.COMPUTE,
16312
+ buffer: {
16313
+ type: 'read-only-storage',
16314
+ },
16315
+ },
16316
+ {
16317
+ binding: 2,
16318
+ visibility: GPUShaderStage.COMPUTE,
16319
+ buffer: {
16320
+ type: 'storage',
16321
+ },
16322
+ },
16323
+ {
16324
+ binding: 3,
16325
+ visibility: GPUShaderStage.COMPUTE,
16326
+ buffer: {
16327
+ type: 'storage',
16328
+ },
16329
+ },
16330
+ {
16331
+ binding: 4,
16332
+ visibility: GPUShaderStage.COMPUTE,
16333
+ buffer: {
16334
+ type: 'read-only-storage',
16335
+ },
16336
+ },
16337
+ {
16338
+ binding: 5,
16339
+ visibility: GPUShaderStage.COMPUTE,
16340
+ buffer: {
16341
+ type: 'read-only-storage',
16342
+ },
16343
+ },
16344
+ {
16345
+ binding: 6,
16346
+ visibility: GPUShaderStage.COMPUTE,
16347
+ buffer: {
16348
+ type: 'storage',
16349
+ },
16350
+ },
16351
+ ],
16352
+ });
16353
+ const bindGroups = [0, 1].map((i) => {
16354
+ const outputLabelmapBuffer = gpuLabelmapBuffers[i];
16355
+ const outputStrengthBuffer = gpuStrengthBuffers[i];
16356
+ const previouLabelmapBuffer = gpuLabelmapBuffers[(i + 1) % 2];
16357
+ const previousStrengthBuffer = gpuStrengthBuffers[(i + 1) % 2];
16358
+ return device.createBindGroup({
16359
+ layout: bindGroupLayout,
16360
+ entries: [
16361
+ {
16362
+ binding: 0,
16363
+ resource: {
16364
+ buffer: gpuParamsBuffer,
16365
+ },
16366
+ },
16367
+ {
16368
+ binding: 1,
16369
+ resource: {
16370
+ buffer: gpuVolumePixelDataBuffer,
16371
+ },
16372
+ },
16373
+ {
16374
+ binding: 2,
16375
+ resource: {
16376
+ buffer: outputLabelmapBuffer,
16377
+ },
16378
+ },
16379
+ {
16380
+ binding: 3,
16381
+ resource: {
16382
+ buffer: outputStrengthBuffer,
16383
+ },
16384
+ },
16385
+ {
16386
+ binding: 4,
16387
+ resource: {
16388
+ buffer: previouLabelmapBuffer,
16389
+ },
16390
+ },
16391
+ {
16392
+ binding: 5,
16393
+ resource: {
16394
+ buffer: previousStrengthBuffer,
16395
+ },
16396
+ },
16397
+ {
16398
+ binding: 6,
16399
+ resource: {
16400
+ buffer: gpuCounterBuffer,
16401
+ },
16402
+ },
16403
+ ],
16404
+ });
16405
+ });
16406
+ const pipeline = device.createComputePipeline({
16407
+ layout: device.createPipelineLayout({
16408
+ bindGroupLayouts: [bindGroupLayout],
16409
+ }),
16410
+ compute: {
16411
+ module: shaderModule,
16412
+ entryPoint: 'main',
16413
+ constants: {
16414
+ workGroupSizeX: workGroupSize[0],
16415
+ workGroupSizeY: workGroupSize[1],
16416
+ workGroupSizeZ: workGroupSize[2],
16417
+ windowSize,
16418
+ },
16419
+ },
16420
+ });
16421
+ const numWorkGroups = [
16422
+ Math.ceil(columns / workGroupSize[0]),
16423
+ Math.ceil(rows / workGroupSize[1]),
16424
+ Math.ceil(numSlices / workGroupSize[2]),
16425
+ ];
16426
+ const gpuUpdatedVoxelsCounterStagingBuffer = device.createBuffer({
16427
+ size: UPDATED_VOXELS_COUNTER_BUFFER_SIZE,
16428
+ usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,
16429
+ });
16430
+ const labelmapStagingBufferTemp = device.createBuffer({
16431
+ size: BUFFER_SIZE,
16432
+ usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,
16433
+ });
16434
+ const limitProcessingTime = maxProcessingTime
16435
+ ? performance.now() + maxProcessingTime
16436
+ : 0;
16437
+ let currentInspectionNumCyclesInterval = inspection.numCyclesInterval;
16438
+ let belowThresholdCounter = 0;
16439
+ for (let i = 0; i < numIterations; i++) {
16440
+ paramsArrayValues[numIterationIndex] = i;
16441
+ device.queue.writeBuffer(gpuParamsBuffer, 0, paramsArrayValues);
16442
+ const commandEncoder = device.createCommandEncoder();
16443
+ const passEncoder = commandEncoder.beginComputePass();
16444
+ passEncoder.setPipeline(pipeline);
16445
+ passEncoder.setBindGroup(0, bindGroups[i % 2]);
16446
+ passEncoder.dispatchWorkgroups(numWorkGroups[0], numWorkGroups[1], numWorkGroups[2]);
16447
+ passEncoder.end();
16448
+ commandEncoder.copyBufferToBuffer(gpuCounterBuffer, i * Uint32Array.BYTES_PER_ELEMENT, gpuUpdatedVoxelsCounterStagingBuffer, i * Uint32Array.BYTES_PER_ELEMENT, Uint32Array.BYTES_PER_ELEMENT);
16449
+ device.queue.submit([commandEncoder.finish()]);
16450
+ const inspect = i > 0 && !(i % currentInspectionNumCyclesInterval);
16451
+ if (inspect) {
16452
+ await gpuUpdatedVoxelsCounterStagingBuffer.mapAsync(GPUMapMode.READ, 0, UPDATED_VOXELS_COUNTER_BUFFER_SIZE);
16453
+ const updatedVoxelsCounterResultBuffer = gpuUpdatedVoxelsCounterStagingBuffer.getMappedRange(0, UPDATED_VOXELS_COUNTER_BUFFER_SIZE);
16454
+ const updatedVoxelsCounterBufferData = new Uint32Array(updatedVoxelsCounterResultBuffer.slice(0));
16455
+ const updatedVoxelsRatio = updatedVoxelsCounterBufferData[i] / volumePixelData.length;
16456
+ gpuUpdatedVoxelsCounterStagingBuffer.unmap();
16457
+ if (i >= 1 && updatedVoxelsRatio < inspection.threshold) {
16458
+ currentInspectionNumCyclesInterval = 1;
16459
+ belowThresholdCounter++;
16460
+ if (belowThresholdCounter === inspection.numCyclesBelowThreshold) {
16461
+ break;
16462
+ }
16463
+ }
16464
+ else {
16465
+ currentInspectionNumCyclesInterval = inspection.numCyclesInterval;
16466
+ }
16467
+ }
16468
+ if (limitProcessingTime && performance.now() > limitProcessingTime) {
16469
+ console.warn(`Exceeded processing time limit (${maxProcessingTime})ms`);
16470
+ break;
16471
+ }
16472
+ }
16473
+ const commandEncoder = device.createCommandEncoder();
16474
+ const outputLabelmapBufferIndex = (numIterations + 1) % 2;
16475
+ const labelmapStagingBuffer = device.createBuffer({
16476
+ size: BUFFER_SIZE,
16477
+ usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,
16478
+ });
16479
+ commandEncoder.copyBufferToBuffer(gpuLabelmapBuffers[outputLabelmapBufferIndex], 0, labelmapStagingBuffer, 0, BUFFER_SIZE);
16480
+ device.queue.submit([commandEncoder.finish()]);
16481
+ await labelmapStagingBuffer.mapAsync(GPUMapMode.READ, 0, BUFFER_SIZE);
16482
+ const labelmapResultBuffer = labelmapStagingBuffer.getMappedRange(0, BUFFER_SIZE);
16483
+ const labelmapResult = new Uint32Array(labelmapResultBuffer);
16484
+ labelmapData.set(labelmapResult);
16485
+ labelmapStagingBuffer.unmap();
16486
+ labelmap.voxelManager.setCompleteScalarDataArray(labelmapData);
16487
+ }
16488
+
16489
+
16490
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/getSphereBoundsInfo.js
16491
+ var getSphereBoundsInfo = __webpack_require__(4296);
16492
+ ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/growCut/runGrowCutForSphere.js
16493
+
16494
+
16495
+
16496
+
16497
+ const { transformWorldToIndex } = esm.utilities;
16498
+ const POSITIVE_SEED_VALUE = 254;
16499
+ const NEGATIVE_SEED_VALUE = 255;
16500
+ const POSITIVE_SEED_VARIANCE = 0.1;
16501
+ const NEGATIVE_SEED_VARIANCE = 0.8;
16502
+ function _getGrowCutSphereBoundsInfo(referencedVolume, sphereBoundsInfo) {
16503
+ const { topLeftWorld, bottomRightWorld } = sphereBoundsInfo;
16504
+ const topLeftIJK = transformWorldToIndex(referencedVolume.imageData, topLeftWorld);
16505
+ const bottomRightIJK = transformWorldToIndex(referencedVolume.imageData, bottomRightWorld);
16506
+ return {
16507
+ ...sphereBoundsInfo,
16508
+ topLeftIJK,
16509
+ bottomRightIJK,
16510
+ };
16511
+ }
16512
+ function _getSphereBoundsInfo(referencedVolume, sphereInfo) {
16513
+ const direction = referencedVolume.imageData.getDirection();
16514
+ const vecColumn = gl_matrix_esm/* vec3.fromValues */.eR.fromValues(direction[3], direction[4], direction[5]);
16515
+ const { center: sphereCenterPoint, radius: sphereRadius } = sphereInfo;
16516
+ const refVolImageData = referencedVolume.imageData;
16517
+ const topCirclePoint = gl_matrix_esm/* vec3.scaleAndAdd */.eR.scaleAndAdd(gl_matrix_esm/* vec3.create */.eR.create(), sphereCenterPoint, vecColumn, -sphereRadius);
16518
+ const bottomCirclePoint = gl_matrix_esm/* vec3.scaleAndAdd */.eR.scaleAndAdd(gl_matrix_esm/* vec3.create */.eR.create(), sphereCenterPoint, vecColumn, sphereRadius);
16519
+ const sphereBoundsInfo = (0,getSphereBoundsInfo/* getSphereBoundsInfo */.R)([bottomCirclePoint, topCirclePoint], refVolImageData);
16520
+ return _getGrowCutSphereBoundsInfo(referencedVolume, sphereBoundsInfo);
16521
+ }
16522
+ function _createSubVolumeFromSphere(referencedVolume, sphereInfo, viewport) {
16523
+ const refVolImageData = referencedVolume.imageData;
16524
+ const camera = viewport.getCamera();
16525
+ const { ijkVecRowDir, ijkVecColDir } = esm.utilities.getVolumeDirectionVectors(refVolImageData, camera);
16526
+ const obliqueView = [ijkVecRowDir, ijkVecColDir].some((vec) => !esm.utilities.isEqual(Math.abs(vec[0]), 1) &&
16527
+ !esm.utilities.isEqual(Math.abs(vec[1]), 1) &&
16528
+ !esm.utilities.isEqual(Math.abs(vec[2]), 1));
16529
+ if (obliqueView) {
16530
+ console.warn('Oblique view is not supported!');
16531
+ return;
16532
+ }
16533
+ const { boundsIJK: sphereBoundsIJK } = _getSphereBoundsInfo(referencedVolume, sphereInfo);
16534
+ const subVolumeBoundsIJK = {
16535
+ minX: sphereBoundsIJK[0][0],
16536
+ maxX: sphereBoundsIJK[0][1] + 1,
16537
+ minY: sphereBoundsIJK[1][0],
16538
+ maxY: sphereBoundsIJK[1][1] + 1,
16539
+ minZ: sphereBoundsIJK[2][0],
16540
+ maxZ: sphereBoundsIJK[2][1] + 1,
16541
+ };
16542
+ return esm.utilities.createSubVolume(referencedVolume.volumeId, subVolumeBoundsIJK, {
16543
+ targetBuffer: {
16544
+ type: 'Float32Array',
16545
+ },
16546
+ });
16547
+ }
16548
+ function _setPositiveSeedValues(referencedVolume, labelmap, sphereInfo, options) {
16549
+ const refVolumePixelData = referencedVolume.voxelManager.getCompleteScalarDataArray();
16550
+ const worldStartPos = sphereInfo.center;
16551
+ const [width, height, numSlices] = referencedVolume.dimensions;
16552
+ const numPixelsPerSlice = width * height;
16553
+ const ijkStartPosition = transformWorldToIndex(referencedVolume.imageData, worldStartPos);
16554
+ const referencePixelValue = refVolumePixelData[ijkStartPosition[2] * numPixelsPerSlice +
16555
+ ijkStartPosition[1] * width +
16556
+ ijkStartPosition[0]];
16557
+ const positiveSeedValue = options.positiveSeedValue ?? POSITIVE_SEED_VALUE;
16558
+ const positiveSeedVariance = options.positiveSeedVariance ?? POSITIVE_SEED_VARIANCE;
16559
+ const positiveSeedVarianceValue = Math.abs(referencePixelValue * positiveSeedVariance);
16560
+ const minPositivePixelValue = referencePixelValue - positiveSeedVarianceValue;
16561
+ const maxPositivePixelValue = referencePixelValue + positiveSeedVarianceValue;
16562
+ const neighborsCoordDelta = [
16563
+ [-1, 0, 0],
16564
+ [1, 0, 0],
16565
+ [0, -1, 0],
16566
+ [0, 1, 0],
16567
+ [0, 0, -1],
16568
+ [0, 0, 1],
16569
+ ];
16570
+ const startVoxelIndex = ijkStartPosition[2] * numPixelsPerSlice +
16571
+ ijkStartPosition[1] * width +
16572
+ ijkStartPosition[0];
16573
+ labelmap.voxelManager.setAtIndex(startVoxelIndex, positiveSeedValue);
16574
+ const queue = [ijkStartPosition];
16575
+ while (queue.length) {
16576
+ const ijkVoxel = queue.shift();
16577
+ const [x, y, z] = ijkVoxel;
16578
+ for (let i = 0, len = neighborsCoordDelta.length; i < len; i++) {
16579
+ const neighborCoordDelta = neighborsCoordDelta[i];
16580
+ const nx = x + neighborCoordDelta[0];
16581
+ const ny = y + neighborCoordDelta[1];
16582
+ const nz = z + neighborCoordDelta[2];
16583
+ if (nx < 0 ||
16584
+ nx >= width ||
16585
+ ny < 0 ||
16586
+ ny >= height ||
16587
+ nz < 0 ||
16588
+ nz >= numSlices) {
16589
+ continue;
16590
+ }
16591
+ const neighborVoxelIndex = nz * numPixelsPerSlice + ny * width + nx;
16592
+ const neighborPixelValue = refVolumePixelData[neighborVoxelIndex];
16593
+ const neighborLabelmapValue = labelmap.voxelManager.getAtIndex(neighborVoxelIndex);
16594
+ if (neighborLabelmapValue === positiveSeedValue ||
16595
+ neighborPixelValue < minPositivePixelValue ||
16596
+ neighborPixelValue > maxPositivePixelValue) {
16597
+ continue;
16598
+ }
16599
+ labelmap.voxelManager.setAtIndex(neighborVoxelIndex, positiveSeedValue);
16600
+ queue.push([nx, ny, nz]);
16601
+ }
16602
+ }
16603
+ }
16604
+ function _setNegativeSeedValues(subVolume, labelmap, sphereInfo, viewport, options) {
16605
+ const subVolPixelData = subVolume.voxelManager.getCompleteScalarDataArray();
16606
+ const [columns, rows, numSlices] = labelmap.dimensions;
16607
+ const numPixelsPerSlice = columns * rows;
16608
+ const { worldVecRowDir, worldVecSliceDir } = esm.utilities.getVolumeDirectionVectors(labelmap.imageData, viewport.getCamera());
16609
+ const ijkSphereCenter = transformWorldToIndex(subVolume.imageData, sphereInfo.center);
16610
+ const referencePixelValue = subVolPixelData[ijkSphereCenter[2] * columns * rows +
16611
+ ijkSphereCenter[1] * columns +
16612
+ ijkSphereCenter[0]];
16613
+ const negativeSeedVariance = options.negativeSeedVariance ?? NEGATIVE_SEED_VARIANCE;
16614
+ const negativeSeedValue = options?.negativeSeedValue ?? NEGATIVE_SEED_VALUE;
16615
+ const negativeSeedVarianceValue = Math.abs(referencePixelValue * negativeSeedVariance);
16616
+ const minNegativePixelValue = referencePixelValue - negativeSeedVarianceValue;
16617
+ const maxNegativePixelValue = referencePixelValue + negativeSeedVarianceValue;
16618
+ const numCirclePoints = 360;
16619
+ const rotationAngle = (2 * Math.PI) / numCirclePoints;
16620
+ const worldQuat = gl_matrix_esm/* quat.setAxisAngle */.Yu.setAxisAngle(gl_matrix_esm/* quat.create */.Yu.create(), worldVecSliceDir, rotationAngle);
16621
+ const vecRotation = gl_matrix_esm/* vec3.clone */.eR.clone(worldVecRowDir);
16622
+ for (let i = 0; i < numCirclePoints; i++) {
16623
+ const worldCircleBorderPoint = gl_matrix_esm/* vec3.scaleAndAdd */.eR.scaleAndAdd(gl_matrix_esm/* vec3.create */.eR.create(), sphereInfo.center, vecRotation, sphereInfo.radius);
16624
+ const ijkCircleBorderPoint = transformWorldToIndex(labelmap.imageData, worldCircleBorderPoint);
16625
+ const [x, y, z] = ijkCircleBorderPoint;
16626
+ gl_matrix_esm/* vec3.transformQuat */.eR.transformQuat(vecRotation, vecRotation, worldQuat);
16627
+ if (x < 0 ||
16628
+ x >= columns ||
16629
+ y < 0 ||
16630
+ y >= rows ||
16631
+ z < 0 ||
16632
+ z >= numSlices) {
16633
+ continue;
16634
+ }
16635
+ const offset = x + y * columns + z * numPixelsPerSlice;
16636
+ const pixelValue = subVolPixelData[offset];
16637
+ if (pixelValue < minNegativePixelValue ||
16638
+ pixelValue > maxNegativePixelValue) {
16639
+ labelmap.voxelManager.setAtIndex(offset, negativeSeedValue);
16640
+ }
16641
+ }
16642
+ }
16643
+ async function _createAndCacheSegmentationSubVolumeForSphere(subVolume, sphereInfo, viewport, options) {
16644
+ const labelmap = await esm.volumeLoader.createAndCacheDerivedLabelmapVolume(subVolume.volumeId);
16645
+ _setPositiveSeedValues(subVolume, labelmap, sphereInfo, options);
16646
+ _setNegativeSeedValues(subVolume, labelmap, sphereInfo, viewport, options);
16647
+ return labelmap;
16648
+ }
16649
+ async function runGrowCutForSphere(referencedVolumeId, sphereInfo, viewport, options) {
16650
+ const referencedVolume = esm.cache.getVolume(referencedVolumeId);
16651
+ const subVolume = _createSubVolumeFromSphere(referencedVolume, sphereInfo, viewport);
16652
+ const labelmap = await _createAndCacheSegmentationSubVolumeForSphere(subVolume, sphereInfo, viewport, options);
16653
+ await runGrowCut(subVolume.volumeId, labelmap.volumeId);
16654
+ return labelmap;
16655
+ }
16656
+
16657
+
16658
+ ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/growCut/runGrowCutForBoundingBox.js
16659
+
16660
+
16661
+ const runGrowCutForBoundingBox_POSITIVE_SEED_VALUE = 254;
16662
+ const runGrowCutForBoundingBox_NEGATIVE_SEED_VALUE = 255;
16663
+ const NEGATIVE_PIXEL_RANGE = [-Infinity, -995];
16664
+ const POSITIVE_PIXEL_RANGE = [0, 1900];
16665
+ function runGrowCutForBoundingBox_setNegativeSeedValues(subVolume, labelmap, options) {
16666
+ const { negativeSeedValue = runGrowCutForBoundingBox_NEGATIVE_SEED_VALUE, negativePixelRange = NEGATIVE_PIXEL_RANGE, } = options;
16667
+ const subVolPixelData = subVolume.voxelManager.getCompleteScalarDataArray();
16668
+ const [width, height, numSlices] = labelmap.dimensions;
16669
+ const middleSliceIndex = Math.floor(numSlices / 2);
16670
+ const visited = new Array(width * height).fill(false);
16671
+ const sliceOffset = middleSliceIndex * width * height;
16672
+ const bfs = (startX, startY) => {
16673
+ const queue = [[startX, startY]];
16674
+ while (queue.length) {
16675
+ const [x, y] = queue.shift();
16676
+ const slicePixelIndex = y * width + x;
16677
+ if (x < 0 ||
16678
+ x >= width ||
16679
+ y < 0 ||
16680
+ y >= height ||
16681
+ visited[slicePixelIndex]) {
16682
+ continue;
16683
+ }
16684
+ visited[slicePixelIndex] = true;
16685
+ const volumeVoxelIndex = sliceOffset + slicePixelIndex;
16686
+ const volumeVoxelValue = subVolPixelData[volumeVoxelIndex];
16687
+ if (volumeVoxelValue < negativePixelRange[0] ||
16688
+ volumeVoxelValue > negativePixelRange[1]) {
16689
+ continue;
16690
+ }
16691
+ labelmap.voxelManager.setAtIndex(volumeVoxelIndex, negativeSeedValue);
16692
+ queue.push([x - 1, y]);
16693
+ queue.push([x + 1, y]);
16694
+ queue.push([x, y - 1]);
16695
+ queue.push([x, y + 1]);
16696
+ }
16697
+ };
16698
+ const scanLine = (startX, limitX, incX, y) => {
16699
+ for (let x = startX; x !== limitX; x += incX) {
16700
+ const slicePixelIndex = y * width + x;
16701
+ const volumeVoxelIndex = sliceOffset + slicePixelIndex;
16702
+ const volumeVoxelValue = subVolPixelData[volumeVoxelIndex];
16703
+ if (volumeVoxelValue < negativePixelRange[0] ||
16704
+ volumeVoxelValue > negativePixelRange[1]) {
16705
+ break;
16706
+ }
16707
+ if (!visited[slicePixelIndex]) {
16708
+ bfs(x, y);
16709
+ }
16710
+ }
16711
+ };
16712
+ for (let y = 0; y < height; y++) {
16713
+ scanLine(0, width - 1, 1, y);
16714
+ scanLine(width - 1, 0, -1, y);
16715
+ }
16716
+ }
16717
+ function runGrowCutForBoundingBox_setPositiveSeedValues(subVolume, labelmap, options) {
16718
+ const { positiveSeedValue = runGrowCutForBoundingBox_POSITIVE_SEED_VALUE, positivePixelRange = POSITIVE_PIXEL_RANGE, } = options;
16719
+ const subVolPixelData = subVolume.voxelManager.getCompleteScalarDataArray();
16720
+ const labelmapData = labelmap.voxelManager.getCompleteScalarDataArray();
16721
+ const [width, height, numSlices] = labelmap.dimensions;
16722
+ const middleSliceIndex = Math.floor(numSlices / 2);
16723
+ const startSliceIndex = Math.max(middleSliceIndex - 3, 0);
16724
+ const stopSliceIndex = Math.max(startSliceIndex + 5, numSlices);
16725
+ const pixelsPerSlice = width * height;
16726
+ for (let z = startSliceIndex; z < stopSliceIndex; z++) {
16727
+ const zOffset = z * pixelsPerSlice;
16728
+ for (let y = 0; y < height; y++) {
16729
+ const yOffset = y * width;
16730
+ for (let x = 0; x < width; x++) {
16731
+ const index = zOffset + yOffset + x;
16732
+ const pixelValue = subVolPixelData[index];
16733
+ const isPositiveValue = pixelValue >= positivePixelRange[0] &&
16734
+ pixelValue <= positivePixelRange[1];
16735
+ if (isPositiveValue) {
16736
+ labelmap.voxelManager.setAtIndex(index, positiveSeedValue);
16737
+ }
16738
+ }
16739
+ }
16740
+ }
16741
+ }
16742
+ async function _createAndCacheSegmentationSubVolumeForBoundingBox(subVolume, options) {
16743
+ const labelmap = esm.volumeLoader.createAndCacheDerivedLabelmapVolume(subVolume.volumeId);
16744
+ runGrowCutForBoundingBox_setPositiveSeedValues(subVolume, labelmap, options);
16745
+ runGrowCutForBoundingBox_setNegativeSeedValues(subVolume, labelmap, options);
16746
+ return labelmap;
16747
+ }
16748
+ async function runGrowCutForBoundingBox(referencedVolumeId, boundingBoxInfo, options) {
16749
+ const { boundingBox } = boundingBoxInfo;
16750
+ const { ijkTopLeft, ijkBottomRight } = boundingBox;
16751
+ const subVolumeBoundsIJK = {
16752
+ minX: ijkTopLeft[0],
16753
+ maxX: ijkBottomRight[0],
16754
+ minY: ijkTopLeft[1],
16755
+ maxY: ijkBottomRight[1],
16756
+ minZ: ijkTopLeft[2],
16757
+ maxZ: ijkBottomRight[2],
16758
+ };
16759
+ const subVolume = esm.utilities.createSubVolume(referencedVolumeId, subVolumeBoundsIJK, {
16760
+ targetBuffer: {
16761
+ type: 'Float32Array',
16762
+ },
16763
+ });
16764
+ const labelmap = await _createAndCacheSegmentationSubVolumeForBoundingBox(subVolume, options);
16765
+ await runGrowCut(subVolume.volumeId, labelmap.volumeId);
16766
+ return labelmap;
16767
+ }
16768
+
16769
+
16770
+ ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/growCut/runOneClickGrowCut.js
16771
+
16772
+
16773
+
16774
+ const { transformWorldToIndex: runOneClickGrowCut_transformWorldToIndex, transformIndexToWorld } = esm.utilities;
16775
+ const runOneClickGrowCut_POSITIVE_SEED_VALUE = 254;
16776
+ const runOneClickGrowCut_NEGATIVE_SEED_VALUE = 255;
16777
+ const runOneClickGrowCut_POSITIVE_SEED_VARIANCE = 0.1;
16778
+ const runOneClickGrowCut_NEGATIVE_SEED_VARIANCE = 0.8;
16779
+ const SUBVOLUME_PADDING_PERCENTAGE = 0.2;
16780
+ const SUBVOLUME_MIN_PADDING = 5;
16781
+ function _createSubVolume(referencedVolume, positiveRegionData, options) {
16782
+ const { dimensions } = referencedVolume;
16783
+ const positiveRegionSize = gl_matrix_esm/* vec3.sub */.eR.sub(gl_matrix_esm/* vec3.create */.eR.create(), positiveRegionData.boundingBox.bottomRight, positiveRegionData.boundingBox.topLeft);
16784
+ let subVolumePaddingPercentage = options?.subVolumePaddingPercentage ?? SUBVOLUME_PADDING_PERCENTAGE;
16785
+ let subVolumeMinPadding = options?.subVolumeMinPadding ?? SUBVOLUME_MIN_PADDING;
16786
+ if (typeof subVolumePaddingPercentage === 'number') {
16787
+ subVolumePaddingPercentage = [
16788
+ subVolumePaddingPercentage,
16789
+ subVolumePaddingPercentage,
16790
+ subVolumePaddingPercentage,
16791
+ ];
16792
+ }
16793
+ if (typeof subVolumeMinPadding === 'number') {
16794
+ subVolumeMinPadding = [
16795
+ subVolumeMinPadding,
16796
+ subVolumeMinPadding,
16797
+ subVolumeMinPadding,
16798
+ ];
16799
+ }
16800
+ const padding = gl_matrix_esm/* vec3.mul */.eR.mul(gl_matrix_esm/* vec3.create */.eR.create(), positiveRegionSize, subVolumePaddingPercentage);
16801
+ gl_matrix_esm/* vec3.round */.eR.round(padding, padding);
16802
+ gl_matrix_esm/* vec3.max */.eR.max(padding, padding, subVolumeMinPadding);
16803
+ const subVolumeSize = gl_matrix_esm/* vec3.scaleAndAdd */.eR.scaleAndAdd(gl_matrix_esm/* vec3.create */.eR.create(), positiveRegionSize, padding, 2);
16804
+ const ijkTopLeft = gl_matrix_esm/* vec3.sub */.eR.sub(gl_matrix_esm/* vec3.create */.eR.create(), positiveRegionData.boundingBox.topLeft, padding);
16805
+ const ijkBottomRight = gl_matrix_esm/* vec3.add */.eR.add(gl_matrix_esm/* vec3.create */.eR.create(), ijkTopLeft, subVolumeSize);
16806
+ gl_matrix_esm/* vec3.max */.eR.max(ijkTopLeft, ijkTopLeft, [0, 0, 0]);
16807
+ gl_matrix_esm/* vec3.min */.eR.min(ijkTopLeft, ijkTopLeft, dimensions);
16808
+ gl_matrix_esm/* vec3.max */.eR.max(ijkBottomRight, ijkBottomRight, [0, 0, 0]);
16809
+ gl_matrix_esm/* vec3.min */.eR.min(ijkBottomRight, ijkBottomRight, dimensions);
16810
+ const subVolumeBoundsIJK = {
16811
+ minX: ijkTopLeft[0],
16812
+ maxX: ijkBottomRight[0],
16813
+ minY: ijkTopLeft[1],
16814
+ maxY: ijkBottomRight[1],
16815
+ minZ: ijkTopLeft[2],
16816
+ maxZ: ijkBottomRight[2],
16817
+ };
16818
+ return esm.utilities.createSubVolume(referencedVolume.volumeId, subVolumeBoundsIJK, {
16819
+ targetBuffer: {
16820
+ type: 'Float32Array',
16821
+ },
16822
+ });
16823
+ }
16824
+ function _getPositiveRegionData(referencedVolume, worldPosition, options) {
16825
+ const [width, height, numSlices] = referencedVolume.dimensions;
16826
+ const subVolPixelData = referencedVolume.voxelManager.getCompleteScalarDataArray();
16827
+ const numPixelsPerSlice = width * height;
16828
+ const ijkStartPosition = runOneClickGrowCut_transformWorldToIndex(referencedVolume.imageData, worldPosition);
16829
+ const referencePixelValue = subVolPixelData[ijkStartPosition[2] * numPixelsPerSlice +
16830
+ ijkStartPosition[1] * width +
16831
+ ijkStartPosition[0]];
16832
+ const positiveSeedVariance = options.positiveSeedVariance ?? runOneClickGrowCut_POSITIVE_SEED_VARIANCE;
16833
+ const positiveSeedVarianceValue = Math.abs(referencePixelValue * positiveSeedVariance);
16834
+ const minPositivePixelValue = referencePixelValue - positiveSeedVarianceValue;
16835
+ const maxPositivePixelValue = referencePixelValue + positiveSeedVarianceValue;
16836
+ const neighborsCoordDelta = [
16837
+ [-1, 0, 0],
16838
+ [1, 0, 0],
16839
+ [0, -1, 0],
16840
+ [0, 1, 0],
16841
+ [0, 0, -1],
16842
+ [0, 0, 1],
16843
+ ];
16844
+ let minX = Infinity;
16845
+ let minY = Infinity;
16846
+ let minZ = Infinity;
16847
+ let maxX = -Infinity;
16848
+ let maxY = -Infinity;
16849
+ let maxZ = -Infinity;
16850
+ const startVoxelIndex = ijkStartPosition[2] * numPixelsPerSlice +
16851
+ ijkStartPosition[1] * width +
16852
+ ijkStartPosition[0];
16853
+ const voxelIndexesSet = new Set([startVoxelIndex]);
16854
+ const worldVoxelSet = new Set([worldPosition]);
16855
+ const queue = [ijkStartPosition];
16856
+ while (queue.length) {
16857
+ const ijkVoxel = queue.shift();
16858
+ const [x, y, z] = ijkVoxel;
16859
+ minX = ijkVoxel[0] < minX ? ijkVoxel[0] : minX;
16860
+ minY = ijkVoxel[1] < minY ? ijkVoxel[1] : minY;
16861
+ minZ = ijkVoxel[2] < minZ ? ijkVoxel[2] : minZ;
16862
+ maxX = ijkVoxel[0] > maxX ? ijkVoxel[0] : maxX;
16863
+ maxY = ijkVoxel[1] > maxY ? ijkVoxel[1] : maxY;
16864
+ maxZ = ijkVoxel[2] > maxZ ? ijkVoxel[2] : maxZ;
16865
+ for (let i = 0, len = neighborsCoordDelta.length; i < len; i++) {
16866
+ const neighborCoordDelta = neighborsCoordDelta[i];
16867
+ const nx = x + neighborCoordDelta[0];
16868
+ const ny = y + neighborCoordDelta[1];
16869
+ const nz = z + neighborCoordDelta[2];
16870
+ if (nx < 0 ||
16871
+ nx >= width ||
16872
+ ny < 0 ||
16873
+ ny >= height ||
16874
+ nz < 0 ||
16875
+ nz >= numSlices) {
16876
+ continue;
16877
+ }
16878
+ const neighborVoxelIndex = nz * numPixelsPerSlice + ny * width + nx;
16879
+ const neighborPixelValue = subVolPixelData[neighborVoxelIndex];
16880
+ if (voxelIndexesSet.has(neighborVoxelIndex) ||
16881
+ neighborPixelValue < minPositivePixelValue ||
16882
+ neighborPixelValue > maxPositivePixelValue) {
16883
+ continue;
16884
+ }
16885
+ const ijkVoxel = [nx, ny, nz];
16886
+ const worldVoxel = transformIndexToWorld(referencedVolume.imageData, ijkVoxel);
16887
+ voxelIndexesSet.add(neighborVoxelIndex);
16888
+ worldVoxelSet.add(worldVoxel);
16889
+ queue.push(ijkVoxel);
16890
+ }
16891
+ }
16892
+ return {
16893
+ worldVoxels: Array.from(worldVoxelSet),
16894
+ boundingBox: {
16895
+ topLeft: [minX, minY, minZ],
16896
+ bottomRight: [maxX, maxY, maxZ],
16897
+ },
16898
+ };
16899
+ }
16900
+ function runOneClickGrowCut_setPositiveSeedValues(labelmap, positiveRegionData, options) {
16901
+ const { dimensions } = labelmap;
16902
+ const [width, height] = dimensions;
16903
+ const numPixelsPerSlice = width * height;
16904
+ const positiveSeedValue = options.positiveSeedValue ?? runOneClickGrowCut_POSITIVE_SEED_VALUE;
16905
+ const { worldVoxels } = positiveRegionData;
16906
+ for (let i = 0, len = worldVoxels.length; i < len; i++) {
16907
+ const worldVoxel = worldVoxels[i];
16908
+ const ijkVoxel = runOneClickGrowCut_transformWorldToIndex(labelmap.imageData, worldVoxel);
16909
+ const voxelIndex = ijkVoxel[2] * numPixelsPerSlice + ijkVoxel[1] * width + ijkVoxel[0];
16910
+ labelmap.voxelManager.setAtIndex(voxelIndex, positiveSeedValue);
16911
+ }
16912
+ }
16913
+ function runOneClickGrowCut_setNegativeSeedValues(subVolume, labelmap, worldPosition, options) {
16914
+ const [width, height] = subVolume.dimensions;
16915
+ const subVolPixelData = subVolume.voxelManager.getCompleteScalarDataArray();
16916
+ const labelmapData = labelmap.voxelManager.getCompleteScalarDataArray();
16917
+ const ijkPosition = runOneClickGrowCut_transformWorldToIndex(subVolume.imageData, worldPosition);
16918
+ const referencePixelValue = subVolPixelData[ijkPosition[2] * width * height + ijkPosition[1] * width + ijkPosition[0]];
16919
+ const negativeSeedVariance = options.negativeSeedVariance ?? runOneClickGrowCut_NEGATIVE_SEED_VARIANCE;
16920
+ const negativeSeedValue = options.negativeSeedValue ?? runOneClickGrowCut_NEGATIVE_SEED_VALUE;
16921
+ const negativeSeedVarianceValue = Math.abs(referencePixelValue * negativeSeedVariance);
16922
+ const minNegativePixelValue = referencePixelValue - negativeSeedVarianceValue;
16923
+ const maxNegativePixelValue = referencePixelValue + negativeSeedVarianceValue;
16924
+ for (let i = 0, len = subVolPixelData.length; i < len; i++) {
16925
+ const pixelValue = subVolPixelData[i];
16926
+ if (!labelmapData[i] &&
16927
+ (pixelValue < minNegativePixelValue || pixelValue > maxNegativePixelValue)) {
16928
+ labelmap.voxelManager.setAtIndex(i, negativeSeedValue);
16929
+ }
16930
+ }
16931
+ }
16932
+ async function _createAndCacheSegmentation(subVolume, positiveRegionData, worldPosition, options) {
16933
+ const labelmap = esm.volumeLoader.createAndCacheDerivedLabelmapVolume(subVolume.volumeId);
16934
+ runOneClickGrowCut_setPositiveSeedValues(labelmap, positiveRegionData, options);
16935
+ runOneClickGrowCut_setNegativeSeedValues(subVolume, labelmap, worldPosition, options);
16936
+ return labelmap;
16937
+ }
16938
+ async function runOneClickGrowCut(referencedVolumeId, worldPosition, viewport, options) {
16939
+ const referencedVolume = esm.cache.getVolume(referencedVolumeId);
16940
+ const positiveRegionData = _getPositiveRegionData(referencedVolume, worldPosition, options);
16941
+ const subVolume = _createSubVolume(referencedVolume, positiveRegionData, options);
16942
+ const labelmap = await _createAndCacheSegmentation(subVolume, positiveRegionData, worldPosition, options);
16943
+ await runGrowCut(subVolume.volumeId, labelmap.volumeId);
16944
+ return labelmap;
16945
+ }
16946
+
16947
+
16948
+ ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/growCut/index.js
16949
+
16950
+
16951
+
16952
+
16953
+
16954
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/createLabelmapMemo.js
16955
+ var createLabelmapMemo = __webpack_require__(2397);
15253
16956
  ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/index.js
15254
16957
 
15255
16958
 
@@ -15268,6 +16971,9 @@ function getHoveredContourSegmentationAnnotation(segmentationId) {
15268
16971
 
15269
16972
 
15270
16973
 
16974
+
16975
+
16976
+
15271
16977
 
15272
16978
 
15273
16979