@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.
- package/dist/{1185.bundle.52f04f41c08dc5853aed.js → 1185.bundle.f5bdc6fbf5cf6e77f1ca.js} +129 -29
- package/dist/{1266.bundle.4f06772fcf6b303d894d.js → 1266.bundle.723b1e14a8c03300ca49.js} +30 -0
- package/dist/1266.css +1 -1
- package/dist/1801.css +1 -1
- package/dist/{1927.bundle.49539e3ab5b0aad1399c.js → 1927.bundle.c55edd5a362e7d79e23d.js} +1 -1
- package/dist/{2701.bundle.8c1ff2e0faaa7d2f4716.js → 2701.bundle.caa28a0b2f7e0b79088a.js} +14 -22
- package/dist/{149.bundle.b8d177954628f4631fc0.js → 3022.bundle.51a7056ea0e39b06e095.js} +2095 -389
- package/dist/{3198.bundle.3b22ad50fb086338b85e.js → 3198.bundle.a27ad30339285ee88574.js} +2 -2
- package/dist/3198.css +1 -1
- package/dist/{3200.bundle.768571169c3d6e603324.js → 3200.bundle.eff6d0c695d962fe4b5b.js} +17 -9
- package/dist/3200.css +1 -1
- package/dist/{3677.bundle.7d9110e8c5682b56a456.js → 3677.bundle.d3c30c37d00fc58b4442.js} +876 -18
- package/dist/{3970.bundle.31942cc0c12a008e7ba0.js → 3970.bundle.216ca9d37288f34b8f0b.js} +15 -5
- package/dist/4182.css +1 -1
- package/dist/{4571.bundle.3b1691730b3c57bf4d35.js → 4571.bundle.142e8f6150bf81f1b7d2.js} +129 -107
- package/dist/5139.css +1 -1
- package/dist/{5247.bundle.17495c3d97cf29e44e73.js → 5247.bundle.affc956197b6220e3c94.js} +4 -4
- package/dist/{5252.bundle.5ec502c53a9cc877ed8d.js → 5252.bundle.9d1855f7fb56235709ec.js} +713 -280
- package/dist/{1520.bundle.83586195deb9d61702d9.js → 5630.bundle.d206792a2f04f7156442.js} +90 -70
- package/dist/{5687.bundle.2665d32af98b253b78fd.js → 5687.bundle.022f94286f70741366b3.js} +4 -4
- package/dist/{5823.bundle.cb588e5e33eea80cd49f.js → 573.bundle.d08dcb8e65e3b7729b58.js} +27 -865
- package/dist/{1436.bundle.773756cd51b69e887bac.js → 6498.bundle.02f5b640a94509a11180.js} +1057 -536
- package/dist/{717.bundle.ba680e992f721c5d8b4a.js → 717.bundle.0b47b3dba812d4554266.js} +2 -2
- package/dist/717.css +1 -1
- package/dist/{7197.bundle.c4ff7a71122131167cbb.js → 7197.bundle.580576f8db68a65a10ce.js} +4 -4
- package/dist/{5717.bundle.848e13f256818475f57f.js → 727.bundle.f93673c292647f58ee1e.js} +1833 -817
- package/dist/{7955.bundle.dd665937d280f9427909.js → 7955.bundle.70fe7524bf3c8b78cd15.js} +1 -1
- package/dist/{8228.bundle.55ac03d7165248f47d4e.js → 8228.bundle.22df751df68b512fc6fb.js} +2 -2
- package/dist/8228.css +2 -2
- package/dist/{8558.bundle.dfedfd13f3845ea7104a.js → 8558.bundle.487a5e67207aa1f91da9.js} +3 -0
- package/dist/{9551.bundle.01a1567f174986f74fcf.js → 9551.bundle.26cea86f50cb4800bdaa.js} +1 -1
- package/dist/{9611.bundle.767595c93877e5166c03.js → 9611.bundle.0feebcae79e65852d610.js} +14 -9
- package/dist/{5807.bundle.dac5ce36534a71c77723.js → 967.bundle.fee0d6c1e9e244ad5bb3.js} +1134 -1128
- package/dist/{8523.bundle.648334132159465cdc41.js → 9809.bundle.9d3afbcc67703574e298.js} +1265 -185
- package/dist/{9862.bundle.7146682e56aa66130ae6.js → 9862.bundle.6ea7e474a390b386e2b2.js} +1 -1
- package/dist/{app.bundle.b81b47f20105288797e2.js → app.bundle.64d91e75036855d4e31a.js} +9080 -8397
- package/dist/app.bundle.css +18 -18
- package/dist/{histogram-worker.bundle.f0e060cf2637a2ca94b7.js → histogram-worker.bundle.f978654858500a3080cc.js} +3 -3
- package/dist/index.html +1 -1
- package/dist/{polySeg.bundle.b79ae514989e86301c71.js → polySeg.bundle.70ed683f467a47e3c92d.js} +3 -3
- package/dist/serve.json +1 -10
- package/dist/{suv-peak-worker.bundle.76dd4fdf82aaa2c3ad41.js → suv-peak-worker.bundle.8c83e6e99d48223569b6.js} +4 -4
- package/dist/sw.js +1 -1
- package/package.json +19 -19
- /package/dist/{1374.bundle.e5b05fd7e1295bf06867.js → 1374.bundle.afdb21e02ca5a08f8060.js} +0 -0
- /package/dist/{213.bundle.68c723cdf7de1ebb18f2.js → 213.bundle.2e20b24ab08945ba56bb.js} +0 -0
- /package/dist/{2424.bundle.acefd29e9b3948544119.js → 2424.bundle.a72e288e00a909f3930b.js} +0 -0
- /package/dist/{2825.bundle.9b280fd4de22a0b2b729.js → 2825.bundle.9fcf88214bf70b49356f.js} +0 -0
- /package/dist/{3121.bundle.d3e7092e305cf6cecdb5.js → 3121.bundle.67ff7e799683191bb324.js} +0 -0
- /package/dist/{3334.bundle.0e6ba24024018199ab66.js → 3334.bundle.e36011d0fd5fcb7e8b84.js} +0 -0
- /package/dist/{4202.bundle.5c8120ed4841da0af211.js → 4202.bundle.1311396ecdb6c0b09eb0.js} +0 -0
- /package/dist/{4834.bundle.1deb034b995ef76461a3.js → 4834.bundle.71f72158944e5afd94e8.js} +0 -0
- /package/dist/{5139.bundle.61d9101ea220a8382f2b.js → 5139.bundle.36ec15905a109af39099.js} +0 -0
- /package/dist/{5261.bundle.74682659cce85f3ae592.js → 5261.bundle.54d7af66923a3bae707d.js} +0 -0
- /package/dist/{6939.bundle.9b79da82315a25f37d96.js → 6939.bundle.5e77a634e8784085c00e.js} +0 -0
- /package/dist/{7159.bundle.9f4856182f1eda29c59d.js → 7159.bundle.4ee84ebbce84383e30d4.js} +0 -0
- /package/dist/{8008.bundle.d24be79eebc455c4512a.js → 8008.bundle.6be72115a1d79d69e7ab.js} +0 -0
- /package/dist/{8259.bundle.a91eb7639bc72f522c16.js → 8259.bundle.127e657e46bcff886565.js} +0 -0
- /package/dist/{8295.bundle.4ecb27f9e58526f12bcb.js → 8295.bundle.14cddaccdcd3a7093398.js} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(self["webpackChunk"] = self["webpackChunk"] || []).push([[
|
|
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
|
-
/***/
|
|
1962
|
+
/***/ 97:
|
|
1963
1963
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
1964
1964
|
|
|
1965
1965
|
"use strict";
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
/*
|
|
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.
|
|
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
|
-
/***/
|
|
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 */
|
|
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
|
|
2190
|
+
function getNextColorLUTIndex() {
|
|
2138
2191
|
const segmentationStateManager = _SegmentationStateManager__WEBPACK_IMPORTED_MODULE_0__/* .defaultSegmentationStateManager */ ._6;
|
|
2139
|
-
return segmentationStateManager.
|
|
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(
|
|
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 =
|
|
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
|
|
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 {
|
|
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
|
|
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 {
|
|
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 {
|
|
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
|
|
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
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
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/
|
|
5841
|
-
var
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
/***/
|
|
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 */
|
|
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
|
|
6554
|
-
/* harmony import */ var
|
|
6555
|
-
/* harmony import */ var
|
|
6556
|
-
/* harmony import */ var
|
|
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
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
|
|
6583
|
-
|
|
6584
|
-
|
|
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
|
-
|
|
6588
|
-
|
|
6589
|
-
|
|
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
|
-
|
|
6875
|
+
return {
|
|
6876
|
+
imageId: segmentationImageId,
|
|
6877
|
+
segmentsLocked,
|
|
6878
|
+
};
|
|
6593
6879
|
}
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
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.
|
|
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
|
-
/***/
|
|
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,
|
|
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
|
-
|
|
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
|
|
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/
|
|
6846
|
-
var
|
|
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 {
|
|
6856
|
-
if (!strategySpecificConfiguration.THRESHOLD ||
|
|
7383
|
+
const { strategySpecificConfiguration, previewSegmentIndex, segmentIndex } = operationData;
|
|
7384
|
+
if (!strategySpecificConfiguration.THRESHOLD ||
|
|
7385
|
+
segmentIndex === null ||
|
|
7386
|
+
previewSegmentIndex === undefined) {
|
|
6857
7387
|
return;
|
|
6858
7388
|
}
|
|
6859
|
-
const
|
|
6860
|
-
if (!
|
|
7389
|
+
const segmentSet = createSegmentSet(operationData);
|
|
7390
|
+
if (!segmentSet) {
|
|
6861
7391
|
return;
|
|
6862
7392
|
}
|
|
6863
|
-
|
|
7393
|
+
const externalRemoved = removeExternalIslands(operationData, segmentSet);
|
|
7394
|
+
if (externalRemoved === undefined) {
|
|
6864
7395
|
return;
|
|
6865
7396
|
}
|
|
6866
|
-
const
|
|
6867
|
-
|
|
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
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
|
|
6895
|
-
|
|
6896
|
-
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
|
|
6900
|
-
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
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
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
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
|
-
|
|
6940
|
-
|
|
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
|
-
(
|
|
6961
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
7037
|
-
if (!tracking || tracking.modifiedSlices.size === 0) {
|
|
7589
|
+
if (!previewVoxelManager || previewVoxelManager.modifiedSlices.size === 0) {
|
|
7038
7590
|
return;
|
|
7039
7591
|
}
|
|
7040
|
-
const
|
|
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,
|
|
7598
|
+
segmentationVoxelManager.setAtIndex(index, value);
|
|
7599
|
+
voxelManager.setAtIndex(index, segmentIndex);
|
|
7044
7600
|
}
|
|
7045
7601
|
};
|
|
7046
|
-
|
|
7047
|
-
(0,triggerSegmentationDataModified/* triggerSegmentationDataModified */.Q)(operationData.segmentationId,
|
|
7048
|
-
|
|
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
|
|
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,
|
|
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__(
|
|
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 */ .
|
|
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__(
|
|
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__(
|
|
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 */
|
|
7934
|
+
/* harmony export */ pY: () => (/* binding */ fillInsideRectangle)
|
|
7335
7935
|
/* harmony export */ });
|
|
7336
|
-
/* unused harmony
|
|
7337
|
-
/* harmony import */ var
|
|
7338
|
-
/* harmony import */ var
|
|
7339
|
-
/* harmony import */ var
|
|
7340
|
-
/* harmony import */ var
|
|
7341
|
-
/* harmony import */ var
|
|
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
|
-
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7351
|
-
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
|
|
7359
|
-
|
|
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,
|
|
7369
|
-
const isStackViewport = viewport instanceof
|
|
7370
|
-
const isAligned = isStackViewport || (0,
|
|
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 =
|
|
7989
|
+
const EPS = _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_1__.utilities.getSpacingInNormalDirection({
|
|
7375
7990
|
direction,
|
|
7376
7991
|
spacing,
|
|
7377
7992
|
}, viewPlaneNormal);
|
|
7378
|
-
const pointsBoundsLPS = (0,
|
|
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
|
-
|
|
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__(
|
|
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__/* .
|
|
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
|
|
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__(
|
|
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
|
-
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
|
|
8060
|
-
|
|
8061
|
-
|
|
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
|
-
|
|
8723
|
-
|
|
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,
|
|
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 =
|
|
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,
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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
|
|
9686
|
-
const
|
|
9687
|
-
const
|
|
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,
|
|
9696
|
-
gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.scaleAndAdd */ .eR.scaleAndAdd(bottomRightWorld,
|
|
9697
|
-
gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.scaleAndAdd */ .eR.scaleAndAdd(topLeftWorld, topLeftWorld,
|
|
9698
|
-
gl_matrix__WEBPACK_IMPORTED_MODULE_1__/* .vec3.scaleAndAdd */ .eR.scaleAndAdd(bottomRightWorld, bottomRightWorld,
|
|
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
|
|
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 =
|
|
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
|
|
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
|
-
/***/
|
|
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
|
-
|
|
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 +
|
|
15075
|
-
var segmentationState = __webpack_require__(
|
|
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
|
|