@ohif/app 3.7.0-beta.9 → 3.7.0-beta.91
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/{917.bundle.0edb40e9d9467dd3a189.js → 12.bundle.e8d2ae45df74384fd980.js} +6 -6
- package/dist/{295.bundle.957b1159fec14b9199a1.js → 125.bundle.253395f320b72180da63.js} +6 -6
- package/dist/{351.bundle.0742237651aef9694a65.js → 181.bundle.73fc96c6b3ab1fabedc8.js} +226 -204
- package/dist/{351.css → 181.css} +1 -1
- package/dist/{744.bundle.c459c690581bc8a522d8.js → 19.bundle.839e1ef2a3468da3ae6e.js} +240 -375
- package/dist/{606.bundle.5d876f5f3dd8287f0a28.js → 202.bundle.96bbb4547a346fe3921f.js} +1420 -750
- package/dist/{926.bundle.dbc9d0e591cb9217fda2.js → 220.bundle.f7e1c96c94245e70f2be.js} +990 -400
- package/dist/221.bundle.39ad5abb775af5702ddb.js +1723 -0
- package/dist/221.css +2 -0
- package/dist/{664.bundle.09abae984223969d1bde.js → 23.bundle.e008ad788170f2ed5569.js} +5 -6
- package/dist/{976.bundle.3f8bfb620791f4508420.js → 236.bundle.a24efa76d228c38e56d0.js} +88 -104
- package/dist/{55.bundle.550a823e75eb608e8d5e.js → 250.bundle.4bebed43526c7e06344f.js} +52 -36
- package/dist/{973.bundle.5aa91607481865ead93f.js → 281.bundle.b50f5766fb3f79b2ed9d.js} +18 -14
- package/dist/{82.bundle.978be6f7595202cd342b.js → 342.bundle.40cf206d7cddf20933eb.js} +1765 -476
- package/dist/{404.bundle.83acdec604ed84f4b772.js → 359.bundle.b13a62377d68750cbf34.js} +46 -131
- package/dist/{192.bundle.655fc9c5aeff41110aa9.js → 370.bundle.f25928b95a42ac10c7a7.js} +113 -99
- package/dist/{790.bundle.08e37fd3b64af8dd8e78.js → 410.bundle.cc5008512de45d69e1cb.js} +11 -9
- package/dist/{151.bundle.31ea35044218837bf73f.js → 417.bundle.af0a207c29b109f84159.js} +49 -17
- package/dist/{569.bundle.c8e771a8d28e237b32be.js → 451.bundle.1c714bfb8b66d3a5adfb.js} +86 -106
- package/dist/{581.bundle.dc6197189f7c88c27d4c.js → 471.bundle.4aaec34d87b0c93687c1.js} +78 -99
- package/dist/{199.bundle.251f86c6e2eee85c49a5.js → 506.bundle.817e9b84a97639aa147d.js} +11 -9
- package/dist/{531.bundle.2a82fb1d69e5b57cc72b.js → 530.bundle.a03b6f942ace3e1baa1e.js} +726 -447
- package/dist/579.css +1 -0
- package/dist/{935.bundle.deeffff0e4f7b528e3c3.js → 604.bundle.a51f83e64004bca5f497.js} +2 -3
- package/dist/613.bundle.37227666b898dfdfe9c1.js +532 -0
- package/dist/{984.bundle.0c8b7d8388a662ad5ebc.js → 663.bundle.73495b93aa8cb540241c.js} +68 -38
- package/dist/{205.bundle.b5a473c200dcf2bbcdb4.js → 686.bundle.dccef1f36e4bc79bcc48.js} +6 -6
- package/dist/{50.bundle.bec52570fe00c2ccced8.js → 687.bundle.3d415b0f43c3e19ef6ef.js} +218 -9
- package/dist/{331.bundle.bd0c13931a21d53086c9.js → 743.bundle.4bfe6e562ffb2c22708f.js} +26281 -21326
- package/dist/{728.bundle.d13856835357400fef82.js → 774.bundle.7528cba56a1407357144.js} +95 -64
- package/dist/{381.bundle.0905e683605fcbc0895f.js → 775.bundle.2285e7e0e67878948c0d.js} +16 -16
- package/dist/{283.bundle.b43e001c27e02b0199aa.js → 782.bundle.4bf97e067cf8067f2239.js} +117 -67
- package/dist/{642.bundle.1ab1e9ea67caeaedb189.js → 814.bundle.9d5edb8094787e02f22f.js} +6 -6
- package/dist/{799.bundle.758558e64147e5aad612.js → 822.bundle.00de6455c18be0307b41.js} +81 -34
- package/dist/831.bundle.83658f62fcc769043605.js +16700 -0
- package/dist/{707.bundle.9622c314b0ea3488d69a.js → 877.bundle.b83c182be6ee497d2df7.js} +1022 -708
- package/dist/{953.bundle.3b0189ebc11cf0946f18.js → 886.bundle.7324d84913daffb6a4c4.js} +34 -29
- package/dist/945.min.worker.js +1 -1
- package/dist/945.min.worker.js.map +1 -1
- package/dist/{270.bundle.4564621556b0f963a004.js → 957.bundle.8c09a01840ab8aa32734.js} +7093 -987
- package/dist/{208.bundle.05451122c341d80d3c22.js → 99.bundle.e6844ea7f331fd2ae35a.js} +85 -104
- package/dist/_redirects +1 -1
- package/dist/app-config.js +35 -17
- package/dist/{app.bundle.d2ebd2fcc8b88864ebeb.js → app.bundle.6c7d9f72689fc7c05040.js} +71939 -66734
- package/dist/app.bundle.css +13 -12
- package/dist/assets/yandex-browser-manifest.json +1 -1
- package/dist/cornerstoneDICOMImageLoader.min.js +1 -1
- package/dist/cornerstoneDICOMImageLoader.min.js.map +1 -1
- package/dist/{dicom-microscopy-viewer.bundle.aa60bdf008c32c39cfd7.js → dicom-microscopy-viewer.bundle.2c146384eb9466d02ff8.js} +5 -4
- package/dist/es6-shim.min.js +3569 -2
- package/dist/google.js +8 -7
- package/dist/index.html +1 -1
- package/dist/{index.worker.1c69152d710fa7b84bce.worker.js → index.worker.e62ecca63f1a2e124230.worker.js} +2 -2
- package/dist/index.worker.e62ecca63f1a2e124230.worker.js.map +1 -0
- package/dist/init-service-worker.js +3 -5
- package/dist/oidc-client.min.js +10857 -39
- package/dist/polyfill.min.js +184 -1
- package/dist/silent-refresh.html +18 -9
- package/dist/sw.js +1 -1
- package/package.json +20 -22
- package/dist/616.bundle.d0581701281977bea39b.js +0 -685
- package/dist/780.bundle.fd0f13dc92e9caa0581e.js +0 -4769
- package/dist/index.worker.1c69152d710fa7b84bce.worker.js.map +0 -1
- /package/dist/{806.css → 19.css} +0 -0
- /package/dist/{55.css → 250.css} +0 -0
- /package/dist/{707.css → 877.css} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
(
|
|
1
|
+
(self["webpackChunk"] = self["webpackChunk"] || []).push([[877],{
|
|
2
2
|
|
|
3
|
-
/***/
|
|
3
|
+
/***/ 94848:
|
|
4
4
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
5
5
|
|
|
6
6
|
"use strict";
|
|
@@ -9,7 +9,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
9
9
|
|
|
10
10
|
// EXPORTS
|
|
11
11
|
__webpack_require__.d(__webpack_exports__, {
|
|
12
|
-
|
|
12
|
+
Types: () => (/* reexport */ types_namespaceObject),
|
|
13
13
|
"default": () => (/* binding */ cornerstone_src),
|
|
14
14
|
getActiveViewportEnabledElement: () => (/* reexport */ getActiveViewportEnabledElement),
|
|
15
15
|
measurementMappingUtils: () => (/* reexport */ utils_namespaceObject),
|
|
@@ -26,27 +26,26 @@ __webpack_require__.r(utils_namespaceObject);
|
|
|
26
26
|
__webpack_require__.d(utils_namespaceObject, {
|
|
27
27
|
getFirstAnnotationSelected: () => (getFirstAnnotationSelected),
|
|
28
28
|
getHandlesFromPoints: () => (getHandlesFromPoints),
|
|
29
|
-
getModalityUnit: () => (utils_getModalityUnit),
|
|
30
29
|
getSOPInstanceAttributes: () => (getSOPInstanceAttributes/* default */.Z),
|
|
31
30
|
isAnnotationSelected: () => (isAnnotationSelected),
|
|
32
31
|
setAnnotationSelected: () => (setAnnotationSelected)
|
|
33
32
|
});
|
|
34
33
|
|
|
35
34
|
// EXTERNAL MODULE: ../../../node_modules/react/index.js
|
|
36
|
-
var react = __webpack_require__(
|
|
37
|
-
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js +
|
|
38
|
-
var esm = __webpack_require__(
|
|
39
|
-
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js +
|
|
40
|
-
var dist_esm = __webpack_require__(
|
|
41
|
-
// EXTERNAL MODULE: ../../core/src/index.ts +
|
|
42
|
-
var src = __webpack_require__(
|
|
35
|
+
var react = __webpack_require__(43001);
|
|
36
|
+
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js + 331 modules
|
|
37
|
+
var esm = __webpack_require__(3743);
|
|
38
|
+
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js + 348 modules
|
|
39
|
+
var dist_esm = __webpack_require__(14957);
|
|
40
|
+
// EXTERNAL MODULE: ../../core/src/index.ts + 64 modules
|
|
41
|
+
var src = __webpack_require__(67869);
|
|
43
42
|
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/streaming-image-volume-loader/dist/esm/index.js + 13 modules
|
|
44
|
-
var streaming_image_volume_loader_dist_esm = __webpack_require__(
|
|
43
|
+
var streaming_image_volume_loader_dist_esm = __webpack_require__(7087);
|
|
45
44
|
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/dicom-image-loader/dist/dynamic-import/cornerstoneDICOMImageLoader.min.js
|
|
46
|
-
var cornerstoneDICOMImageLoader_min = __webpack_require__(
|
|
45
|
+
var cornerstoneDICOMImageLoader_min = __webpack_require__(61539);
|
|
47
46
|
var cornerstoneDICOMImageLoader_min_default = /*#__PURE__*/__webpack_require__.n(cornerstoneDICOMImageLoader_min);
|
|
48
47
|
// EXTERNAL MODULE: ../../../node_modules/dicom-parser/dist/dicomParser.min.js
|
|
49
|
-
var dicomParser_min = __webpack_require__(
|
|
48
|
+
var dicomParser_min = __webpack_require__(56660);
|
|
50
49
|
var dicomParser_min_default = /*#__PURE__*/__webpack_require__.n(dicomParser_min);
|
|
51
50
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/initWADOImageLoader.js
|
|
52
51
|
|
|
@@ -76,7 +75,7 @@ function initWebWorkers(appConfig) {
|
|
|
76
75
|
initialized = true;
|
|
77
76
|
}
|
|
78
77
|
}
|
|
79
|
-
function initWADOImageLoader(userAuthenticationService, appConfig) {
|
|
78
|
+
function initWADOImageLoader(userAuthenticationService, appConfig, extensionManager) {
|
|
80
79
|
(cornerstoneDICOMImageLoader_min_default()).external.cornerstone = esm;
|
|
81
80
|
(cornerstoneDICOMImageLoader_min_default()).external.dicomParser = (dicomParser_min_default());
|
|
82
81
|
registerVolumeLoader('cornerstoneStreamingImageVolume', streaming_image_volume_loader_dist_esm/* cornerstoneStreamingImageVolumeLoader */.IU);
|
|
@@ -87,21 +86,17 @@ function initWADOImageLoader(userAuthenticationService, appConfig) {
|
|
|
87
86
|
// will convert everything to integers (to be able to work with cornerstone-2d).
|
|
88
87
|
// Until the default is set to true (which is the case for cornerstone3D),
|
|
89
88
|
// we should set this flag to false.
|
|
90
|
-
convertFloatPixelDataToInt: false
|
|
89
|
+
convertFloatPixelDataToInt: false,
|
|
90
|
+
use16BitDataType: Boolean(appConfig.use16BitDataType)
|
|
91
91
|
},
|
|
92
92
|
beforeSend: function (xhr) {
|
|
93
|
+
//TODO should be removed in the future and request emitted by DicomWebDataSource
|
|
94
|
+
const sourceConfig = extensionManager.getActiveDataSource()?.[0].getConfig() ?? {};
|
|
93
95
|
const headers = userAuthenticationService.getAuthorizationHeader();
|
|
94
|
-
|
|
95
|
-
// Request:
|
|
96
|
-
// JPEG-LS Lossless (1.2.840.10008.1.2.4.80) if available, otherwise accept
|
|
97
|
-
// whatever transfer-syntax the origin server provides.
|
|
98
|
-
// For now we use image/jls and image/x-jls because some servers still use the old type
|
|
99
|
-
// http://dicom.nema.org/medical/dicom/current/output/html/part18.html
|
|
96
|
+
const acceptHeader = src.utils.generateAcceptHeader(sourceConfig.acceptHeader, sourceConfig.requestTransferSyntaxUID, sourceConfig.omitQuotationForMultipartRequest);
|
|
100
97
|
const xhrRequestHeaders = {
|
|
101
|
-
Accept:
|
|
102
|
-
// 'multipart/related; type="image/x-jls", multipart/related; type="image/jls"; transfer-syntax="1.2.840.10008.1.2.4.80", multipart/related; type="image/x-jls", multipart/related; type="application/octet-stream"; transfer-syntax=*',
|
|
98
|
+
Accept: acceptHeader
|
|
103
99
|
};
|
|
104
|
-
|
|
105
100
|
if (headers) {
|
|
106
101
|
Object.assign(xhrRequestHeaders, headers);
|
|
107
102
|
}
|
|
@@ -116,14 +111,14 @@ function initWADOImageLoader(userAuthenticationService, appConfig) {
|
|
|
116
111
|
function destroy() {
|
|
117
112
|
// Note: we don't want to call .terminate on the webWorkerManager since
|
|
118
113
|
// that resets the config
|
|
119
|
-
const webWorkers =
|
|
114
|
+
const webWorkers = webWorkerManager.webWorkers;
|
|
120
115
|
for (let i = 0; i < webWorkers.length; i++) {
|
|
121
116
|
webWorkers[i].worker.terminate();
|
|
122
117
|
}
|
|
123
118
|
webWorkers.length = 0;
|
|
124
119
|
}
|
|
125
|
-
// EXTERNAL MODULE: ../../ui/src/index.js +
|
|
126
|
-
var ui_src = __webpack_require__(
|
|
120
|
+
// EXTERNAL MODULE: ../../ui/src/index.js + 485 modules
|
|
121
|
+
var ui_src = __webpack_require__(71783);
|
|
127
122
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/callInputDialog.tsx
|
|
128
123
|
|
|
129
124
|
|
|
@@ -157,7 +152,9 @@ function callInputDialog(uiDialogService, data, callback) {
|
|
|
157
152
|
} = _ref;
|
|
158
153
|
switch (action.id) {
|
|
159
154
|
case 'save':
|
|
160
|
-
if (typeof validateFunc === 'function' && !validateFunc(value.label))
|
|
155
|
+
if (typeof validateFunc === 'function' && !validateFunc(value.label)) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
161
158
|
callback(value.label, action.id);
|
|
162
159
|
break;
|
|
163
160
|
case 'cancel':
|
|
@@ -187,11 +184,11 @@ function callInputDialog(uiDialogService, data, callback) {
|
|
|
187
184
|
actions: [{
|
|
188
185
|
id: 'cancel',
|
|
189
186
|
text: 'Cancel',
|
|
190
|
-
type: ui_src/* ButtonEnums.type */.LZ.
|
|
187
|
+
type: ui_src/* ButtonEnums.type */.LZ.dt.secondary
|
|
191
188
|
}, {
|
|
192
189
|
id: 'save',
|
|
193
190
|
text: 'Save',
|
|
194
|
-
type: ui_src/* ButtonEnums.type */.LZ.
|
|
191
|
+
type: ui_src/* ButtonEnums.type */.LZ.dt.primary
|
|
195
192
|
}],
|
|
196
193
|
onSubmit: onSubmitHandler,
|
|
197
194
|
body: _ref2 => {
|
|
@@ -201,7 +198,7 @@ function callInputDialog(uiDialogService, data, callback) {
|
|
|
201
198
|
} = _ref2;
|
|
202
199
|
return /*#__PURE__*/react.createElement(ui_src/* Input */.II, {
|
|
203
200
|
autoFocus: true,
|
|
204
|
-
className: "
|
|
201
|
+
className: "border-primary-main bg-black",
|
|
205
202
|
type: "text",
|
|
206
203
|
id: "annotation",
|
|
207
204
|
label: inputLabel,
|
|
@@ -232,17 +229,17 @@ function callInputDialog(uiDialogService, data, callback) {
|
|
|
232
229
|
}
|
|
233
230
|
/* harmony default export */ const utils_callInputDialog = (callInputDialog);
|
|
234
231
|
// EXTERNAL MODULE: ../../../extensions/cornerstone/src/state.ts
|
|
235
|
-
var state = __webpack_require__(
|
|
232
|
+
var state = __webpack_require__(73704);
|
|
236
233
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/getActiveViewportEnabledElement.ts
|
|
237
234
|
|
|
238
235
|
|
|
239
236
|
function getActiveViewportEnabledElement(viewportGridService) {
|
|
240
237
|
const {
|
|
241
|
-
|
|
238
|
+
activeViewportId
|
|
242
239
|
} = viewportGridService.getState();
|
|
243
240
|
const {
|
|
244
241
|
element
|
|
245
|
-
} = (0,state/* getEnabledElement */.K8)(
|
|
242
|
+
} = (0,state/* getEnabledElement */.K8)(activeViewportId) || {};
|
|
246
243
|
const enabledElement = (0,esm.getEnabledElement)(element);
|
|
247
244
|
return enabledElement;
|
|
248
245
|
}
|
|
@@ -322,11 +319,12 @@ function onCompletedCalibrationLine(servicesManager, csToolsEvent) {
|
|
|
322
319
|
const currentColumnPixelSpacing = calibratedPixelSpacing?.[1] || imagePlaneModule?.columnPixelSpacing || 1;
|
|
323
320
|
const adjustCalibration = newLength => {
|
|
324
321
|
const spacingScale = newLength / length;
|
|
325
|
-
const rowSpacing = spacingScale * currentRowPixelSpacing;
|
|
326
|
-
const colSpacing = spacingScale * currentColumnPixelSpacing;
|
|
327
322
|
|
|
328
323
|
// trigger resize of the viewport to adjust the world/pixel mapping
|
|
329
|
-
calibrateImageSpacing(imageId, viewport.getRenderingEngine(),
|
|
324
|
+
calibrateImageSpacing(imageId, viewport.getRenderingEngine(), {
|
|
325
|
+
type: 'User',
|
|
326
|
+
scale: 1 / spacingScale
|
|
327
|
+
});
|
|
330
328
|
};
|
|
331
329
|
return new Promise((resolve, reject) => {
|
|
332
330
|
if (!uiDialogService) {
|
|
@@ -358,9 +356,223 @@ function onCompletedCalibrationLine(servicesManager, csToolsEvent) {
|
|
|
358
356
|
});
|
|
359
357
|
});
|
|
360
358
|
}
|
|
359
|
+
// EXTERNAL MODULE: ../../core/src/utils/index.js + 25 modules
|
|
360
|
+
var utils = __webpack_require__(77250);
|
|
361
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/tools/ImageOverlayViewerTool.tsx
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Image Overlay Viewer tool is not a traditional tool that requires user interactin.
|
|
368
|
+
* But it is used to display Pixel Overlays. And it will provide toggling capability.
|
|
369
|
+
*
|
|
370
|
+
* The documentation for Overlay Plane Module of DICOM can be found in [C.9.2 of
|
|
371
|
+
* Part-3 of DICOM standard](https://dicom.nema.org/medical/dicom/2018b/output/chtml/part03/sect_C.9.2.html)
|
|
372
|
+
*
|
|
373
|
+
* Image Overlay rendered by this tool can be toggled on and off using
|
|
374
|
+
* toolGroup.setToolEnabled() and toolGroup.setToolDisabled()
|
|
375
|
+
*/
|
|
376
|
+
class ImageOverlayViewerTool extends dist_esm.AnnotationDisplayTool {
|
|
377
|
+
constructor() {
|
|
378
|
+
let toolProps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
379
|
+
let defaultToolProps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
380
|
+
supportedInteractionTypes: [],
|
|
381
|
+
configuration: {
|
|
382
|
+
fillColor: [255, 127, 127, 255]
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
super(toolProps, defaultToolProps);
|
|
386
|
+
this._cachedOverlayMetadata = new Map();
|
|
387
|
+
this._cachedStats = {};
|
|
388
|
+
this.onSetToolDisabled = () => {
|
|
389
|
+
this._cachedStats = {};
|
|
390
|
+
this._cachedOverlayMetadata = new Map();
|
|
391
|
+
};
|
|
392
|
+
this.renderAnnotation = (enabledElement, svgDrawingHelper) => {
|
|
393
|
+
const {
|
|
394
|
+
viewport
|
|
395
|
+
} = enabledElement;
|
|
396
|
+
const imageId = this.getReferencedImageId(viewport);
|
|
397
|
+
if (!imageId) {
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
const overlays = this._cachedOverlayMetadata.get(imageId) ?? esm.metaData.get('overlayPlaneModule', imageId)?.overlays;
|
|
401
|
+
|
|
402
|
+
// no overlays
|
|
403
|
+
if (!overlays?.length) {
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
this._cachedOverlayMetadata.set(imageId, overlays);
|
|
407
|
+
this._getCachedStat(imageId, overlays, this.configuration.fillColor).then(cachedStat => {
|
|
408
|
+
cachedStat.overlays.forEach(overlay => {
|
|
409
|
+
this._renderOverlay(enabledElement, svgDrawingHelper, overlay);
|
|
410
|
+
});
|
|
411
|
+
});
|
|
412
|
+
return true;
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
getReferencedImageId(viewport) {
|
|
416
|
+
if (viewport instanceof esm.VolumeViewport) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
const targetId = this.getTargetId(viewport);
|
|
420
|
+
return targetId.split('imageId:')[1];
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Render to DOM
|
|
424
|
+
*
|
|
425
|
+
* @param enabledElement
|
|
426
|
+
* @param svgDrawingHelper
|
|
427
|
+
* @param overlayData
|
|
428
|
+
* @returns
|
|
429
|
+
*/
|
|
430
|
+
_renderOverlay(enabledElement, svgDrawingHelper, overlayData) {
|
|
431
|
+
const {
|
|
432
|
+
viewport
|
|
433
|
+
} = enabledElement;
|
|
434
|
+
const imageId = this.getReferencedImageId(viewport);
|
|
435
|
+
if (!imageId) {
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Decide the rendering position of the overlay image on the current canvas
|
|
440
|
+
const {
|
|
441
|
+
_id,
|
|
442
|
+
columns: width,
|
|
443
|
+
rows: height,
|
|
444
|
+
x,
|
|
445
|
+
y
|
|
446
|
+
} = overlayData;
|
|
447
|
+
const overlayTopLeftWorldPos = esm.utilities.imageToWorldCoords(imageId, [x - 1,
|
|
448
|
+
// Remind that top-left corner's (x, y) is be (1, 1)
|
|
449
|
+
y - 1]);
|
|
450
|
+
const overlayTopLeftOnCanvas = viewport.worldToCanvas(overlayTopLeftWorldPos);
|
|
451
|
+
const overlayBottomRightWorldPos = esm.utilities.imageToWorldCoords(imageId, [width, height]);
|
|
452
|
+
const overlayBottomRightOnCanvas = viewport.worldToCanvas(overlayBottomRightWorldPos);
|
|
453
|
+
|
|
454
|
+
// add image to the annotations svg layer
|
|
455
|
+
const svgns = 'http://www.w3.org/2000/svg';
|
|
456
|
+
const svgNodeHash = `image-overlay-${_id}`;
|
|
457
|
+
const existingImageElement = svgDrawingHelper.getSvgNode(svgNodeHash);
|
|
458
|
+
const attributes = {
|
|
459
|
+
'data-id': svgNodeHash,
|
|
460
|
+
width: overlayBottomRightOnCanvas[0] - overlayTopLeftOnCanvas[0],
|
|
461
|
+
height: overlayBottomRightOnCanvas[1] - overlayTopLeftOnCanvas[1],
|
|
462
|
+
x: overlayTopLeftOnCanvas[0],
|
|
463
|
+
y: overlayTopLeftOnCanvas[1],
|
|
464
|
+
href: overlayData.dataUrl
|
|
465
|
+
};
|
|
466
|
+
if (isNaN(attributes.x) || isNaN(attributes.y) || isNaN(attributes.width) || isNaN(attributes.height)) {
|
|
467
|
+
console.warn('Invalid rendering attribute for image overlay', attributes['data-id']);
|
|
468
|
+
return false;
|
|
469
|
+
}
|
|
470
|
+
if (existingImageElement) {
|
|
471
|
+
dist_esm.drawing.setAttributesIfNecessary(attributes, existingImageElement);
|
|
472
|
+
svgDrawingHelper.setNodeTouched(svgNodeHash);
|
|
473
|
+
} else {
|
|
474
|
+
const newImageElement = document.createElementNS(svgns, 'image');
|
|
475
|
+
dist_esm.drawing.setNewAttributesIfValid(attributes, newImageElement);
|
|
476
|
+
svgDrawingHelper.appendNode(newImageElement, svgNodeHash);
|
|
477
|
+
}
|
|
478
|
+
return true;
|
|
479
|
+
}
|
|
480
|
+
async _getCachedStat(imageId, overlayMetadata, color) {
|
|
481
|
+
if (this._cachedStats[imageId] && this._isSameColor(this._cachedStats[imageId].color, color)) {
|
|
482
|
+
return this._cachedStats[imageId];
|
|
483
|
+
}
|
|
484
|
+
const overlays = await Promise.all(overlayMetadata.filter(overlay => overlay.pixelData).map(async (overlay, idx) => {
|
|
485
|
+
let pixelData = null;
|
|
486
|
+
if (overlay.pixelData.Value) {
|
|
487
|
+
pixelData = overlay.pixelData.Value;
|
|
488
|
+
} else if (overlay.pixelData instanceof Array) {
|
|
489
|
+
pixelData = overlay.pixelData[0];
|
|
490
|
+
} else if (overlay.pixelData.retrieveBulkData) {
|
|
491
|
+
pixelData = await overlay.pixelData.retrieveBulkData();
|
|
492
|
+
}
|
|
493
|
+
if (!pixelData) {
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
const dataUrl = this._renderOverlayToDataUrl({
|
|
497
|
+
width: overlay.columns,
|
|
498
|
+
height: overlay.rows
|
|
499
|
+
}, color, pixelData);
|
|
500
|
+
return {
|
|
501
|
+
...overlay,
|
|
502
|
+
_id: (0,utils/* guid */.M8)(),
|
|
503
|
+
dataUrl,
|
|
504
|
+
// this will be a data url expression of the rendered image
|
|
505
|
+
color
|
|
506
|
+
};
|
|
507
|
+
}));
|
|
508
|
+
this._cachedStats[imageId] = {
|
|
509
|
+
color: color,
|
|
510
|
+
overlays: overlays.filter(overlay => overlay)
|
|
511
|
+
};
|
|
512
|
+
return this._cachedStats[imageId];
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* compare two RGBA expression of colors.
|
|
517
|
+
*
|
|
518
|
+
* @param color1
|
|
519
|
+
* @param color2
|
|
520
|
+
* @returns
|
|
521
|
+
*/
|
|
522
|
+
_isSameColor(color1, color2) {
|
|
523
|
+
return color1 && color2 && color1[0] === color2[0] && color1[1] === color2[1] && color1[2] === color2[2] && color1[3] === color2[3];
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* pixelData of overlayPlane module is an array of bits corresponding
|
|
528
|
+
* to each of the underlying pixels of the image.
|
|
529
|
+
* Let's create pixel data from bit array of overlay data
|
|
530
|
+
*
|
|
531
|
+
* @param pixelDataRaw
|
|
532
|
+
* @param color
|
|
533
|
+
* @returns
|
|
534
|
+
*/
|
|
535
|
+
_renderOverlayToDataUrl(_ref, color, pixelDataRaw) {
|
|
536
|
+
let {
|
|
537
|
+
width,
|
|
538
|
+
height
|
|
539
|
+
} = _ref;
|
|
540
|
+
const pixelDataView = new DataView(pixelDataRaw);
|
|
541
|
+
const totalBits = width * height;
|
|
542
|
+
const canvas = document.createElement('canvas');
|
|
543
|
+
canvas.width = width;
|
|
544
|
+
canvas.height = height;
|
|
545
|
+
const ctx = canvas.getContext('2d');
|
|
546
|
+
ctx.clearRect(0, 0, width, height); // make it transparent
|
|
547
|
+
ctx.globalCompositeOperation = 'copy';
|
|
548
|
+
const imageData = ctx.getImageData(0, 0, width, height);
|
|
549
|
+
const data = imageData.data;
|
|
550
|
+
for (let i = 0, bitIdx = 0, byteIdx = 0; i < totalBits; i++) {
|
|
551
|
+
if (pixelDataView.getUint8(byteIdx) & 1 << bitIdx) {
|
|
552
|
+
data[i * 4] = color[0];
|
|
553
|
+
data[i * 4 + 1] = color[1];
|
|
554
|
+
data[i * 4 + 2] = color[2];
|
|
555
|
+
data[i * 4 + 3] = color[3];
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// next bit, byte
|
|
559
|
+
if (bitIdx >= 7) {
|
|
560
|
+
bitIdx = 0;
|
|
561
|
+
byteIdx++;
|
|
562
|
+
} else {
|
|
563
|
+
bitIdx++;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
ctx.putImageData(imageData, 0, 0);
|
|
567
|
+
return canvas.toDataURL();
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
ImageOverlayViewerTool.toolName = 'ImageOverlayViewer';
|
|
571
|
+
/* harmony default export */ const tools_ImageOverlayViewerTool = (ImageOverlayViewerTool);
|
|
361
572
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/initCornerstoneTools.js
|
|
362
573
|
|
|
363
574
|
|
|
575
|
+
|
|
364
576
|
function initCornerstoneTools() {
|
|
365
577
|
let configuration = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
366
578
|
dist_esm.CrosshairsTool.isAnnotation = false;
|
|
@@ -390,6 +602,10 @@ function initCornerstoneTools() {
|
|
|
390
602
|
(0,dist_esm.addTool)(dist_esm.ReferenceLinesTool);
|
|
391
603
|
(0,dist_esm.addTool)(tools_CalibrationLineTool);
|
|
392
604
|
(0,dist_esm.addTool)(dist_esm.TrackballRotateTool);
|
|
605
|
+
(0,dist_esm.addTool)(dist_esm.CircleScissorsTool);
|
|
606
|
+
(0,dist_esm.addTool)(dist_esm.RectangleScissorsTool);
|
|
607
|
+
(0,dist_esm.addTool)(dist_esm.SphereScissorsTool);
|
|
608
|
+
(0,dist_esm.addTool)(tools_ImageOverlayViewerTool);
|
|
393
609
|
|
|
394
610
|
// Modify annotation tools to use dashed lines on SR
|
|
395
611
|
const annotationStyle = {
|
|
@@ -428,13 +644,17 @@ const toolNames = {
|
|
|
428
644
|
SegmentationDisplay: dist_esm.SegmentationDisplayTool.toolName,
|
|
429
645
|
ReferenceLines: dist_esm.ReferenceLinesTool.toolName,
|
|
430
646
|
CalibrationLine: tools_CalibrationLineTool.toolName,
|
|
431
|
-
TrackballRotateTool: dist_esm.TrackballRotateTool.toolName
|
|
647
|
+
TrackballRotateTool: dist_esm.TrackballRotateTool.toolName,
|
|
648
|
+
CircleScissors: dist_esm.CircleScissorsTool.toolName,
|
|
649
|
+
RectangleScissors: dist_esm.RectangleScissorsTool.toolName,
|
|
650
|
+
SphereScissors: dist_esm.SphereScissorsTool.toolName,
|
|
651
|
+
ImageOverlayViewer: tools_ImageOverlayViewerTool.toolName
|
|
432
652
|
};
|
|
433
653
|
|
|
434
654
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/constants/supportedTools.js
|
|
435
655
|
/* harmony default export */ const supportedTools = (['Length', 'EllipticalROI', 'CircleROI', 'Bidirectional', 'ArrowAnnotate', 'Angle', 'CobbAngle', 'Probe', 'RectangleROI', 'PlanarFreehandROI']);
|
|
436
656
|
// EXTERNAL MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/utils/getSOPInstanceAttributes.js
|
|
437
|
-
var getSOPInstanceAttributes = __webpack_require__(
|
|
657
|
+
var getSOPInstanceAttributes = __webpack_require__(87172);
|
|
438
658
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/Length.ts
|
|
439
659
|
|
|
440
660
|
|
|
@@ -537,9 +757,9 @@ function getMappedAnnotations(annotation, displaySetService) {
|
|
|
537
757
|
SeriesNumber
|
|
538
758
|
} = displaySet;
|
|
539
759
|
const {
|
|
540
|
-
length
|
|
760
|
+
length,
|
|
761
|
+
unit = 'mm'
|
|
541
762
|
} = targetStats;
|
|
542
|
-
const unit = 'mm';
|
|
543
763
|
annotations.push({
|
|
544
764
|
SeriesInstanceUID,
|
|
545
765
|
SOPInstanceUID,
|
|
@@ -566,10 +786,13 @@ function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
|
|
|
566
786
|
values.push('Cornerstone:Length');
|
|
567
787
|
mappedAnnotations.forEach(annotation => {
|
|
568
788
|
const {
|
|
569
|
-
length
|
|
789
|
+
length,
|
|
790
|
+
unit
|
|
570
791
|
} = annotation;
|
|
571
|
-
columns.push(`Length
|
|
792
|
+
columns.push(`Length`);
|
|
572
793
|
values.push(length);
|
|
794
|
+
columns.push('Unit');
|
|
795
|
+
values.push(unit);
|
|
573
796
|
});
|
|
574
797
|
if (FrameOfReferenceUID) {
|
|
575
798
|
columns.push('FrameOfReferenceUID');
|
|
@@ -598,7 +821,8 @@ function getDisplayText(mappedAnnotations, displaySet) {
|
|
|
598
821
|
length,
|
|
599
822
|
SeriesNumber,
|
|
600
823
|
SOPInstanceUID,
|
|
601
|
-
frameNumber
|
|
824
|
+
frameNumber,
|
|
825
|
+
unit
|
|
602
826
|
} = mappedAnnotations[0];
|
|
603
827
|
const instance = displaySet.images.find(image => image.SOPInstanceUID === SOPInstanceUID);
|
|
604
828
|
let InstanceNumber;
|
|
@@ -607,9 +831,11 @@ function getDisplayText(mappedAnnotations, displaySet) {
|
|
|
607
831
|
}
|
|
608
832
|
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
|
609
833
|
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
|
|
610
|
-
if (length === null || length === undefined)
|
|
834
|
+
if (length === null || length === undefined) {
|
|
835
|
+
return displayText;
|
|
836
|
+
}
|
|
611
837
|
const roundedLength = src.utils.roundNumber(length, 2);
|
|
612
|
-
displayText.push(`${roundedLength}
|
|
838
|
+
displayText.push(`${roundedLength} ${unit} (S: ${SeriesNumber}${instanceText}${frameText})`);
|
|
613
839
|
return displayText;
|
|
614
840
|
}
|
|
615
841
|
/* harmony default export */ const measurementServiceMappings_Length = (Length);
|
|
@@ -711,9 +937,9 @@ function Bidirectional_getMappedAnnotations(annotation, displaySetService) {
|
|
|
711
937
|
} = displaySet;
|
|
712
938
|
const {
|
|
713
939
|
length,
|
|
714
|
-
width
|
|
940
|
+
width,
|
|
941
|
+
unit
|
|
715
942
|
} = targetStats;
|
|
716
|
-
const unit = 'mm';
|
|
717
943
|
annotations.push({
|
|
718
944
|
SeriesInstanceUID,
|
|
719
945
|
SOPInstanceUID,
|
|
@@ -742,10 +968,11 @@ function Bidirectional_getReport(mappedAnnotations, points, FrameOfReferenceUID)
|
|
|
742
968
|
mappedAnnotations.forEach(annotation => {
|
|
743
969
|
const {
|
|
744
970
|
length,
|
|
745
|
-
width
|
|
971
|
+
width,
|
|
972
|
+
unit
|
|
746
973
|
} = annotation;
|
|
747
|
-
columns.push(`Length
|
|
748
|
-
values.push(length, width);
|
|
974
|
+
columns.push(`Length`, `Width`, 'Unit');
|
|
975
|
+
values.push(length, width, unit);
|
|
749
976
|
});
|
|
750
977
|
if (FrameOfReferenceUID) {
|
|
751
978
|
columns.push('FrameOfReferenceUID');
|
|
@@ -773,6 +1000,7 @@ function Bidirectional_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
773
1000
|
const {
|
|
774
1001
|
length,
|
|
775
1002
|
width,
|
|
1003
|
+
unit,
|
|
776
1004
|
SeriesNumber,
|
|
777
1005
|
SOPInstanceUID,
|
|
778
1006
|
frameNumber
|
|
@@ -786,27 +1014,15 @@ function Bidirectional_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
786
1014
|
}
|
|
787
1015
|
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
|
788
1016
|
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
|
|
789
|
-
displayText.push(`L: ${roundedLength}
|
|
790
|
-
displayText.push(`W: ${roundedWidth}
|
|
1017
|
+
displayText.push(`L: ${roundedLength} ${unit} (S: ${SeriesNumber}${instanceText}${frameText})`);
|
|
1018
|
+
displayText.push(`W: ${roundedWidth} ${unit}`);
|
|
791
1019
|
return displayText;
|
|
792
1020
|
}
|
|
793
1021
|
/* harmony default export */ const measurementServiceMappings_Bidirectional = (Bidirectional);
|
|
794
|
-
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/utils/getModalityUnit.js
|
|
795
|
-
function getModalityUnit(modality) {
|
|
796
|
-
if (modality === 'CT') {
|
|
797
|
-
return 'HU';
|
|
798
|
-
} else if (modality === 'PT') {
|
|
799
|
-
return 'SUV';
|
|
800
|
-
} else {
|
|
801
|
-
return '';
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
/* harmony default export */ const utils_getModalityUnit = (getModalityUnit);
|
|
805
1022
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/EllipticalROI.ts
|
|
806
1023
|
|
|
807
1024
|
|
|
808
1025
|
|
|
809
|
-
|
|
810
1026
|
const EllipticalROI = {
|
|
811
1027
|
toAnnotation: measurement => {},
|
|
812
1028
|
toMeasurement: (csToolsEventDetail, displaySetService, cornerstoneViewportService, getValueTypeFromToolType) => {
|
|
@@ -904,16 +1120,18 @@ function EllipticalROI_getMappedAnnotations(annotation, displaySetService) {
|
|
|
904
1120
|
stdDev,
|
|
905
1121
|
max,
|
|
906
1122
|
area,
|
|
907
|
-
Modality
|
|
1123
|
+
Modality,
|
|
1124
|
+
areaUnit,
|
|
1125
|
+
modalityUnit
|
|
908
1126
|
} = targetStats;
|
|
909
|
-
const unit = utils_getModalityUnit(Modality);
|
|
910
1127
|
annotations.push({
|
|
911
1128
|
SeriesInstanceUID,
|
|
912
1129
|
SOPInstanceUID,
|
|
913
1130
|
SeriesNumber,
|
|
914
1131
|
frameNumber,
|
|
915
1132
|
Modality,
|
|
916
|
-
unit,
|
|
1133
|
+
unit: modalityUnit,
|
|
1134
|
+
areaUnit,
|
|
917
1135
|
mean,
|
|
918
1136
|
stdDev,
|
|
919
1137
|
max,
|
|
@@ -941,13 +1159,14 @@ function EllipticalROI_getReport(mappedAnnotations, points, FrameOfReferenceUID)
|
|
|
941
1159
|
stdDev,
|
|
942
1160
|
max,
|
|
943
1161
|
area,
|
|
944
|
-
unit
|
|
1162
|
+
unit,
|
|
1163
|
+
areaUnit
|
|
945
1164
|
} = annotation;
|
|
946
1165
|
if (!mean || !unit || !max || !area) {
|
|
947
1166
|
return;
|
|
948
1167
|
}
|
|
949
|
-
columns.push(`max (${unit})`, `mean (${unit})`, `std (${unit})`,
|
|
950
|
-
values.push(max, mean, stdDev, area);
|
|
1168
|
+
columns.push(`max (${unit})`, `mean (${unit})`, `std (${unit})`, 'Area', 'Unit');
|
|
1169
|
+
values.push(max, mean, stdDev, area, areaUnit);
|
|
951
1170
|
});
|
|
952
1171
|
if (FrameOfReferenceUID) {
|
|
953
1172
|
columns.push('FrameOfReferenceUID');
|
|
@@ -975,7 +1194,8 @@ function EllipticalROI_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
975
1194
|
const {
|
|
976
1195
|
area,
|
|
977
1196
|
SOPInstanceUID,
|
|
978
|
-
frameNumber
|
|
1197
|
+
frameNumber,
|
|
1198
|
+
areaUnit
|
|
979
1199
|
} = mappedAnnotations[0];
|
|
980
1200
|
const instance = displaySet.images.find(image => image.SOPInstanceUID === SOPInstanceUID);
|
|
981
1201
|
let InstanceNumber;
|
|
@@ -984,10 +1204,8 @@ function EllipticalROI_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
984
1204
|
}
|
|
985
1205
|
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
|
986
1206
|
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
const roundedArea = src.utils.roundNumber(area || 0, 2);
|
|
990
|
-
displayText.push(`${roundedArea} mm<sup>2</sup>`);
|
|
1207
|
+
const roundedArea = src.utils.roundNumber(area, 2);
|
|
1208
|
+
displayText.push(`${roundedArea} ${areaUnit}`);
|
|
991
1209
|
|
|
992
1210
|
// Todo: we need a better UI for displaying all these information
|
|
993
1211
|
mappedAnnotations.forEach(mappedAnnotation => {
|
|
@@ -1013,7 +1231,6 @@ function EllipticalROI_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
1013
1231
|
|
|
1014
1232
|
|
|
1015
1233
|
|
|
1016
|
-
|
|
1017
1234
|
const CircleROI = {
|
|
1018
1235
|
toAnnotation: measurement => {},
|
|
1019
1236
|
toMeasurement: (csToolsEventDetail, DisplaySetService, CornerstoneViewportService, getValueTypeFromToolType) => {
|
|
@@ -1111,20 +1328,22 @@ function CircleROI_getMappedAnnotations(annotation, DisplaySetService) {
|
|
|
1111
1328
|
stdDev,
|
|
1112
1329
|
max,
|
|
1113
1330
|
area,
|
|
1114
|
-
Modality
|
|
1331
|
+
Modality,
|
|
1332
|
+
areaUnit,
|
|
1333
|
+
modalityUnit
|
|
1115
1334
|
} = targetStats;
|
|
1116
|
-
const unit = utils_getModalityUnit(Modality);
|
|
1117
1335
|
annotations.push({
|
|
1118
1336
|
SeriesInstanceUID,
|
|
1119
1337
|
SOPInstanceUID,
|
|
1120
1338
|
SeriesNumber,
|
|
1121
1339
|
frameNumber,
|
|
1122
1340
|
Modality,
|
|
1123
|
-
unit,
|
|
1341
|
+
unit: modalityUnit,
|
|
1124
1342
|
mean,
|
|
1125
1343
|
stdDev,
|
|
1126
1344
|
max,
|
|
1127
|
-
area
|
|
1345
|
+
area,
|
|
1346
|
+
areaUnit
|
|
1128
1347
|
});
|
|
1129
1348
|
});
|
|
1130
1349
|
return annotations;
|
|
@@ -1148,13 +1367,14 @@ function CircleROI_getReport(mappedAnnotations, points, FrameOfReferenceUID) {
|
|
|
1148
1367
|
stdDev,
|
|
1149
1368
|
max,
|
|
1150
1369
|
area,
|
|
1151
|
-
unit
|
|
1370
|
+
unit,
|
|
1371
|
+
areaUnit
|
|
1152
1372
|
} = annotation;
|
|
1153
1373
|
if (!mean || !unit || !max || !area) {
|
|
1154
1374
|
return;
|
|
1155
1375
|
}
|
|
1156
|
-
columns.push(`max (${unit})`, `mean (${unit})`, `std (${unit})`,
|
|
1157
|
-
values.push(max, mean, stdDev, area);
|
|
1376
|
+
columns.push(`max (${unit})`, `mean (${unit})`, `std (${unit})`, 'Area', 'Unit');
|
|
1377
|
+
values.push(max, mean, stdDev, area, areaUnit);
|
|
1158
1378
|
});
|
|
1159
1379
|
if (FrameOfReferenceUID) {
|
|
1160
1380
|
columns.push('FrameOfReferenceUID');
|
|
@@ -1182,7 +1402,8 @@ function CircleROI_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
1182
1402
|
const {
|
|
1183
1403
|
area,
|
|
1184
1404
|
SOPInstanceUID,
|
|
1185
|
-
frameNumber
|
|
1405
|
+
frameNumber,
|
|
1406
|
+
areaUnit
|
|
1186
1407
|
} = mappedAnnotations[0];
|
|
1187
1408
|
const instance = displaySet.images.find(image => image.SOPInstanceUID === SOPInstanceUID);
|
|
1188
1409
|
let InstanceNumber;
|
|
@@ -1194,7 +1415,7 @@ function CircleROI_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
1194
1415
|
|
|
1195
1416
|
// Area sometimes becomes undefined if `preventHandleOutsideImage` is off.
|
|
1196
1417
|
const roundedArea = src.utils.roundNumber(area || 0, 2);
|
|
1197
|
-
displayText.push(`${roundedArea}
|
|
1418
|
+
displayText.push(`${roundedArea} ${areaUnit}`);
|
|
1198
1419
|
|
|
1199
1420
|
// Todo: we need a better UI for displaying all these information
|
|
1200
1421
|
mappedAnnotations.forEach(mappedAnnotation => {
|
|
@@ -1515,7 +1736,9 @@ function CobbAngle_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
1515
1736
|
}
|
|
1516
1737
|
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
|
1517
1738
|
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
|
|
1518
|
-
if (angle === undefined)
|
|
1739
|
+
if (angle === undefined) {
|
|
1740
|
+
return displayText;
|
|
1741
|
+
}
|
|
1519
1742
|
const roundedAngle = src.utils.roundNumber(angle, 2);
|
|
1520
1743
|
displayText.push(`${roundedAngle} ${unit} (S: ${SeriesNumber}${instanceText}${frameText})`);
|
|
1521
1744
|
return displayText;
|
|
@@ -1695,7 +1918,9 @@ function Angle_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
1695
1918
|
}
|
|
1696
1919
|
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
|
1697
1920
|
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
|
|
1698
|
-
if (angle === undefined)
|
|
1921
|
+
if (angle === undefined) {
|
|
1922
|
+
return displayText;
|
|
1923
|
+
}
|
|
1699
1924
|
const roundedAngle = src.utils.roundNumber(angle, 2);
|
|
1700
1925
|
displayText.push(`${roundedAngle} ${unit} (S: ${SeriesNumber}${instanceText}${frameText})`);
|
|
1701
1926
|
return displayText;
|
|
@@ -1839,7 +2064,6 @@ function PlanarFreehandROI_getDisplayText(mappedAnnotations) {
|
|
|
1839
2064
|
|
|
1840
2065
|
|
|
1841
2066
|
|
|
1842
|
-
|
|
1843
2067
|
const RectangleROI = {
|
|
1844
2068
|
toAnnotation: measurement => {},
|
|
1845
2069
|
toMeasurement: (csToolsEventDetail, DisplaySetService, CornerstoneViewportService, getValueTypeFromToolType) => {
|
|
@@ -1937,20 +2161,22 @@ function RectangleROI_getMappedAnnotations(annotation, DisplaySetService) {
|
|
|
1937
2161
|
stdDev,
|
|
1938
2162
|
max,
|
|
1939
2163
|
area,
|
|
1940
|
-
Modality
|
|
2164
|
+
Modality,
|
|
2165
|
+
modalityUnit,
|
|
2166
|
+
areaUnit
|
|
1941
2167
|
} = targetStats;
|
|
1942
|
-
const unit = utils_getModalityUnit(Modality);
|
|
1943
2168
|
annotations.push({
|
|
1944
2169
|
SeriesInstanceUID,
|
|
1945
2170
|
SOPInstanceUID,
|
|
1946
2171
|
SeriesNumber,
|
|
1947
2172
|
frameNumber,
|
|
1948
2173
|
Modality,
|
|
1949
|
-
unit,
|
|
2174
|
+
unit: modalityUnit,
|
|
1950
2175
|
mean,
|
|
1951
2176
|
stdDev,
|
|
1952
2177
|
max,
|
|
1953
|
-
area
|
|
2178
|
+
area,
|
|
2179
|
+
areaUnit
|
|
1954
2180
|
});
|
|
1955
2181
|
});
|
|
1956
2182
|
return annotations;
|
|
@@ -1974,13 +2200,14 @@ function RectangleROI_getReport(mappedAnnotations, points, FrameOfReferenceUID)
|
|
|
1974
2200
|
stdDev,
|
|
1975
2201
|
max,
|
|
1976
2202
|
area,
|
|
1977
|
-
unit
|
|
2203
|
+
unit,
|
|
2204
|
+
areaUnit
|
|
1978
2205
|
} = annotation;
|
|
1979
2206
|
if (!mean || !unit || !max || !area) {
|
|
1980
2207
|
return;
|
|
1981
2208
|
}
|
|
1982
|
-
columns.push(`
|
|
1983
|
-
values.push(max, mean, stdDev, area);
|
|
2209
|
+
columns.push(`Maximum`, `Mean`, `Std Dev`, 'Pixel Unit', `Area`, 'Unit');
|
|
2210
|
+
values.push(max, mean, stdDev, unit, area, areaUnit);
|
|
1984
2211
|
});
|
|
1985
2212
|
if (FrameOfReferenceUID) {
|
|
1986
2213
|
columns.push('FrameOfReferenceUID');
|
|
@@ -2008,7 +2235,8 @@ function RectangleROI_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
2008
2235
|
const {
|
|
2009
2236
|
area,
|
|
2010
2237
|
SOPInstanceUID,
|
|
2011
|
-
frameNumber
|
|
2238
|
+
frameNumber,
|
|
2239
|
+
areaUnit
|
|
2012
2240
|
} = mappedAnnotations[0];
|
|
2013
2241
|
const instance = displaySet.images.find(image => image.SOPInstanceUID === SOPInstanceUID);
|
|
2014
2242
|
let InstanceNumber;
|
|
@@ -2020,7 +2248,7 @@ function RectangleROI_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
2020
2248
|
|
|
2021
2249
|
// Area sometimes becomes undefined if `preventHandleOutsideImage` is off.
|
|
2022
2250
|
const roundedArea = src.utils.roundNumber(area || 0, 2);
|
|
2023
|
-
displayText.push(`${roundedArea}
|
|
2251
|
+
displayText.push(`${roundedArea} ${areaUnit}`);
|
|
2024
2252
|
|
|
2025
2253
|
// Todo: we need a better UI for displaying all these information
|
|
2026
2254
|
mappedAnnotations.forEach(mappedAnnotation => {
|
|
@@ -2515,7 +2743,7 @@ function getInterleavedFrames(imageIds) {
|
|
|
2515
2743
|
}
|
|
2516
2744
|
while (!prefetchQueuedFilled.currentPositionDownToMinimum || !prefetchQueuedFilled.currentPositionUpToMaximum) {
|
|
2517
2745
|
if (!prefetchQueuedFilled.currentPositionDownToMinimum) {
|
|
2518
|
-
// Add imageId
|
|
2746
|
+
// Add imageId below
|
|
2519
2747
|
lowerImageIdIndex--;
|
|
2520
2748
|
imageIdsToPrefetch.push({
|
|
2521
2749
|
imageId: imageIds[lowerImageIdIndex],
|
|
@@ -2540,7 +2768,7 @@ function getInterleavedFrames(imageIds) {
|
|
|
2540
2768
|
return imageIdsToPrefetch;
|
|
2541
2769
|
}
|
|
2542
2770
|
// EXTERNAL MODULE: ../../../node_modules/lodash/lodash.js
|
|
2543
|
-
var lodash = __webpack_require__(
|
|
2771
|
+
var lodash = __webpack_require__(44379);
|
|
2544
2772
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/interleaveCenterLoader.ts
|
|
2545
2773
|
|
|
2546
2774
|
|
|
@@ -2730,8 +2958,12 @@ function getNthFrames(imageIds) {
|
|
|
2730
2958
|
* @returns [] reordered to be breadth first traversal of lists
|
|
2731
2959
|
*/
|
|
2732
2960
|
function interleave(lists) {
|
|
2733
|
-
if (!lists || !lists.length)
|
|
2734
|
-
|
|
2961
|
+
if (!lists || !lists.length) {
|
|
2962
|
+
return [];
|
|
2963
|
+
}
|
|
2964
|
+
if (lists.length === 1) {
|
|
2965
|
+
return lists[0];
|
|
2966
|
+
}
|
|
2735
2967
|
console.time('interleave');
|
|
2736
2968
|
const useLists = [...lists];
|
|
2737
2969
|
const ret = [];
|
|
@@ -3004,6 +3236,7 @@ const DEFAULT_CONTEXT_MENU_CLICKS = {
|
|
|
3004
3236
|
commands: [{
|
|
3005
3237
|
commandName: 'showCornerstoneContextMenu',
|
|
3006
3238
|
commandOptions: {
|
|
3239
|
+
requireNearbyToolData: true,
|
|
3007
3240
|
menuId: 'measurementsContextMenu'
|
|
3008
3241
|
}
|
|
3009
3242
|
}]
|
|
@@ -3020,9 +3253,15 @@ const DEFAULT_CONTEXT_MENU_CLICKS = {
|
|
|
3020
3253
|
function getEventName(evt) {
|
|
3021
3254
|
const button = evt.detail.event.which;
|
|
3022
3255
|
const nameArr = [];
|
|
3023
|
-
if (evt.detail.event.altKey)
|
|
3024
|
-
|
|
3025
|
-
|
|
3256
|
+
if (evt.detail.event.altKey) {
|
|
3257
|
+
nameArr.push('alt');
|
|
3258
|
+
}
|
|
3259
|
+
if (evt.detail.event.ctrlKey) {
|
|
3260
|
+
nameArr.push('ctrl');
|
|
3261
|
+
}
|
|
3262
|
+
if (evt.detail.event.shiftKey) {
|
|
3263
|
+
nameArr.push('shift');
|
|
3264
|
+
}
|
|
3026
3265
|
nameArr.push('button');
|
|
3027
3266
|
nameArr.push(button);
|
|
3028
3267
|
return nameArr.join('');
|
|
@@ -3040,9 +3279,18 @@ function initContextMenu(_ref) {
|
|
|
3040
3279
|
const cornerstoneViewportHandleEvent = (name, evt) => {
|
|
3041
3280
|
const customizations = customizationService.get('cornerstoneViewportClickCommands') || DEFAULT_CONTEXT_MENU_CLICKS;
|
|
3042
3281
|
const toRun = customizations[name];
|
|
3043
|
-
|
|
3282
|
+
if (!toRun) {
|
|
3283
|
+
return;
|
|
3284
|
+
}
|
|
3285
|
+
|
|
3286
|
+
// only find nearbyToolData if required, for the click (which closes the context menu
|
|
3287
|
+
// we don't need to find nearbyToolData)
|
|
3288
|
+
let nearbyToolData = null;
|
|
3289
|
+
if (toRun.commands.some(command => command.commandOptions?.requireNearbyToolData)) {
|
|
3290
|
+
nearbyToolData = findNearbyToolData(commandsManager, evt);
|
|
3291
|
+
}
|
|
3044
3292
|
const options = {
|
|
3045
|
-
nearbyToolData
|
|
3293
|
+
nearbyToolData,
|
|
3046
3294
|
event: evt
|
|
3047
3295
|
};
|
|
3048
3296
|
commandsManager.run(toRun, options);
|
|
@@ -3057,10 +3305,11 @@ function initContextMenu(_ref) {
|
|
|
3057
3305
|
element
|
|
3058
3306
|
} = evt.detail;
|
|
3059
3307
|
const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId);
|
|
3060
|
-
if (!viewportInfo)
|
|
3061
|
-
|
|
3308
|
+
if (!viewportInfo) {
|
|
3309
|
+
return;
|
|
3310
|
+
}
|
|
3062
3311
|
// TODO check update upstream
|
|
3063
|
-
(0,state/* setEnabledElement */.Yc)(
|
|
3312
|
+
(0,state/* setEnabledElement */.Yc)(viewportId, element);
|
|
3064
3313
|
element.addEventListener(cs3DToolsEvents.MOUSE_CLICK, cornerstoneViewportHandleClick);
|
|
3065
3314
|
}
|
|
3066
3315
|
function elementDisabledHandler(evt) {
|
|
@@ -3094,9 +3343,15 @@ const DEFAULT_DOUBLE_CLICK = {
|
|
|
3094
3343
|
*/
|
|
3095
3344
|
function getDoubleClickEventName(evt) {
|
|
3096
3345
|
const nameArr = [];
|
|
3097
|
-
if (evt.detail.event.altKey)
|
|
3098
|
-
|
|
3099
|
-
|
|
3346
|
+
if (evt.detail.event.altKey) {
|
|
3347
|
+
nameArr.push('alt');
|
|
3348
|
+
}
|
|
3349
|
+
if (evt.detail.event.ctrlKey) {
|
|
3350
|
+
nameArr.push('ctrl');
|
|
3351
|
+
}
|
|
3352
|
+
if (evt.detail.event.shiftKey) {
|
|
3353
|
+
nameArr.push('shift');
|
|
3354
|
+
}
|
|
3100
3355
|
nameArr.push('doubleClick');
|
|
3101
3356
|
return nameArr.join('');
|
|
3102
3357
|
}
|
|
@@ -3154,7 +3409,6 @@ function initDoubleClick(_ref) {
|
|
|
3154
3409
|
|
|
3155
3410
|
|
|
3156
3411
|
|
|
3157
|
-
|
|
3158
3412
|
// TODO: Cypress tests are currently grabbing this from the window?
|
|
3159
3413
|
window.cornerstone = esm;
|
|
3160
3414
|
window.cornerstoneTools = dist_esm;
|
|
@@ -3169,7 +3423,24 @@ async function init(_ref) {
|
|
|
3169
3423
|
configuration,
|
|
3170
3424
|
appConfig
|
|
3171
3425
|
} = _ref;
|
|
3172
|
-
|
|
3426
|
+
// Note: this should run first before initializing the cornerstone
|
|
3427
|
+
// DO NOT CHANGE THE ORDER
|
|
3428
|
+
const value = appConfig.useSharedArrayBuffer;
|
|
3429
|
+
let sharedArrayBufferDisabled = false;
|
|
3430
|
+
if (value === 'AUTO') {
|
|
3431
|
+
esm.setUseSharedArrayBuffer(esm.Enums.SharedArrayBufferModes.AUTO);
|
|
3432
|
+
} else if (value === 'FALSE' || value === false) {
|
|
3433
|
+
esm.setUseSharedArrayBuffer(esm.Enums.SharedArrayBufferModes.FALSE);
|
|
3434
|
+
sharedArrayBufferDisabled = true;
|
|
3435
|
+
} else {
|
|
3436
|
+
esm.setUseSharedArrayBuffer(esm.Enums.SharedArrayBufferModes.TRUE);
|
|
3437
|
+
}
|
|
3438
|
+
await (0,esm.init)({
|
|
3439
|
+
rendering: {
|
|
3440
|
+
preferSizeOverAccuracy: Boolean(appConfig.use16BitDataType),
|
|
3441
|
+
useNorm16Texture: Boolean(appConfig.use16BitDataType)
|
|
3442
|
+
}
|
|
3443
|
+
});
|
|
3173
3444
|
|
|
3174
3445
|
// For debugging e2e tests that are failing on CI
|
|
3175
3446
|
esm.setUseCPURendering(Boolean(appConfig.useCPURendering));
|
|
@@ -3181,34 +3452,35 @@ async function init(_ref) {
|
|
|
3181
3452
|
}
|
|
3182
3453
|
});
|
|
3183
3454
|
|
|
3184
|
-
// For debugging large datasets
|
|
3185
|
-
const
|
|
3186
|
-
|
|
3187
|
-
|
|
3455
|
+
// For debugging large datasets, otherwise prefer the defaults
|
|
3456
|
+
const {
|
|
3457
|
+
maxCacheSize
|
|
3458
|
+
} = appConfig;
|
|
3459
|
+
if (maxCacheSize) {
|
|
3460
|
+
esm.cache.setMaxCacheSize(maxCacheSize);
|
|
3461
|
+
}
|
|
3188
3462
|
initCornerstoneTools();
|
|
3189
3463
|
esm.Settings.getRuntimeSettings().set('useCursors', Boolean(appConfig.useCursors));
|
|
3190
3464
|
const {
|
|
3191
3465
|
userAuthenticationService,
|
|
3192
|
-
measurementService,
|
|
3193
3466
|
customizationService,
|
|
3194
|
-
displaySetService,
|
|
3195
|
-
uiDialogService,
|
|
3196
3467
|
uiModalService,
|
|
3197
3468
|
uiNotificationService,
|
|
3198
3469
|
cineService,
|
|
3199
3470
|
cornerstoneViewportService,
|
|
3200
3471
|
hangingProtocolService,
|
|
3201
3472
|
toolGroupService,
|
|
3473
|
+
toolbarService,
|
|
3202
3474
|
viewportGridService,
|
|
3203
3475
|
stateSyncService
|
|
3204
3476
|
} = servicesManager.services;
|
|
3205
3477
|
window.services = servicesManager.services;
|
|
3206
3478
|
window.extensionManager = extensionManager;
|
|
3207
3479
|
window.commandsManager = commandsManager;
|
|
3208
|
-
if (appConfig.showWarningMessageForCrossOrigin && !window.crossOriginIsolated) {
|
|
3480
|
+
if (appConfig.showWarningMessageForCrossOrigin && !window.crossOriginIsolated && !sharedArrayBufferDisabled) {
|
|
3209
3481
|
uiNotificationService.show({
|
|
3210
3482
|
title: 'Cross Origin Isolation',
|
|
3211
|
-
message: 'Cross Origin Isolation is not enabled,
|
|
3483
|
+
message: 'Cross Origin Isolation is not enabled, read more about it here: https://docs.ohif.org/faq/',
|
|
3212
3484
|
type: 'warning'
|
|
3213
3485
|
});
|
|
3214
3486
|
}
|
|
@@ -3254,7 +3526,7 @@ async function init(_ref) {
|
|
|
3254
3526
|
thumbnail: appConfig?.maxNumRequests?.thumbnail || 75,
|
|
3255
3527
|
prefetch: appConfig?.maxNumRequests?.prefetch || 10
|
|
3256
3528
|
};
|
|
3257
|
-
initWADOImageLoader(userAuthenticationService, appConfig);
|
|
3529
|
+
initWADOImageLoader(userAuthenticationService, appConfig, extensionManager);
|
|
3258
3530
|
|
|
3259
3531
|
/* Measurement Service */
|
|
3260
3532
|
this.measurementServiceSource = connectToolsToMeasurementService(servicesManager);
|
|
@@ -3289,11 +3561,51 @@ async function init(_ref) {
|
|
|
3289
3561
|
customizationService,
|
|
3290
3562
|
commandsManager
|
|
3291
3563
|
});
|
|
3292
|
-
|
|
3564
|
+
|
|
3565
|
+
/**
|
|
3566
|
+
* When a viewport gets a new display set, this call will go through all the
|
|
3567
|
+
* active tools in the toolbar, and call any commands registered in the
|
|
3568
|
+
* toolbar service with a callback to re-enable on displaying the viewport.
|
|
3569
|
+
*/
|
|
3570
|
+
const toolbarEventListener = evt => {
|
|
3293
3571
|
const {
|
|
3294
3572
|
element
|
|
3295
3573
|
} = evt.detail;
|
|
3296
|
-
|
|
3574
|
+
const activeTools = toolbarService.getActiveTools();
|
|
3575
|
+
activeTools.forEach(tool => {
|
|
3576
|
+
const toolData = toolbarService.getNestedButton(tool);
|
|
3577
|
+
const commands = toolData?.listeners?.[evt.type];
|
|
3578
|
+
commandsManager.run(commands, {
|
|
3579
|
+
element,
|
|
3580
|
+
evt
|
|
3581
|
+
});
|
|
3582
|
+
});
|
|
3583
|
+
};
|
|
3584
|
+
|
|
3585
|
+
/** Listens for active viewport events and fires the toolbar listeners */
|
|
3586
|
+
const activeViewportEventListener = evt => {
|
|
3587
|
+
const {
|
|
3588
|
+
viewportId
|
|
3589
|
+
} = evt;
|
|
3590
|
+
const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
|
|
3591
|
+
const activeTools = toolbarService.getActiveTools();
|
|
3592
|
+
activeTools.forEach(tool => {
|
|
3593
|
+
if (!toolGroup?._toolInstances?.[tool]) {
|
|
3594
|
+
return;
|
|
3595
|
+
}
|
|
3596
|
+
|
|
3597
|
+
// check if tool is active on the new viewport
|
|
3598
|
+
const toolEnabled = toolGroup._toolInstances[tool].mode === dist_esm.Enums.ToolModes.Enabled;
|
|
3599
|
+
if (!toolEnabled) {
|
|
3600
|
+
return;
|
|
3601
|
+
}
|
|
3602
|
+
const button = toolbarService.getNestedButton(tool);
|
|
3603
|
+
const commands = button?.listeners?.[evt.type];
|
|
3604
|
+
commandsManager.run(commands, {
|
|
3605
|
+
viewportId,
|
|
3606
|
+
evt
|
|
3607
|
+
});
|
|
3608
|
+
});
|
|
3297
3609
|
};
|
|
3298
3610
|
const resetCrosshairs = evt => {
|
|
3299
3611
|
const {
|
|
@@ -3316,12 +3628,18 @@ async function init(_ref) {
|
|
|
3316
3628
|
toolGroup.setToolEnabled('Crosshairs');
|
|
3317
3629
|
}
|
|
3318
3630
|
};
|
|
3631
|
+
esm.eventTarget.addEventListener(esm.EVENTS.STACK_VIEWPORT_NEW_STACK, evt => {
|
|
3632
|
+
const {
|
|
3633
|
+
element
|
|
3634
|
+
} = evt.detail;
|
|
3635
|
+
dist_esm.utilities.stackContextPrefetch.enable(element);
|
|
3636
|
+
});
|
|
3319
3637
|
function elementEnabledHandler(evt) {
|
|
3320
3638
|
const {
|
|
3321
3639
|
element
|
|
3322
3640
|
} = evt.detail;
|
|
3323
3641
|
element.addEventListener(esm.EVENTS.CAMERA_RESET, resetCrosshairs);
|
|
3324
|
-
esm.eventTarget.addEventListener(esm.EVENTS.STACK_VIEWPORT_NEW_STACK,
|
|
3642
|
+
esm.eventTarget.addEventListener(esm.EVENTS.STACK_VIEWPORT_NEW_STACK, toolbarEventListener);
|
|
3325
3643
|
}
|
|
3326
3644
|
function elementDisabledHandler(evt) {
|
|
3327
3645
|
const {
|
|
@@ -3338,31 +3656,7 @@ async function init(_ref) {
|
|
|
3338
3656
|
|
|
3339
3657
|
esm.eventTarget.addEventListener(esm.EVENTS.ELEMENT_ENABLED, elementEnabledHandler.bind(null));
|
|
3340
3658
|
esm.eventTarget.addEventListener(esm.EVENTS.ELEMENT_DISABLED, elementDisabledHandler.bind(null));
|
|
3341
|
-
viewportGridService.subscribe(viewportGridService.EVENTS.
|
|
3342
|
-
let {
|
|
3343
|
-
viewportIndex,
|
|
3344
|
-
viewportId
|
|
3345
|
-
} = _ref2;
|
|
3346
|
-
viewportId = viewportId || `viewport-${viewportIndex}`;
|
|
3347
|
-
const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
|
|
3348
|
-
if (!toolGroup || !toolGroup._toolInstances?.['ReferenceLines']) {
|
|
3349
|
-
return;
|
|
3350
|
-
}
|
|
3351
|
-
|
|
3352
|
-
// check if reference lines are active
|
|
3353
|
-
const referenceLinesEnabled = toolGroup._toolInstances['ReferenceLines'].mode === dist_esm.Enums.ToolModes.Enabled;
|
|
3354
|
-
if (!referenceLinesEnabled) {
|
|
3355
|
-
return;
|
|
3356
|
-
}
|
|
3357
|
-
toolGroup.setToolConfiguration(dist_esm.ReferenceLinesTool.toolName, {
|
|
3358
|
-
sourceViewportId: viewportId
|
|
3359
|
-
}, true // overwrite
|
|
3360
|
-
);
|
|
3361
|
-
|
|
3362
|
-
// make sure to set it to enabled again since we want to recalculate
|
|
3363
|
-
// the source-target lines
|
|
3364
|
-
toolGroup.setToolEnabled(dist_esm.ReferenceLinesTool.toolName);
|
|
3365
|
-
});
|
|
3659
|
+
viewportGridService.subscribe(viewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED, activeViewportEventListener);
|
|
3366
3660
|
}
|
|
3367
3661
|
function CPUModal() {
|
|
3368
3662
|
return /*#__PURE__*/react.createElement("div", null, /*#__PURE__*/react.createElement("p", null, "Your computer does not have enough GPU power to support the default GPU rendering mode. OHIF has switched to CPU rendering mode. Please note that CPU rendering does not support all features such as Volume Rendering, Multiplanar Reconstruction, and Segmentation Overlays."));
|
|
@@ -3387,12 +3681,12 @@ function _showCPURenderingModal(uiModalService, hangingProtocolService) {
|
|
|
3387
3681
|
});
|
|
3388
3682
|
}
|
|
3389
3683
|
// EXTERNAL MODULE: ../../../node_modules/react-dropzone/dist/es/index.js + 5 modules
|
|
3390
|
-
var es = __webpack_require__(
|
|
3684
|
+
var es = __webpack_require__(74834);
|
|
3391
3685
|
// EXTERNAL MODULE: ../../../node_modules/prop-types/index.js
|
|
3392
|
-
var prop_types = __webpack_require__(
|
|
3686
|
+
var prop_types = __webpack_require__(3827);
|
|
3393
3687
|
var prop_types_default = /*#__PURE__*/__webpack_require__.n(prop_types);
|
|
3394
3688
|
// EXTERNAL MODULE: ../../../node_modules/classnames/index.js
|
|
3395
|
-
var classnames = __webpack_require__(
|
|
3689
|
+
var classnames = __webpack_require__(44921);
|
|
3396
3690
|
var classnames_default = /*#__PURE__*/__webpack_require__.n(classnames);
|
|
3397
3691
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/DicomFileUploader.ts
|
|
3398
3692
|
|
|
@@ -3541,7 +3835,9 @@ class DicomFileUploader extends src/* PubSubService */.hC {
|
|
|
3541
3835
|
request.addEventListener('loadend', cleanUpCallback);
|
|
3542
3836
|
}
|
|
3543
3837
|
_checkDicomFile(arrayBuffer) {
|
|
3544
|
-
if (arrayBuffer.length <= 132)
|
|
3838
|
+
if (arrayBuffer.length <= 132) {
|
|
3839
|
+
return false;
|
|
3840
|
+
}
|
|
3545
3841
|
const arr = new Uint8Array(arrayBuffer.slice(128, 132));
|
|
3546
3842
|
// bytes from 128 to 132 must be "DICM"
|
|
3547
3843
|
return Array.from('DICM').every((char, i) => char.charCodeAt(0) === arr[i]);
|
|
@@ -3560,7 +3856,6 @@ const DicomUploadProgressItem = /*#__PURE__*/(0,react.memo)(_ref => {
|
|
|
3560
3856
|
const [percentComplete, setPercentComplete] = (0,react.useState)(dicomFileUploader.getPercentComplete());
|
|
3561
3857
|
const [failedReason, setFailedReason] = (0,react.useState)('');
|
|
3562
3858
|
const [status, setStatus] = (0,react.useState)(dicomFileUploader.getStatus());
|
|
3563
|
-
console.info(`${dicomFileUploader.getFileId()}`);
|
|
3564
3859
|
const isComplete = (0,react.useCallback)(() => {
|
|
3565
3860
|
return status === UploadStatus.Failed || status === UploadStatus.Cancelled || status === UploadStatus.Success;
|
|
3566
3861
|
}, [status]);
|
|
@@ -3601,25 +3896,25 @@ const DicomUploadProgressItem = /*#__PURE__*/(0,react.memo)(_ref => {
|
|
|
3601
3896
|
}
|
|
3602
3897
|
};
|
|
3603
3898
|
return /*#__PURE__*/react.createElement("div", {
|
|
3604
|
-
className: "
|
|
3899
|
+
className: "min-h-14 border-secondary-light flex w-full items-center overflow-hidden border-b p-2.5 text-lg"
|
|
3605
3900
|
}, /*#__PURE__*/react.createElement("div", {
|
|
3606
|
-
className: "
|
|
3901
|
+
className: "self-top flex w-0 shrink grow flex-col gap-1"
|
|
3607
3902
|
}, /*#__PURE__*/react.createElement("div", {
|
|
3608
3903
|
className: "flex gap-4"
|
|
3609
3904
|
}, /*#__PURE__*/react.createElement("div", {
|
|
3610
|
-
className: "flex w-6
|
|
3905
|
+
className: "flex w-6 shrink-0 items-center justify-center"
|
|
3611
3906
|
}, getStatusIcon()), /*#__PURE__*/react.createElement("div", {
|
|
3612
|
-
className: "text-ellipsis whitespace-nowrap
|
|
3907
|
+
className: "overflow-hidden text-ellipsis whitespace-nowrap"
|
|
3613
3908
|
}, dicomFileUploader.getFileName())), failedReason && /*#__PURE__*/react.createElement("div", {
|
|
3614
3909
|
className: "pl-10"
|
|
3615
3910
|
}, failedReason)), /*#__PURE__*/react.createElement("div", {
|
|
3616
|
-
className: "w-24
|
|
3911
|
+
className: "flex w-24 items-center"
|
|
3617
3912
|
}, !isComplete() && /*#__PURE__*/react.createElement(react.Fragment, null, dicomFileUploader.getStatus() === UploadStatus.InProgress && /*#__PURE__*/react.createElement("div", {
|
|
3618
3913
|
className: "w-10 text-right"
|
|
3619
3914
|
}, percentComplete, "%"), /*#__PURE__*/react.createElement("div", {
|
|
3620
|
-
className: "flex cursor-pointer
|
|
3915
|
+
className: "ml-auto flex cursor-pointer"
|
|
3621
3916
|
}, /*#__PURE__*/react.createElement(ui_src/* Icon */.JO, {
|
|
3622
|
-
className: "
|
|
3917
|
+
className: "text-primary-active self-center",
|
|
3623
3918
|
name: "close",
|
|
3624
3919
|
onClick: cancelUpload
|
|
3625
3920
|
})))));
|
|
@@ -3846,7 +4141,7 @@ function DicomUploadProgress(_ref) {
|
|
|
3846
4141
|
}, []);
|
|
3847
4142
|
const getNumCompletedAndTimeRemainingComponent = () => {
|
|
3848
4143
|
return /*#__PURE__*/react.createElement("div", {
|
|
3849
|
-
className: "
|
|
4144
|
+
className: "bg-primary-dark flex h-14 items-center px-1 pb-4 text-lg"
|
|
3850
4145
|
}, numFilesCompleted === dicomFileUploaderArr.length ? /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("span", {
|
|
3851
4146
|
className: NO_WRAP_ELLIPSIS_CLASS_NAMES
|
|
3852
4147
|
}, `${dicomFileUploaderArr.length} ${dicomFileUploaderArr.length > 1 ? 'files' : 'file'} completed.`), /*#__PURE__*/react.createElement(ui_src/* Button */.zx, {
|
|
@@ -3861,13 +4156,13 @@ function DicomUploadProgress(_ref) {
|
|
|
3861
4156
|
}, ' files completed.', "\xA0"), /*#__PURE__*/react.createElement("span", {
|
|
3862
4157
|
className: NO_WRAP_ELLIPSIS_CLASS_NAMES
|
|
3863
4158
|
}, timeRemaining ? `Less than ${getFormattedTimeRemaining()} remaining. ` : ''), /*#__PURE__*/react.createElement("span", {
|
|
3864
|
-
className: classnames_default()(NO_WRAP_ELLIPSIS_CLASS_NAMES, '
|
|
4159
|
+
className: classnames_default()(NO_WRAP_ELLIPSIS_CLASS_NAMES, 'text-primary-active hover:text-primary-light active:text-aqua-pale ml-auto cursor-pointer'),
|
|
3865
4160
|
onClick: cancelAllUploads
|
|
3866
4161
|
}, "Cancel All Uploads")));
|
|
3867
4162
|
};
|
|
3868
4163
|
const getShowFailedOnlyIconComponent = () => {
|
|
3869
4164
|
return /*#__PURE__*/react.createElement("div", {
|
|
3870
|
-
className: "ml-auto flex justify-center
|
|
4165
|
+
className: "ml-auto flex w-6 justify-center"
|
|
3871
4166
|
}, numFails > 0 && /*#__PURE__*/react.createElement("div", {
|
|
3872
4167
|
onClick: () => setShowFailedOnly(currentShowFailedOnly => !currentShowFailedOnly)
|
|
3873
4168
|
}, /*#__PURE__*/react.createElement(ui_src/* Icon */.JO, {
|
|
@@ -3877,28 +4172,28 @@ function DicomUploadProgress(_ref) {
|
|
|
3877
4172
|
};
|
|
3878
4173
|
const getPercentCompleteComponent = () => {
|
|
3879
4174
|
return /*#__PURE__*/react.createElement("div", {
|
|
3880
|
-
className: "overflow-y-scroll
|
|
4175
|
+
className: "ohif-scrollbar border-secondary-light overflow-y-scroll border-b px-2"
|
|
3881
4176
|
}, /*#__PURE__*/react.createElement("div", {
|
|
3882
|
-
className: "flex w-full p-2.5
|
|
4177
|
+
className: "min-h-14 flex w-full items-center p-2.5"
|
|
3883
4178
|
}, numFilesCompleted === dicomFileUploaderArr.length ? /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
3884
|
-
className: "text-
|
|
4179
|
+
className: "text-primary-light text-xl"
|
|
3885
4180
|
}, numFails > 0 ? `Completed with ${numFails} ${numFails > 1 ? 'errors' : 'error'}!` : 'Completed!'), getShowFailedOnlyIconComponent()) : /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
3886
4181
|
ref: progressBarContainerRef,
|
|
3887
4182
|
className: "flex-grow"
|
|
3888
4183
|
}, /*#__PURE__*/react.createElement(ui_src/* ProgressLoadingBar */.YE, {
|
|
3889
4184
|
progress: showInfiniteProgressBar() ? undefined : Math.min(100, percentComplete)
|
|
3890
4185
|
})), /*#__PURE__*/react.createElement("div", {
|
|
3891
|
-
className: "
|
|
4186
|
+
className: "ml-1 flex w-24 items-center"
|
|
3892
4187
|
}, /*#__PURE__*/react.createElement("div", {
|
|
3893
4188
|
className: "w-10 text-right"
|
|
3894
4189
|
}, `${getPercentCompleteRounded()}%`), getShowFailedOnlyIconComponent()))));
|
|
3895
4190
|
};
|
|
3896
4191
|
return /*#__PURE__*/react.createElement("div", {
|
|
3897
|
-
className: "flex flex-col
|
|
4192
|
+
className: "flex grow flex-col"
|
|
3898
4193
|
}, getNumCompletedAndTimeRemainingComponent(), /*#__PURE__*/react.createElement("div", {
|
|
3899
|
-
className: "flex flex-col bg-black text-lg
|
|
4194
|
+
className: "flex grow flex-col overflow-hidden bg-black text-lg"
|
|
3900
4195
|
}, getPercentCompleteComponent(), /*#__PURE__*/react.createElement("div", {
|
|
3901
|
-
className: "overflow-y-scroll
|
|
4196
|
+
className: "ohif-scrollbar h-1 grow overflow-y-scroll px-2"
|
|
3902
4197
|
}, dicomFileUploaderArr.filter(dicomFileUploader => !showFailedOnly || dicomFileUploader.getStatus() === UploadStatus.Failed).map(dicomFileUploader => /*#__PURE__*/react.createElement(DicomUpload_DicomUploadProgressItem, {
|
|
3903
4198
|
key: dicomFileUploader.getFileId(),
|
|
3904
4199
|
dicomFileUploader: dicomFileUploader
|
|
@@ -3945,7 +4240,7 @@ function DicomUpload(_ref) {
|
|
|
3945
4240
|
getRootProps
|
|
3946
4241
|
} = _ref2;
|
|
3947
4242
|
return /*#__PURE__*/react.createElement("div", _extends({}, getRootProps(), {
|
|
3948
|
-
className: "
|
|
4243
|
+
className: "dicom-upload-drop-area-border-dash m-5 flex h-full flex-col items-center justify-center"
|
|
3949
4244
|
}), /*#__PURE__*/react.createElement("div", {
|
|
3950
4245
|
className: "flex gap-3"
|
|
3951
4246
|
}, /*#__PURE__*/react.createElement(es/* default */.Z, {
|
|
@@ -3969,7 +4264,7 @@ function DicomUpload(_ref) {
|
|
|
3969
4264
|
getInputProps
|
|
3970
4265
|
} = _ref4;
|
|
3971
4266
|
return /*#__PURE__*/react.createElement("div", getRootProps(), /*#__PURE__*/react.createElement(ui_src/* Button */.zx, {
|
|
3972
|
-
type: ui_src/* ButtonEnums.type */.LZ.
|
|
4267
|
+
type: ui_src/* ButtonEnums.type */.LZ.dt.secondary,
|
|
3973
4268
|
disabled: false,
|
|
3974
4269
|
onClick: () => {}
|
|
3975
4270
|
}, 'Add folder', /*#__PURE__*/react.createElement("input", _extends({}, getInputProps(), {
|
|
@@ -3979,7 +4274,7 @@ function DicomUpload(_ref) {
|
|
|
3979
4274
|
})), /*#__PURE__*/react.createElement("div", {
|
|
3980
4275
|
className: "pt-5"
|
|
3981
4276
|
}, "or drag images or folders here"), /*#__PURE__*/react.createElement("div", {
|
|
3982
|
-
className: "
|
|
4277
|
+
className: "text-aqua-pale pt-3 text-lg"
|
|
3983
4278
|
}, "(DICOM files supported)"));
|
|
3984
4279
|
});
|
|
3985
4280
|
};
|
|
@@ -4043,7 +4338,7 @@ function getCustomizationModule() {
|
|
|
4043
4338
|
}
|
|
4044
4339
|
/* harmony default export */ const src_getCustomizationModule = (getCustomizationModule);
|
|
4045
4340
|
// EXTERNAL MODULE: ../../../node_modules/html2canvas/dist/html2canvas.esm.js
|
|
4046
|
-
var html2canvas_esm = __webpack_require__(
|
|
4341
|
+
var html2canvas_esm = __webpack_require__(76010);
|
|
4047
4342
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/CornerstoneViewportDownloadForm.tsx
|
|
4048
4343
|
|
|
4049
4344
|
|
|
@@ -4059,10 +4354,10 @@ const VIEWPORT_ID = 'cornerstone-viewport-download-form';
|
|
|
4059
4354
|
const CornerstoneViewportDownloadForm = _ref => {
|
|
4060
4355
|
let {
|
|
4061
4356
|
onClose,
|
|
4062
|
-
|
|
4357
|
+
activeViewportId: activeViewportIdProp,
|
|
4063
4358
|
cornerstoneViewportService
|
|
4064
4359
|
} = _ref;
|
|
4065
|
-
const enabledElement = (0,state/* getEnabledElement */.K8)(
|
|
4360
|
+
const enabledElement = (0,state/* getEnabledElement */.K8)(activeViewportIdProp);
|
|
4066
4361
|
const activeViewportElement = enabledElement?.element;
|
|
4067
4362
|
const activeViewportEnabledElement = (0,esm.getEnabledElement)(activeViewportElement);
|
|
4068
4363
|
const {
|
|
@@ -4181,13 +4476,18 @@ const CornerstoneViewportDownloadForm = _ref => {
|
|
|
4181
4476
|
const imageId = viewport.getCurrentImageId();
|
|
4182
4477
|
const properties = viewport.getProperties();
|
|
4183
4478
|
downloadViewport.setStack([imageId]).then(() => {
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4479
|
+
try {
|
|
4480
|
+
downloadViewport.setProperties(properties);
|
|
4481
|
+
const newWidth = Math.min(width || image.width, MAX_TEXTURE_SIZE);
|
|
4482
|
+
const newHeight = Math.min(height || image.height, MAX_TEXTURE_SIZE);
|
|
4483
|
+
resolve({
|
|
4484
|
+
width: newWidth,
|
|
4485
|
+
height: newHeight
|
|
4486
|
+
});
|
|
4487
|
+
} catch (e) {
|
|
4488
|
+
// Happens on clicking the cancel button
|
|
4489
|
+
console.warn('Unable to set properties', e);
|
|
4490
|
+
}
|
|
4191
4491
|
});
|
|
4192
4492
|
} else if (downloadViewport instanceof esm.VolumeViewport) {
|
|
4193
4493
|
const actors = viewport.getActors();
|
|
@@ -4264,74 +4564,75 @@ const CornerstoneViewportDownloadForm = _ref => {
|
|
|
4264
4564
|
};
|
|
4265
4565
|
CornerstoneViewportDownloadForm.propTypes = {
|
|
4266
4566
|
onClose: (prop_types_default()).func,
|
|
4267
|
-
|
|
4567
|
+
activeViewportId: (prop_types_default()).string.isRequired
|
|
4268
4568
|
};
|
|
4269
4569
|
/* harmony default export */ const utils_CornerstoneViewportDownloadForm = (CornerstoneViewportDownloadForm);
|
|
4270
|
-
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/stackSync/calculateViewportRegistrations.ts
|
|
4271
|
-
|
|
4272
|
-
function calculateViewportRegistrations(viewports) {
|
|
4273
|
-
const viewportPairs = _getViewportPairs(viewports);
|
|
4274
|
-
for (const [viewport, nextViewport] of viewportPairs) {
|
|
4275
|
-
// check if they are in the same Frame of Reference
|
|
4276
|
-
const renderingEngine1 = (0,esm.getRenderingEngine)(viewport.renderingEngineId);
|
|
4277
|
-
const renderingEngine2 = (0,esm.getRenderingEngine)(nextViewport.renderingEngineId);
|
|
4278
|
-
const csViewport1 = renderingEngine1.getViewport(viewport.viewportId);
|
|
4279
|
-
const csViewport2 = renderingEngine2.getViewport(nextViewport.viewportId);
|
|
4280
|
-
esm.utilities.calculateViewportsSpatialRegistration(csViewport1, csViewport2);
|
|
4281
|
-
}
|
|
4282
|
-
}
|
|
4283
|
-
const _getViewportPairs = viewports => {
|
|
4284
|
-
const viewportPairs = [];
|
|
4285
|
-
for (let i = 0; i < viewports.length; i++) {
|
|
4286
|
-
for (let j = i + 1; j < viewports.length; j++) {
|
|
4287
|
-
viewportPairs.push([viewports[i], viewports[j]]);
|
|
4288
|
-
}
|
|
4289
|
-
}
|
|
4290
|
-
return viewportPairs;
|
|
4291
|
-
};
|
|
4292
4570
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/stackSync/toggleStackImageSync.ts
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
// [ {
|
|
4296
|
-
// synchronizerId: string,
|
|
4297
|
-
// viewports: [ { viewportId: number, renderingEngineId: string, index: number } , ...]
|
|
4298
|
-
// ]}
|
|
4299
|
-
let STACK_IMAGE_SYNC_GROUPS_INFO = [];
|
|
4571
|
+
const STACK_SYNC_NAME = 'stackImageSync';
|
|
4300
4572
|
function toggleStackImageSync(_ref) {
|
|
4301
4573
|
let {
|
|
4302
4574
|
toggledState,
|
|
4303
4575
|
servicesManager,
|
|
4304
|
-
|
|
4576
|
+
viewports: providedViewports
|
|
4305
4577
|
} = _ref;
|
|
4578
|
+
if (!toggledState) {
|
|
4579
|
+
return disableSync(STACK_SYNC_NAME, servicesManager);
|
|
4580
|
+
}
|
|
4306
4581
|
const {
|
|
4307
4582
|
syncGroupService,
|
|
4308
4583
|
viewportGridService,
|
|
4309
4584
|
displaySetService,
|
|
4310
4585
|
cornerstoneViewportService
|
|
4311
4586
|
} = servicesManager.services;
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4587
|
+
const viewports = providedViewports || getReconstructableStackViewports(viewportGridService, displaySetService);
|
|
4588
|
+
|
|
4589
|
+
// create synchronization group and add the viewports to it.
|
|
4590
|
+
viewports.forEach(gridViewport => {
|
|
4591
|
+
const {
|
|
4592
|
+
viewportId
|
|
4593
|
+
} = gridViewport.viewportOptions;
|
|
4594
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
4595
|
+
if (!viewport) {
|
|
4596
|
+
return;
|
|
4597
|
+
}
|
|
4598
|
+
syncGroupService.addViewportToSyncGroup(viewportId, viewport.getRenderingEngine().id, {
|
|
4599
|
+
type: 'stackimage',
|
|
4600
|
+
id: STACK_SYNC_NAME,
|
|
4601
|
+
source: true,
|
|
4602
|
+
target: true
|
|
4325
4603
|
});
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4604
|
+
});
|
|
4605
|
+
}
|
|
4606
|
+
function disableSync(syncName, servicesManager) {
|
|
4607
|
+
const {
|
|
4608
|
+
syncGroupService,
|
|
4609
|
+
viewportGridService,
|
|
4610
|
+
displaySetService,
|
|
4611
|
+
cornerstoneViewportService
|
|
4612
|
+
} = servicesManager.services;
|
|
4613
|
+
const viewports = getReconstructableStackViewports(viewportGridService, displaySetService);
|
|
4614
|
+
viewports.forEach(gridViewport => {
|
|
4615
|
+
const {
|
|
4616
|
+
viewportId
|
|
4617
|
+
} = gridViewport.viewportOptions;
|
|
4618
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
4619
|
+
if (!viewport) {
|
|
4620
|
+
return;
|
|
4621
|
+
}
|
|
4622
|
+
syncGroupService.removeViewportFromSyncGroup(viewport.id, viewport.getRenderingEngine().id, syncName);
|
|
4623
|
+
});
|
|
4624
|
+
}
|
|
4625
|
+
;
|
|
4329
4626
|
|
|
4330
|
-
|
|
4627
|
+
/**
|
|
4628
|
+
* Gets the consistent spacing stack viewport types, which are the ones which
|
|
4629
|
+
* can be navigated using the stack image sync right now.
|
|
4630
|
+
*/
|
|
4631
|
+
function getReconstructableStackViewports(viewportGridService, displaySetService) {
|
|
4331
4632
|
let {
|
|
4332
4633
|
viewports
|
|
4333
4634
|
} = viewportGridService.getState();
|
|
4334
|
-
|
|
4635
|
+
viewports = [...viewports.values()];
|
|
4335
4636
|
// filter empty viewports
|
|
4336
4637
|
viewports = viewports.filter(viewport => viewport.displaySetInstanceUIDs && viewport.displaySetInstanceUIDs.length);
|
|
4337
4638
|
|
|
@@ -4342,72 +4643,17 @@ function toggleStackImageSync(_ref) {
|
|
|
4342
4643
|
} = viewport;
|
|
4343
4644
|
for (const displaySetInstanceUID of displaySetInstanceUIDs) {
|
|
4344
4645
|
const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
|
|
4646
|
+
|
|
4647
|
+
// TODO - add a better test than isReconstructable
|
|
4345
4648
|
if (displaySet && displaySet.isReconstructable) {
|
|
4346
4649
|
return true;
|
|
4347
4650
|
}
|
|
4348
4651
|
return false;
|
|
4349
4652
|
}
|
|
4350
4653
|
});
|
|
4351
|
-
|
|
4352
|
-
const {
|
|
4353
|
-
viewportId,
|
|
4354
|
-
viewportType
|
|
4355
|
-
} = viewport.viewportOptions;
|
|
4356
|
-
if (viewportType !== 'stack') {
|
|
4357
|
-
console.warn('Viewport is not a stack, cannot sync images yet');
|
|
4358
|
-
return acc;
|
|
4359
|
-
}
|
|
4360
|
-
const {
|
|
4361
|
-
element
|
|
4362
|
-
} = cornerstoneViewportService.getViewportInfo(viewportId);
|
|
4363
|
-
const {
|
|
4364
|
-
viewport: csViewport,
|
|
4365
|
-
renderingEngineId
|
|
4366
|
-
} = getEnabledElement(element);
|
|
4367
|
-
const {
|
|
4368
|
-
viewPlaneNormal
|
|
4369
|
-
} = csViewport.getCamera();
|
|
4370
|
-
|
|
4371
|
-
// Should we round here? I guess so, but not sure how much precision we need
|
|
4372
|
-
const orientation = viewPlaneNormal.map(v => Math.round(v)).join(',');
|
|
4373
|
-
if (!acc[orientation]) {
|
|
4374
|
-
acc[orientation] = [];
|
|
4375
|
-
}
|
|
4376
|
-
acc[orientation].push({
|
|
4377
|
-
viewportId,
|
|
4378
|
-
renderingEngineId
|
|
4379
|
-
});
|
|
4380
|
-
return acc;
|
|
4381
|
-
}, {});
|
|
4382
|
-
|
|
4383
|
-
// create synchronizer for each group
|
|
4384
|
-
Object.values(viewportsByOrientation).map(viewports => {
|
|
4385
|
-
let synchronizerId = viewports.map(_ref3 => {
|
|
4386
|
-
let {
|
|
4387
|
-
viewportId
|
|
4388
|
-
} = _ref3;
|
|
4389
|
-
return viewportId;
|
|
4390
|
-
}).join(',');
|
|
4391
|
-
synchronizerId = `imageSync_${synchronizerId}`;
|
|
4392
|
-
calculateViewportRegistrations(viewports);
|
|
4393
|
-
viewports.forEach(_ref4 => {
|
|
4394
|
-
let {
|
|
4395
|
-
viewportId,
|
|
4396
|
-
renderingEngineId
|
|
4397
|
-
} = _ref4;
|
|
4398
|
-
syncGroupService.addViewportToSyncGroup(viewportId, renderingEngineId, {
|
|
4399
|
-
type: 'stackimage',
|
|
4400
|
-
id: synchronizerId,
|
|
4401
|
-
source: true,
|
|
4402
|
-
target: true
|
|
4403
|
-
});
|
|
4404
|
-
});
|
|
4405
|
-
STACK_IMAGE_SYNC_GROUPS_INFO.push({
|
|
4406
|
-
synchronizerId,
|
|
4407
|
-
viewports
|
|
4408
|
-
});
|
|
4409
|
-
});
|
|
4654
|
+
return viewports;
|
|
4410
4655
|
}
|
|
4656
|
+
;
|
|
4411
4657
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/utils/selection.ts
|
|
4412
4658
|
|
|
4413
4659
|
|
|
@@ -4457,6 +4703,7 @@ function commandsModule(_ref) {
|
|
|
4457
4703
|
toolGroupService,
|
|
4458
4704
|
cineService,
|
|
4459
4705
|
toolbarService,
|
|
4706
|
+
stateSyncService,
|
|
4460
4707
|
uiDialogService,
|
|
4461
4708
|
cornerstoneViewportService,
|
|
4462
4709
|
uiNotificationService,
|
|
@@ -4650,8 +4897,7 @@ function commandsModule(_ref) {
|
|
|
4650
4897
|
console.warn('No viewport found for viewportId:', viewportId);
|
|
4651
4898
|
return;
|
|
4652
4899
|
}
|
|
4653
|
-
|
|
4654
|
-
viewportGridService.setActiveViewportIndex(viewportIndex);
|
|
4900
|
+
viewportGridService.setActiveViewportId(viewportId);
|
|
4655
4901
|
},
|
|
4656
4902
|
arrowTextCallback: _ref7 => {
|
|
4657
4903
|
let {
|
|
@@ -4716,10 +4962,16 @@ function commandsModule(_ref) {
|
|
|
4716
4962
|
toolbarServiceRecordInteraction: props => {
|
|
4717
4963
|
toolbarService.recordInteraction(props);
|
|
4718
4964
|
},
|
|
4965
|
+
// Enable or disable a toggleable command, without calling the activation
|
|
4966
|
+
// Used to setup already active tools from hanging protocols
|
|
4967
|
+
setToolbarToggled: props => {
|
|
4968
|
+
toolbarService.setToggled(props.toolId, props.isActive ?? true);
|
|
4969
|
+
},
|
|
4719
4970
|
setToolActive: _ref9 => {
|
|
4720
4971
|
let {
|
|
4721
4972
|
toolName,
|
|
4722
|
-
toolGroupId = null
|
|
4973
|
+
toolGroupId = null,
|
|
4974
|
+
toggledState
|
|
4723
4975
|
} = _ref9;
|
|
4724
4976
|
if (toolName === 'Crosshairs') {
|
|
4725
4977
|
const activeViewportToolGroup = toolGroupService.getToolGroup(null);
|
|
@@ -4735,9 +4987,10 @@ function commandsModule(_ref) {
|
|
|
4735
4987
|
}
|
|
4736
4988
|
const {
|
|
4737
4989
|
viewports
|
|
4738
|
-
} = viewportGridService.getState()
|
|
4739
|
-
|
|
4740
|
-
|
|
4990
|
+
} = viewportGridService.getState();
|
|
4991
|
+
if (!viewports.size) {
|
|
4992
|
+
return;
|
|
4993
|
+
}
|
|
4741
4994
|
const toolGroup = toolGroupService.getToolGroup(toolGroupId);
|
|
4742
4995
|
const toolGroupViewportIds = toolGroup?.getViewportIds?.();
|
|
4743
4996
|
|
|
@@ -4745,11 +4998,8 @@ function commandsModule(_ref) {
|
|
|
4745
4998
|
if (!toolGroupViewportIds || !toolGroupViewportIds.length) {
|
|
4746
4999
|
return;
|
|
4747
5000
|
}
|
|
4748
|
-
const filteredViewports = viewports.filter(viewport => {
|
|
4749
|
-
|
|
4750
|
-
return false;
|
|
4751
|
-
}
|
|
4752
|
-
return toolGroupViewportIds.includes(viewport.viewportOptions.viewportId);
|
|
5001
|
+
const filteredViewports = Array.from(viewports.values()).filter(viewport => {
|
|
5002
|
+
return toolGroupViewportIds.includes(viewport.viewportId);
|
|
4753
5003
|
});
|
|
4754
5004
|
if (!filteredViewports.length) {
|
|
4755
5005
|
return;
|
|
@@ -4773,6 +5023,14 @@ function commandsModule(_ref) {
|
|
|
4773
5023
|
toolGroup.setToolPassive(activeToolName);
|
|
4774
5024
|
}
|
|
4775
5025
|
}
|
|
5026
|
+
|
|
5027
|
+
// If there is a toggle state, then simply set the enabled/disabled state without
|
|
5028
|
+
// setting the tool active.
|
|
5029
|
+
if (toggledState != null) {
|
|
5030
|
+
toggledState ? toolGroup.setToolEnabled(toolName) : toolGroup.setToolDisabled(toolName);
|
|
5031
|
+
return;
|
|
5032
|
+
}
|
|
5033
|
+
|
|
4776
5034
|
// Set the new toolName to be active
|
|
4777
5035
|
toolGroup.setToolActive(toolName, {
|
|
4778
5036
|
bindings: [{
|
|
@@ -4782,9 +5040,9 @@ function commandsModule(_ref) {
|
|
|
4782
5040
|
},
|
|
4783
5041
|
showDownloadViewportModal: () => {
|
|
4784
5042
|
const {
|
|
4785
|
-
|
|
5043
|
+
activeViewportId
|
|
4786
5044
|
} = viewportGridService.getState();
|
|
4787
|
-
if (!cornerstoneViewportService.
|
|
5045
|
+
if (!cornerstoneViewportService.getCornerstoneViewport(activeViewportId)) {
|
|
4788
5046
|
// Cannot download a non-cornerstone viewport (image).
|
|
4789
5047
|
uiNotificationService.show({
|
|
4790
5048
|
title: 'Download Image',
|
|
@@ -4801,7 +5059,7 @@ function commandsModule(_ref) {
|
|
|
4801
5059
|
content: utils_CornerstoneViewportDownloadForm,
|
|
4802
5060
|
title: 'Download High Quality Image',
|
|
4803
5061
|
contentProps: {
|
|
4804
|
-
|
|
5062
|
+
activeViewportId,
|
|
4805
5063
|
onClose: uiModalService.hide,
|
|
4806
5064
|
cornerstoneViewportService
|
|
4807
5065
|
}
|
|
@@ -4882,15 +5140,13 @@ function commandsModule(_ref) {
|
|
|
4882
5140
|
const {
|
|
4883
5141
|
viewport
|
|
4884
5142
|
} = enabledElement;
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
viewport.render();
|
|
4893
|
-
}
|
|
5143
|
+
const {
|
|
5144
|
+
invert
|
|
5145
|
+
} = viewport.getProperties();
|
|
5146
|
+
viewport.setProperties({
|
|
5147
|
+
invert: !invert
|
|
5148
|
+
});
|
|
5149
|
+
viewport.render();
|
|
4894
5150
|
},
|
|
4895
5151
|
resetViewport: () => {
|
|
4896
5152
|
const enabledElement = _getActiveViewportEnabledElement();
|
|
@@ -4993,12 +5249,12 @@ function commandsModule(_ref) {
|
|
|
4993
5249
|
},
|
|
4994
5250
|
setViewportColormap: _ref15 => {
|
|
4995
5251
|
let {
|
|
4996
|
-
|
|
5252
|
+
viewportId,
|
|
4997
5253
|
displaySetInstanceUID,
|
|
4998
5254
|
colormap,
|
|
4999
5255
|
immediate = false
|
|
5000
5256
|
} = _ref15;
|
|
5001
|
-
const viewport = cornerstoneViewportService.
|
|
5257
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
5002
5258
|
const actorEntries = viewport.getActors();
|
|
5003
5259
|
const actorEntry = actorEntries.find(actorEntry => {
|
|
5004
5260
|
return actorEntry.uid.includes(displaySetInstanceUID);
|
|
@@ -5015,51 +5271,53 @@ function commandsModule(_ref) {
|
|
|
5015
5271
|
viewport.render();
|
|
5016
5272
|
}
|
|
5017
5273
|
},
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
} = viewportGridService.getState();
|
|
5023
|
-
const nextViewportIndex = (activeViewportIndex + 1) % viewports.length;
|
|
5024
|
-
viewportGridService.setActiveViewportIndex(nextViewportIndex);
|
|
5025
|
-
},
|
|
5026
|
-
decrementActiveViewport: () => {
|
|
5274
|
+
changeActiveViewport: _ref16 => {
|
|
5275
|
+
let {
|
|
5276
|
+
direction = 1
|
|
5277
|
+
} = _ref16;
|
|
5027
5278
|
const {
|
|
5028
|
-
|
|
5279
|
+
activeViewportId,
|
|
5029
5280
|
viewports
|
|
5030
5281
|
} = viewportGridService.getState();
|
|
5031
|
-
const
|
|
5032
|
-
|
|
5282
|
+
const viewportIds = Array.from(viewports.keys());
|
|
5283
|
+
const currentIndex = viewportIds.indexOf(activeViewportId);
|
|
5284
|
+
const nextViewportIndex = (currentIndex + direction + viewportIds.length) % viewportIds.length;
|
|
5285
|
+
viewportGridService.setActiveViewportId(viewportIds[nextViewportIndex]);
|
|
5033
5286
|
},
|
|
5034
|
-
toggleStackImageSync:
|
|
5287
|
+
toggleStackImageSync: _ref17 => {
|
|
5035
5288
|
let {
|
|
5036
5289
|
toggledState
|
|
5037
|
-
} =
|
|
5290
|
+
} = _ref17;
|
|
5038
5291
|
toggleStackImageSync({
|
|
5039
|
-
getEnabledElement: esm.getEnabledElement,
|
|
5040
5292
|
servicesManager,
|
|
5041
5293
|
toggledState
|
|
5042
5294
|
});
|
|
5043
5295
|
},
|
|
5044
|
-
|
|
5296
|
+
setSourceViewportForReferenceLinesTool: _ref18 => {
|
|
5045
5297
|
let {
|
|
5046
|
-
toggledState
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
if (!toggledState) {
|
|
5055
|
-
toolGroup.setToolDisabled(dist_esm.ReferenceLinesTool.toolName);
|
|
5298
|
+
toggledState,
|
|
5299
|
+
viewportId
|
|
5300
|
+
} = _ref18;
|
|
5301
|
+
if (!viewportId) {
|
|
5302
|
+
const {
|
|
5303
|
+
activeViewportId
|
|
5304
|
+
} = viewportGridService.getState();
|
|
5305
|
+
viewportId = activeViewportId;
|
|
5056
5306
|
}
|
|
5307
|
+
const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
|
|
5057
5308
|
toolGroup.setToolConfiguration(dist_esm.ReferenceLinesTool.toolName, {
|
|
5058
5309
|
sourceViewportId: viewportId
|
|
5059
5310
|
}, true // overwrite
|
|
5060
5311
|
);
|
|
5312
|
+
},
|
|
5061
5313
|
|
|
5062
|
-
|
|
5314
|
+
storePresentation: _ref19 => {
|
|
5315
|
+
let {
|
|
5316
|
+
viewportId
|
|
5317
|
+
} = _ref19;
|
|
5318
|
+
cornerstoneViewportService.storePresentation({
|
|
5319
|
+
viewportId
|
|
5320
|
+
});
|
|
5063
5321
|
}
|
|
5064
5322
|
};
|
|
5065
5323
|
const definitions = {
|
|
@@ -5114,10 +5372,13 @@ function commandsModule(_ref) {
|
|
|
5114
5372
|
}
|
|
5115
5373
|
},
|
|
5116
5374
|
incrementActiveViewport: {
|
|
5117
|
-
commandFn: actions.
|
|
5375
|
+
commandFn: actions.changeActiveViewport
|
|
5118
5376
|
},
|
|
5119
5377
|
decrementActiveViewport: {
|
|
5120
|
-
commandFn: actions.
|
|
5378
|
+
commandFn: actions.changeActiveViewport,
|
|
5379
|
+
options: {
|
|
5380
|
+
direction: -1
|
|
5381
|
+
}
|
|
5121
5382
|
},
|
|
5122
5383
|
flipViewportHorizontal: {
|
|
5123
5384
|
commandFn: actions.flipViewportHorizontal
|
|
@@ -5194,8 +5455,14 @@ function commandsModule(_ref) {
|
|
|
5194
5455
|
toggleStackImageSync: {
|
|
5195
5456
|
commandFn: actions.toggleStackImageSync
|
|
5196
5457
|
},
|
|
5197
|
-
|
|
5198
|
-
commandFn: actions.
|
|
5458
|
+
setSourceViewportForReferenceLinesTool: {
|
|
5459
|
+
commandFn: actions.setSourceViewportForReferenceLinesTool
|
|
5460
|
+
},
|
|
5461
|
+
storePresentation: {
|
|
5462
|
+
commandFn: actions.storePresentation
|
|
5463
|
+
},
|
|
5464
|
+
setToolbarToggled: {
|
|
5465
|
+
commandFn: actions.setToolbarToggled
|
|
5199
5466
|
}
|
|
5200
5467
|
};
|
|
5201
5468
|
return {
|
|
@@ -5210,9 +5477,8 @@ const mpr = {
|
|
|
5210
5477
|
id: 'mpr',
|
|
5211
5478
|
name: 'Multi-Planar Reconstruction',
|
|
5212
5479
|
locked: true,
|
|
5213
|
-
hasUpdatedPriorsInformation: false,
|
|
5214
5480
|
createdDate: '2021-02-23',
|
|
5215
|
-
modifiedDate: '2023-
|
|
5481
|
+
modifiedDate: '2023-08-15',
|
|
5216
5482
|
availableTo: {},
|
|
5217
5483
|
editableBy: {},
|
|
5218
5484
|
// Unknown number of priors referenced - so just match any study
|
|
@@ -5283,6 +5549,7 @@ const mpr = {
|
|
|
5283
5549
|
},
|
|
5284
5550
|
viewports: [{
|
|
5285
5551
|
viewportOptions: {
|
|
5552
|
+
viewportId: 'mpr-axial',
|
|
5286
5553
|
toolGroupId: 'mpr',
|
|
5287
5554
|
viewportType: 'volume',
|
|
5288
5555
|
orientation: 'axial',
|
|
@@ -5301,6 +5568,7 @@ const mpr = {
|
|
|
5301
5568
|
}]
|
|
5302
5569
|
}, {
|
|
5303
5570
|
viewportOptions: {
|
|
5571
|
+
viewportId: 'mpr-sagittal',
|
|
5304
5572
|
toolGroupId: 'mpr',
|
|
5305
5573
|
viewportType: 'volume',
|
|
5306
5574
|
orientation: 'sagittal',
|
|
@@ -5319,6 +5587,7 @@ const mpr = {
|
|
|
5319
5587
|
}]
|
|
5320
5588
|
}, {
|
|
5321
5589
|
viewportOptions: {
|
|
5590
|
+
viewportId: 'mpr-coronal',
|
|
5322
5591
|
toolGroupId: 'mpr',
|
|
5323
5592
|
viewportType: 'volume',
|
|
5324
5593
|
orientation: 'coronal',
|
|
@@ -5341,7 +5610,6 @@ const mpr = {
|
|
|
5341
5610
|
const mprAnd3DVolumeViewport = {
|
|
5342
5611
|
id: 'mprAnd3DVolumeViewport',
|
|
5343
5612
|
locked: true,
|
|
5344
|
-
hasUpdatedPriorsInformation: false,
|
|
5345
5613
|
name: 'mpr',
|
|
5346
5614
|
createdDate: '2023-03-15T10:29:44.894Z',
|
|
5347
5615
|
modifiedDate: '2023-03-15T10:29:44.894Z',
|
|
@@ -5530,9 +5798,9 @@ class ToolGroupService {
|
|
|
5530
5798
|
return dist_esm.ToolGroupManager.getToolGroupForViewport(viewportId, renderingEngine.id);
|
|
5531
5799
|
}
|
|
5532
5800
|
getActiveToolForViewport(viewportId) {
|
|
5533
|
-
const toolGroup =
|
|
5801
|
+
const toolGroup = this.getToolGroupForViewport(viewportId);
|
|
5534
5802
|
if (!toolGroup) {
|
|
5535
|
-
return
|
|
5803
|
+
return;
|
|
5536
5804
|
}
|
|
5537
5805
|
return toolGroup.getActivePrimaryMouseButtonTool();
|
|
5538
5806
|
}
|
|
@@ -5595,9 +5863,8 @@ class ToolGroupService {
|
|
|
5595
5863
|
this._setToolsMode(toolGroup, tools);
|
|
5596
5864
|
}
|
|
5597
5865
|
createToolGroupAndAddTools(toolGroupId, tools) {
|
|
5598
|
-
let configs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
5599
5866
|
const toolGroup = this.createToolGroup(toolGroupId);
|
|
5600
|
-
this.addToolsToToolGroup(toolGroupId, tools
|
|
5867
|
+
this.addToolsToToolGroup(toolGroupId, tools);
|
|
5601
5868
|
return toolGroup;
|
|
5602
5869
|
}
|
|
5603
5870
|
|
|
@@ -5643,30 +5910,6 @@ class ToolGroupService {
|
|
|
5643
5910
|
const toolInstance = toolGroup.getToolInstance(toolName);
|
|
5644
5911
|
toolInstance.configuration = config;
|
|
5645
5912
|
}
|
|
5646
|
-
_getToolNames(toolGroupTools) {
|
|
5647
|
-
const toolNames = [];
|
|
5648
|
-
if (toolGroupTools.active) {
|
|
5649
|
-
toolGroupTools.active.forEach(tool => {
|
|
5650
|
-
toolNames.push(tool.toolName);
|
|
5651
|
-
});
|
|
5652
|
-
}
|
|
5653
|
-
if (toolGroupTools.passive) {
|
|
5654
|
-
toolGroupTools.passive.forEach(tool => {
|
|
5655
|
-
toolNames.push(tool.toolName);
|
|
5656
|
-
});
|
|
5657
|
-
}
|
|
5658
|
-
if (toolGroupTools.enabled) {
|
|
5659
|
-
toolGroupTools.enabled.forEach(tool => {
|
|
5660
|
-
toolNames.push(tool.toolName);
|
|
5661
|
-
});
|
|
5662
|
-
}
|
|
5663
|
-
if (toolGroupTools.disabled) {
|
|
5664
|
-
toolGroupTools.disabled.forEach(tool => {
|
|
5665
|
-
toolNames.push(tool.toolName);
|
|
5666
|
-
});
|
|
5667
|
-
}
|
|
5668
|
-
return toolNames;
|
|
5669
|
-
}
|
|
5670
5913
|
_setToolsMode(toolGroup, tools) {
|
|
5671
5914
|
const {
|
|
5672
5915
|
active,
|
|
@@ -5710,29 +5953,46 @@ class ToolGroupService {
|
|
|
5710
5953
|
});
|
|
5711
5954
|
}
|
|
5712
5955
|
}
|
|
5713
|
-
_addTools(toolGroup, tools
|
|
5714
|
-
const
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5956
|
+
_addTools(toolGroup, tools) {
|
|
5957
|
+
const addTools = tools => {
|
|
5958
|
+
tools.forEach(_ref5 => {
|
|
5959
|
+
let {
|
|
5960
|
+
toolName,
|
|
5961
|
+
parentTool,
|
|
5962
|
+
configuration
|
|
5963
|
+
} = _ref5;
|
|
5964
|
+
if (parentTool) {
|
|
5965
|
+
toolGroup.addToolInstance(toolName, parentTool, {
|
|
5966
|
+
...configuration
|
|
5967
|
+
});
|
|
5968
|
+
} else {
|
|
5969
|
+
toolGroup.addTool(toolName, {
|
|
5970
|
+
...configuration
|
|
5971
|
+
});
|
|
5972
|
+
}
|
|
5725
5973
|
});
|
|
5726
|
-
}
|
|
5974
|
+
};
|
|
5975
|
+
if (tools.active) {
|
|
5976
|
+
addTools(tools.active);
|
|
5977
|
+
}
|
|
5978
|
+
if (tools.passive) {
|
|
5979
|
+
addTools(tools.passive);
|
|
5980
|
+
}
|
|
5981
|
+
if (tools.enabled) {
|
|
5982
|
+
addTools(tools.enabled);
|
|
5983
|
+
}
|
|
5984
|
+
if (tools.disabled) {
|
|
5985
|
+
addTools(tools.disabled);
|
|
5986
|
+
}
|
|
5727
5987
|
}
|
|
5728
5988
|
}
|
|
5729
5989
|
ToolGroupService.REGISTRATION = {
|
|
5730
5990
|
name: 'toolGroupService',
|
|
5731
5991
|
altName: 'ToolGroupService',
|
|
5732
|
-
create:
|
|
5992
|
+
create: _ref6 => {
|
|
5733
5993
|
let {
|
|
5734
5994
|
servicesManager
|
|
5735
|
-
} =
|
|
5995
|
+
} = _ref6;
|
|
5736
5996
|
return new ToolGroupService(servicesManager);
|
|
5737
5997
|
}
|
|
5738
5998
|
};
|
|
@@ -5789,7 +6049,7 @@ class SyncGroupService {
|
|
|
5789
6049
|
* @param type is the type of the synchronizer to create
|
|
5790
6050
|
* @param creator
|
|
5791
6051
|
*/
|
|
5792
|
-
|
|
6052
|
+
addSynchronizerType(type, creator) {
|
|
5793
6053
|
this.synchronizerCreators[type.toLowerCase()] = creator;
|
|
5794
6054
|
}
|
|
5795
6055
|
_getOrCreateSynchronizer(type, id, options) {
|
|
@@ -5867,10 +6127,10 @@ SyncGroupService.REGISTRATION = {
|
|
|
5867
6127
|
|
|
5868
6128
|
/* harmony default export */ const services_SyncGroupService = (SyncGroupService);
|
|
5869
6129
|
// EXTERNAL MODULE: ../../../node_modules/lodash.clonedeep/index.js
|
|
5870
|
-
var lodash_clonedeep = __webpack_require__(
|
|
6130
|
+
var lodash_clonedeep = __webpack_require__(11677);
|
|
5871
6131
|
var lodash_clonedeep_default = /*#__PURE__*/__webpack_require__.n(lodash_clonedeep);
|
|
5872
6132
|
// EXTERNAL MODULE: ../../../node_modules/lodash.isequal/index.js
|
|
5873
|
-
var lodash_isequal = __webpack_require__(
|
|
6133
|
+
var lodash_isequal = __webpack_require__(10311);
|
|
5874
6134
|
var lodash_isequal_default = /*#__PURE__*/__webpack_require__.n(lodash_isequal);
|
|
5875
6135
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/transitions.ts
|
|
5876
6136
|
/**
|
|
@@ -6026,6 +6286,82 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6026
6286
|
segmentation
|
|
6027
6287
|
});
|
|
6028
6288
|
};
|
|
6289
|
+
// Todo: this should not run on the main thread
|
|
6290
|
+
this.calculateCentroids = (segmentationId, segmentIndex) => {
|
|
6291
|
+
const segmentation = this.getSegmentation(segmentationId);
|
|
6292
|
+
const volume = this.getLabelmapVolume(segmentationId);
|
|
6293
|
+
const {
|
|
6294
|
+
dimensions,
|
|
6295
|
+
imageData
|
|
6296
|
+
} = volume;
|
|
6297
|
+
const scalarData = volume.getScalarData();
|
|
6298
|
+
const [dimX, dimY, numFrames] = dimensions;
|
|
6299
|
+
const frameLength = dimX * dimY;
|
|
6300
|
+
const segmentIndices = segmentIndex ? [segmentIndex] : segmentation.segments.filter(segment => segment?.segmentIndex).map(segment => segment.segmentIndex);
|
|
6301
|
+
const segmentIndicesSet = new Set(segmentIndices);
|
|
6302
|
+
const centroids = new Map();
|
|
6303
|
+
for (const index of segmentIndicesSet) {
|
|
6304
|
+
centroids.set(index, {
|
|
6305
|
+
x: 0,
|
|
6306
|
+
y: 0,
|
|
6307
|
+
z: 0,
|
|
6308
|
+
count: 0
|
|
6309
|
+
});
|
|
6310
|
+
}
|
|
6311
|
+
let voxelIndex = 0;
|
|
6312
|
+
for (let frame = 0; frame < numFrames; frame++) {
|
|
6313
|
+
for (let p = 0; p < frameLength; p++) {
|
|
6314
|
+
const segmentIndex = scalarData[voxelIndex++];
|
|
6315
|
+
if (segmentIndicesSet.has(segmentIndex)) {
|
|
6316
|
+
const centroid = centroids.get(segmentIndex);
|
|
6317
|
+
centroid.x += p % dimX;
|
|
6318
|
+
centroid.y += p / dimX | 0;
|
|
6319
|
+
centroid.z += frame;
|
|
6320
|
+
centroid.count++;
|
|
6321
|
+
}
|
|
6322
|
+
}
|
|
6323
|
+
}
|
|
6324
|
+
const result = new Map();
|
|
6325
|
+
for (const [index, centroid] of centroids) {
|
|
6326
|
+
const count = centroid.count;
|
|
6327
|
+
const normalizedCentroid = {
|
|
6328
|
+
x: centroid.x / count,
|
|
6329
|
+
y: centroid.y / count,
|
|
6330
|
+
z: centroid.z / count
|
|
6331
|
+
};
|
|
6332
|
+
normalizedCentroid.world = imageData.indexToWorld([normalizedCentroid.x, normalizedCentroid.y, normalizedCentroid.z]);
|
|
6333
|
+
result.set(index, normalizedCentroid);
|
|
6334
|
+
}
|
|
6335
|
+
this.setCentroids(segmentationId, result);
|
|
6336
|
+
return result;
|
|
6337
|
+
};
|
|
6338
|
+
this.setCentroids = (segmentationId, centroids) => {
|
|
6339
|
+
const segmentation = this.getSegmentation(segmentationId);
|
|
6340
|
+
const imageData = this.getLabelmapVolume(segmentationId).imageData; // Assuming this method returns imageData
|
|
6341
|
+
|
|
6342
|
+
if (!segmentation.cachedStats) {
|
|
6343
|
+
segmentation.cachedStats = {
|
|
6344
|
+
segmentCenter: {}
|
|
6345
|
+
};
|
|
6346
|
+
} else if (!segmentation.cachedStats.segmentCenter) {
|
|
6347
|
+
segmentation.cachedStats.segmentCenter = {};
|
|
6348
|
+
}
|
|
6349
|
+
for (const [segmentIndex, centroid] of centroids) {
|
|
6350
|
+
let world = centroid.world;
|
|
6351
|
+
|
|
6352
|
+
// If world coordinates are not provided, calculate them
|
|
6353
|
+
if (!world || world.length === 0) {
|
|
6354
|
+
world = imageData.indexToWorld(centroid.image);
|
|
6355
|
+
}
|
|
6356
|
+
segmentation.cachedStats.segmentCenter[segmentIndex] = {
|
|
6357
|
+
center: {
|
|
6358
|
+
image: centroid.image,
|
|
6359
|
+
world: world
|
|
6360
|
+
}
|
|
6361
|
+
};
|
|
6362
|
+
}
|
|
6363
|
+
this.addOrUpdateSegmentation(segmentation, true, true);
|
|
6364
|
+
};
|
|
6029
6365
|
this.createSegmentationForDisplaySet = async (displaySetInstanceUID, options) => {
|
|
6030
6366
|
const {
|
|
6031
6367
|
displaySetService
|
|
@@ -6055,6 +6391,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6055
6391
|
// We should set it as active by default, as it created for display
|
|
6056
6392
|
isActive: true,
|
|
6057
6393
|
type: representationType,
|
|
6394
|
+
FrameOfReferenceUID: options?.FrameOfReferenceUID || displaySet.instances?.[0]?.FrameOfReferenceUID,
|
|
6058
6395
|
representationData: {
|
|
6059
6396
|
LABELMAP: {
|
|
6060
6397
|
volumeId: segmentationId,
|
|
@@ -6078,6 +6415,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6078
6415
|
this.addSegmentationRepresentationToToolGroup = async function (toolGroupId, segmentationId) {
|
|
6079
6416
|
let hydrateSegmentation = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
6080
6417
|
let representationType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : dist_esm.Enums.SegmentationRepresentations.Labelmap;
|
|
6418
|
+
let suppressEvents = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
6081
6419
|
const segmentation = _this.getSegmentation(segmentationId);
|
|
6082
6420
|
if (!segmentation) {
|
|
6083
6421
|
throw new Error(`Segmentation with segmentationId ${segmentationId} not found.`);
|
|
@@ -6122,12 +6460,17 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6122
6460
|
if (visibility !== undefined) {
|
|
6123
6461
|
_this._setSegmentVisibility(segmentationId, segmentIndex, visibility, toolGroupId, suppressEvents);
|
|
6124
6462
|
}
|
|
6125
|
-
if (isLocked
|
|
6463
|
+
if (isLocked) {
|
|
6126
6464
|
_this._setSegmentLocked(segmentationId, segmentIndex, isLocked, suppressEvents);
|
|
6127
6465
|
}
|
|
6128
6466
|
}
|
|
6467
|
+
if (!suppressEvents) {
|
|
6468
|
+
_this._broadcastEvent(_this.EVENTS.SEGMENTATION_UPDATED, {
|
|
6469
|
+
segmentation
|
|
6470
|
+
});
|
|
6471
|
+
}
|
|
6129
6472
|
};
|
|
6130
|
-
this.
|
|
6473
|
+
this.setSegmentRGBAColor = (segmentationId, segmentIndex, rgbaColor, toolGroupId) => {
|
|
6131
6474
|
const segmentation = this.getSegmentation(segmentationId);
|
|
6132
6475
|
if (segmentation === undefined) {
|
|
6133
6476
|
throw new Error(`no segmentation for segmentationId: ${segmentationId}`);
|
|
@@ -6153,6 +6496,9 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6153
6496
|
throw new Error(`Segmentation with segmentationId ${segmentationId} not found.`);
|
|
6154
6497
|
}
|
|
6155
6498
|
segmentation.hydrated = true;
|
|
6499
|
+
|
|
6500
|
+
// Not all segmentations have dipslaysets, some of them are derived in the client
|
|
6501
|
+
_this._setDisplaySetIsHydrated(segmentationId, true);
|
|
6156
6502
|
if (!suppressEvents) {
|
|
6157
6503
|
_this._broadcastEvent(_this.EVENTS.SEGMENTATION_UPDATED, {
|
|
6158
6504
|
segmentation
|
|
@@ -6467,34 +6813,40 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6467
6813
|
this._initSegmentationService();
|
|
6468
6814
|
}
|
|
6469
6815
|
/**
|
|
6470
|
-
*
|
|
6471
|
-
* the segment.
|
|
6472
|
-
* @param
|
|
6473
|
-
* segment to.
|
|
6474
|
-
*
|
|
6475
|
-
*
|
|
6476
|
-
*
|
|
6477
|
-
*
|
|
6478
|
-
*
|
|
6479
|
-
*
|
|
6480
|
-
*
|
|
6481
|
-
*
|
|
6816
|
+
* Adds a new segment to the specified segmentation.
|
|
6817
|
+
* @param segmentationId - The ID of the segmentation to add the segment to.
|
|
6818
|
+
* @param config - An object containing the configuration options for the new segment.
|
|
6819
|
+
* - segmentIndex: (optional) The index of the segment to add. If not provided, the next available index will be used.
|
|
6820
|
+
* - toolGroupId: (optional) The ID of the tool group to associate the new segment with. If not provided, the first available tool group will be used.
|
|
6821
|
+
* - properties: (optional) An object containing the properties of the new segment.
|
|
6822
|
+
* - label: (optional) The label of the new segment. If not provided, a default label will be used.
|
|
6823
|
+
* - color: (optional) The color of the new segment in RGB format. If not provided, a default color will be used.
|
|
6824
|
+
* - opacity: (optional) The opacity of the new segment. If not provided, a default opacity will be used.
|
|
6825
|
+
* - visibility: (optional) Whether the new segment should be visible. If not provided, the segment will be visible by default.
|
|
6826
|
+
* - isLocked: (optional) Whether the new segment should be locked for editing. If not provided, the segment will not be locked by default.
|
|
6827
|
+
* - active: (optional) Whether the new segment should be the active segment to be edited. If not provided, the segment will not be active by default.
|
|
6482
6828
|
*/
|
|
6483
|
-
addSegment(segmentationId
|
|
6484
|
-
|
|
6829
|
+
addSegment(segmentationId) {
|
|
6830
|
+
let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
6831
|
+
if (config?.segmentIndex === 0) {
|
|
6485
6832
|
throw new Error('Segment index 0 is reserved for "no label"');
|
|
6486
6833
|
}
|
|
6487
|
-
toolGroupId = toolGroupId ?? this._getFirstToolGroupId();
|
|
6834
|
+
const toolGroupId = config.toolGroupId ?? this._getFirstToolGroupId();
|
|
6488
6835
|
const {
|
|
6489
6836
|
segmentationRepresentationUID,
|
|
6490
6837
|
segmentation
|
|
6491
6838
|
} = this._getSegmentationInfo(segmentationId, toolGroupId);
|
|
6839
|
+
let segmentIndex = config.segmentIndex;
|
|
6840
|
+
if (!segmentIndex) {
|
|
6841
|
+
// grab the next available segment index
|
|
6842
|
+
segmentIndex = segmentation.segments.length === 0 ? 1 : segmentation.segments.length;
|
|
6843
|
+
}
|
|
6492
6844
|
if (this._getSegmentInfo(segmentation, segmentIndex)) {
|
|
6493
6845
|
throw new Error(`Segment ${segmentIndex} already exists`);
|
|
6494
6846
|
}
|
|
6495
6847
|
const rgbaColor = dist_esm.segmentation.config.color.getColorForSegmentIndex(toolGroupId, segmentationRepresentationUID, segmentIndex);
|
|
6496
6848
|
segmentation.segments[segmentIndex] = {
|
|
6497
|
-
label: properties
|
|
6849
|
+
label: config.properties?.label ?? `Segment ${segmentIndex}`,
|
|
6498
6850
|
segmentIndex: segmentIndex,
|
|
6499
6851
|
color: [rgbaColor[0], rgbaColor[1], rgbaColor[2]],
|
|
6500
6852
|
opacity: rgbaColor[3],
|
|
@@ -6502,15 +6854,18 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6502
6854
|
isLocked: false
|
|
6503
6855
|
};
|
|
6504
6856
|
segmentation.segmentCount++;
|
|
6857
|
+
|
|
6858
|
+
// make the newly added segment the active segment
|
|
6859
|
+
this._setActiveSegment(segmentationId, segmentIndex);
|
|
6505
6860
|
const suppressEvents = true;
|
|
6506
|
-
if (properties !== undefined) {
|
|
6861
|
+
if (config.properties !== undefined) {
|
|
6507
6862
|
const {
|
|
6508
6863
|
color: newColor,
|
|
6509
6864
|
opacity,
|
|
6510
6865
|
isLocked,
|
|
6511
6866
|
visibility,
|
|
6512
6867
|
active
|
|
6513
|
-
} = properties;
|
|
6868
|
+
} = config.properties;
|
|
6514
6869
|
if (newColor !== undefined) {
|
|
6515
6870
|
this._setSegmentColor(segmentationId, segmentIndex, newColor, toolGroupId, suppressEvents);
|
|
6516
6871
|
}
|
|
@@ -6590,12 +6945,21 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6590
6945
|
let suppressEvents = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
6591
6946
|
this._setSegmentVisibility(segmentationId, segmentIndex, isVisible, toolGroupId, suppressEvents);
|
|
6592
6947
|
}
|
|
6593
|
-
|
|
6948
|
+
setSegmentLocked(segmentationId, segmentIndex, isLocked) {
|
|
6594
6949
|
const suppressEvents = false;
|
|
6595
6950
|
this._setSegmentLocked(segmentationId, segmentIndex, isLocked, suppressEvents);
|
|
6596
6951
|
}
|
|
6597
|
-
|
|
6598
|
-
|
|
6952
|
+
|
|
6953
|
+
/**
|
|
6954
|
+
* Toggles the locked state of a segment in a segmentation.
|
|
6955
|
+
* @param segmentationId - The ID of the segmentation.
|
|
6956
|
+
* @param segmentIndex - The index of the segment to toggle.
|
|
6957
|
+
*/
|
|
6958
|
+
toggleSegmentLocked(segmentationId, segmentIndex) {
|
|
6959
|
+
const segmentation = this.getSegmentation(segmentationId);
|
|
6960
|
+
const segment = this._getSegmentInfo(segmentation, segmentIndex);
|
|
6961
|
+
const isLocked = !segment.isLocked;
|
|
6962
|
+
this._setSegmentLocked(segmentationId, segmentIndex, isLocked);
|
|
6599
6963
|
}
|
|
6600
6964
|
setSegmentColor(segmentationId, segmentIndex, color, toolGroupId) {
|
|
6601
6965
|
this._setSegmentColor(segmentationId, segmentIndex, color, toolGroupId);
|
|
@@ -6608,7 +6972,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6608
6972
|
const suppressEvents = false;
|
|
6609
6973
|
this._setActiveSegmentationForToolGroup(segmentationId, toolGroupId, suppressEvents);
|
|
6610
6974
|
}
|
|
6611
|
-
|
|
6975
|
+
setActiveSegment(segmentationId, segmentIndex) {
|
|
6612
6976
|
this._setActiveSegment(segmentationId, segmentIndex, false);
|
|
6613
6977
|
}
|
|
6614
6978
|
|
|
@@ -6677,11 +7041,14 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6677
7041
|
}
|
|
6678
7042
|
}]);
|
|
6679
7043
|
|
|
6680
|
-
//
|
|
6681
|
-
//
|
|
6682
|
-
const
|
|
6683
|
-
|
|
6684
|
-
|
|
7044
|
+
// if first segmentation, we can use the default colorLUT, otherwise
|
|
7045
|
+
// we need to generate a new one and use a new colorLUT
|
|
7046
|
+
const colorLUTIndex = 0;
|
|
7047
|
+
if (Object.keys(this.segmentations).length !== 0) {
|
|
7048
|
+
const newColorLUT = this.generateNewColorLUT();
|
|
7049
|
+
const colorLUTIndex = this.getNextColorLUTIndex();
|
|
7050
|
+
dist_esm.segmentation.config.color.addColorLUT(newColorLUT, colorLUTIndex);
|
|
7051
|
+
}
|
|
6685
7052
|
this.segmentations[segmentationId] = {
|
|
6686
7053
|
...segmentation,
|
|
6687
7054
|
label: segmentation.label || '',
|
|
@@ -6689,8 +7056,8 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6689
7056
|
activeSegmentIndex: segmentation.activeSegmentIndex ?? null,
|
|
6690
7057
|
segmentCount: segmentation.segmentCount ?? 0,
|
|
6691
7058
|
isActive: false,
|
|
6692
|
-
|
|
6693
|
-
|
|
7059
|
+
isVisible: true,
|
|
7060
|
+
colorLUTIndex
|
|
6694
7061
|
};
|
|
6695
7062
|
cachedSegmentation = this.segmentations[segmentationId];
|
|
6696
7063
|
this._updateCornerstoneSegmentations({
|
|
@@ -6715,6 +7082,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6715
7082
|
id: segmentationId,
|
|
6716
7083
|
displaySetInstanceUID: segDisplaySet.displaySetInstanceUID,
|
|
6717
7084
|
type: representationType,
|
|
7085
|
+
label: segDisplaySet.SeriesDescription,
|
|
6718
7086
|
representationData: {
|
|
6719
7087
|
[LABELMAP]: {
|
|
6720
7088
|
volumeId: segmentationId,
|
|
@@ -6731,11 +7099,11 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6731
7099
|
return this.addOrUpdateSegmentation(Object.assign(segmentation, cachedSegmentation), suppressEvents);
|
|
6732
7100
|
}
|
|
6733
7101
|
const {
|
|
6734
|
-
|
|
7102
|
+
labelmapBufferArray,
|
|
6735
7103
|
referencedVolumeId
|
|
6736
7104
|
} = segDisplaySet;
|
|
6737
|
-
if (!
|
|
6738
|
-
throw new Error('
|
|
7105
|
+
if (!labelmapBufferArray || !referencedVolumeId) {
|
|
7106
|
+
throw new Error('No labelmapBufferArray or referencedVolumeId found for the SEG displaySet');
|
|
6739
7107
|
}
|
|
6740
7108
|
|
|
6741
7109
|
// if the labelmap doesn't exist, we need to create it first from the
|
|
@@ -6754,72 +7122,27 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6754
7122
|
sharedArrayBuffer: true
|
|
6755
7123
|
}
|
|
6756
7124
|
});
|
|
6757
|
-
const [rows, columns] = derivedVolume.dimensions;
|
|
6758
7125
|
const derivedVolumeScalarData = derivedVolume.getScalarData();
|
|
6759
|
-
const
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
} = esm.metaData.get('generalImageModule', imageId);
|
|
6766
|
-
acc[sopInstanceUid] = index;
|
|
6767
|
-
return acc;
|
|
6768
|
-
}, {});
|
|
6769
|
-
const numSegments = Object.keys(segments).length;
|
|
6770
|
-
// Note: ideally we could use the TypedArray set method, but since each
|
|
6771
|
-
// slice can have multiple segments, we need to loop over each slice and
|
|
6772
|
-
// set the segment value for each segment.
|
|
6773
|
-
let overlappingSegments = false;
|
|
6774
|
-
const _segmentInfoUpdate = (segmentInfo, segmentIndex) => {
|
|
7126
|
+
const segmentsInfo = segDisplaySet.segMetadata.data;
|
|
7127
|
+
derivedVolumeScalarData.set(new Uint8Array(labelmapBufferArray[0]));
|
|
7128
|
+
segmentation.segments = segmentsInfo.map((segmentInfo, segmentIndex) => {
|
|
7129
|
+
if (segmentIndex === 0) {
|
|
7130
|
+
return;
|
|
7131
|
+
}
|
|
6775
7132
|
const {
|
|
6776
|
-
|
|
7133
|
+
SegmentedPropertyCategoryCodeSequence,
|
|
7134
|
+
SegmentNumber,
|
|
7135
|
+
SegmentLabel,
|
|
7136
|
+
SegmentAlgorithmType,
|
|
7137
|
+
SegmentAlgorithmName,
|
|
7138
|
+
SegmentedPropertyTypeCodeSequence,
|
|
7139
|
+
rgba
|
|
6777
7140
|
} = segmentInfo;
|
|
6778
|
-
|
|
6779
|
-
|
|
6780
|
-
|
|
6781
|
-
|
|
6782
|
-
|
|
6783
|
-
const {
|
|
6784
|
-
ReferencedSOPInstanceUID
|
|
6785
|
-
} = functionalGroup.DerivationImageSequence.SourceImageSequence;
|
|
6786
|
-
const imageIdIndex = sopUIDImageIdIndexMap[ReferencedSOPInstanceUID];
|
|
6787
|
-
if (imageIdIndex === -1) {
|
|
6788
|
-
return;
|
|
6789
|
-
}
|
|
6790
|
-
const step = rows * columns;
|
|
6791
|
-
|
|
6792
|
-
// we need a faster way to get the pixel data for the current
|
|
6793
|
-
// functional group, which we use typed array view
|
|
6794
|
-
|
|
6795
|
-
const functionGroupPixelData = new Uint8Array(segPixelData.buffer, functionalGroupIndex * step, step);
|
|
6796
|
-
const functionalGroupStartIndex = imageIdIndex * step;
|
|
6797
|
-
const functionalGroupEndIndex = (imageIdIndex + 1) * step;
|
|
6798
|
-
|
|
6799
|
-
// Note: this for loop is not optimized, since DICOM SEG stores
|
|
6800
|
-
// each segment as a separate labelmap so if there is a slice
|
|
6801
|
-
// that has multiple segments, we will have to loop over each
|
|
6802
|
-
// segment and we cannot use the TypedArray set method.
|
|
6803
|
-
for (let i = functionalGroupStartIndex, j = 0; i < functionalGroupEndIndex; i++, j++) {
|
|
6804
|
-
if (functionGroupPixelData[j] !== 0) {
|
|
6805
|
-
if (derivedVolumeScalarData[i] !== 0) {
|
|
6806
|
-
overlappingSegments = true;
|
|
6807
|
-
}
|
|
6808
|
-
derivedVolumeScalarData[i] = segmentIndex;
|
|
6809
|
-
|
|
6810
|
-
// centroid calculations
|
|
6811
|
-
segmentX += i % columns;
|
|
6812
|
-
segmentY += Math.floor(i / columns) % rows;
|
|
6813
|
-
segmentZ += Math.floor(i / (columns * rows));
|
|
6814
|
-
count++;
|
|
6815
|
-
}
|
|
6816
|
-
}
|
|
6817
|
-
}
|
|
6818
|
-
|
|
6819
|
-
// centroid calculations
|
|
6820
|
-
const x = Math.floor(segmentX / count);
|
|
6821
|
-
const y = Math.floor(segmentY / count);
|
|
6822
|
-
const z = Math.floor(segmentZ / count);
|
|
7141
|
+
const {
|
|
7142
|
+
x,
|
|
7143
|
+
y,
|
|
7144
|
+
z
|
|
7145
|
+
} = segDisplaySet.centroids.get(segmentIndex);
|
|
6823
7146
|
const centerWorld = derivedVolume.imageData.indexToWorld([x, y, z]);
|
|
6824
7147
|
segmentation.cachedStats = {
|
|
6825
7148
|
...segmentation.cachedStats,
|
|
@@ -6834,51 +7157,24 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6834
7157
|
}
|
|
6835
7158
|
}
|
|
6836
7159
|
};
|
|
6837
|
-
|
|
6838
|
-
|
|
6839
|
-
|
|
6840
|
-
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
const promiseArray = [];
|
|
6847
|
-
for (const segmentIndex in segments) {
|
|
6848
|
-
const segmentInfo = segments[segmentIndex];
|
|
6849
|
-
|
|
6850
|
-
// Important: we need a non-blocking way to update the segmentation
|
|
6851
|
-
// state, otherwise the UI will freeze and the user will not be able
|
|
6852
|
-
// to interact with the app or progress bars will not be updated.
|
|
6853
|
-
const promise = new Promise((resolve, reject) => {
|
|
6854
|
-
setTimeout(() => {
|
|
6855
|
-
_segmentInfoUpdate(segmentInfo, segmentIndex);
|
|
6856
|
-
resolve();
|
|
6857
|
-
}, 0);
|
|
6858
|
-
});
|
|
6859
|
-
promiseArray.push(promise);
|
|
6860
|
-
}
|
|
6861
|
-
await Promise.all(promiseArray);
|
|
6862
|
-
segmentation.segmentCount = Object.keys(segments).length;
|
|
6863
|
-
segmentation.segments = [null]; // segment 0
|
|
6864
|
-
|
|
6865
|
-
Object.keys(segments).forEach(segmentIndex => {
|
|
6866
|
-
const segmentInfo = segments[segmentIndex];
|
|
6867
|
-
const segIndex = Number(segmentIndex);
|
|
6868
|
-
segmentation.segments[segIndex] = {
|
|
6869
|
-
label: segmentInfo.label || `Segment ${segIndex}`,
|
|
6870
|
-
segmentIndex: Number(segmentIndex),
|
|
6871
|
-
color: [segmentInfo.color[0], segmentInfo.color[1], segmentInfo.color[2]],
|
|
6872
|
-
opacity: segmentInfo.color[3],
|
|
7160
|
+
return {
|
|
7161
|
+
label: SegmentLabel || `Segment ${SegmentNumber}`,
|
|
7162
|
+
segmentIndex: Number(SegmentNumber),
|
|
7163
|
+
category: SegmentedPropertyCategoryCodeSequence ? SegmentedPropertyCategoryCodeSequence.CodeMeaning : '',
|
|
7164
|
+
type: SegmentedPropertyTypeCodeSequence ? SegmentedPropertyTypeCodeSequence.CodeMeaning : '',
|
|
7165
|
+
algorithmType: SegmentAlgorithmType,
|
|
7166
|
+
algorithmName: SegmentAlgorithmName,
|
|
7167
|
+
color: rgba,
|
|
7168
|
+
opacity: 255,
|
|
6873
7169
|
isVisible: true,
|
|
6874
7170
|
isLocked: false
|
|
6875
7171
|
};
|
|
6876
7172
|
});
|
|
7173
|
+
segmentation.segmentCount = segmentsInfo.length - 1;
|
|
6877
7174
|
segDisplaySet.isLoaded = true;
|
|
6878
7175
|
this._broadcastEvent(SegmentationService_EVENTS.SEGMENTATION_LOADING_COMPLETE, {
|
|
6879
7176
|
segmentationId,
|
|
6880
|
-
segDisplaySet
|
|
6881
|
-
overlappingSegments
|
|
7177
|
+
segDisplaySet
|
|
6882
7178
|
});
|
|
6883
7179
|
return this.addOrUpdateSegmentation(segmentation, suppressEvents);
|
|
6884
7180
|
}
|
|
@@ -6911,6 +7207,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6911
7207
|
id: segmentationId,
|
|
6912
7208
|
displaySetInstanceUID: rtDisplaySetUID,
|
|
6913
7209
|
type: representationType,
|
|
7210
|
+
label: rtDisplaySet.SeriesDescription,
|
|
6914
7211
|
representationData: {
|
|
6915
7212
|
[CONTOUR]: {
|
|
6916
7213
|
geometryIds
|
|
@@ -7015,6 +7312,9 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
7015
7312
|
toolGroupService
|
|
7016
7313
|
} = this.servicesManager.services;
|
|
7017
7314
|
const center = this._getSegmentCenter(segmentationId, segmentIndex);
|
|
7315
|
+
if (!center?.world) {
|
|
7316
|
+
return;
|
|
7317
|
+
}
|
|
7018
7318
|
const {
|
|
7019
7319
|
world
|
|
7020
7320
|
} = center;
|
|
@@ -7068,6 +7368,17 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
7068
7368
|
const adjustedAlpha = type === LABELMAP ? alpha : 1 - alpha;
|
|
7069
7369
|
highlightFn(segmentIndex, adjustedAlpha, hideOthers, segments, toolGroupId, animationLength, segmentationRepresentation);
|
|
7070
7370
|
}
|
|
7371
|
+
_setDisplaySetIsHydrated(displaySetUID, isHydrated) {
|
|
7372
|
+
const {
|
|
7373
|
+
displaySetService
|
|
7374
|
+
} = this.servicesManager.services;
|
|
7375
|
+
const displaySet = displaySetService.getDisplaySetByUID(displaySetUID);
|
|
7376
|
+
if (!displaySet) {
|
|
7377
|
+
return;
|
|
7378
|
+
}
|
|
7379
|
+
displaySet.isHydrated = isHydrated;
|
|
7380
|
+
displaySetService.setDisplaySetMetadataInvalidated(displaySetUID, false);
|
|
7381
|
+
}
|
|
7071
7382
|
_highlightLabelmap(segmentIndex, alpha, hideOthers, segments, toolGroupId, animationLength, segmentationRepresentation) {
|
|
7072
7383
|
const newSegmentSpecificConfig = {
|
|
7073
7384
|
[segmentIndex]: {
|
|
@@ -7170,21 +7481,23 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
7170
7481
|
|
|
7171
7482
|
if (wasActive) {
|
|
7172
7483
|
const remainingSegmentations = this._getSegmentations();
|
|
7173
|
-
|
|
7484
|
+
const remainingHydratedSegmentations = remainingSegmentations.filter(segmentation => segmentation.hydrated);
|
|
7485
|
+
if (remainingHydratedSegmentations.length) {
|
|
7174
7486
|
const {
|
|
7175
7487
|
id
|
|
7176
|
-
} =
|
|
7488
|
+
} = remainingHydratedSegmentations[0];
|
|
7177
7489
|
this._setActiveSegmentationForToolGroup(id, this._getFirstToolGroupId(), false);
|
|
7178
7490
|
}
|
|
7179
7491
|
}
|
|
7492
|
+
this._setDisplaySetIsHydrated(segmentationId, false);
|
|
7180
7493
|
this._broadcastEvent(this.EVENTS.SEGMENTATION_REMOVED, {
|
|
7181
7494
|
segmentationId
|
|
7182
7495
|
});
|
|
7183
7496
|
}
|
|
7184
|
-
|
|
7185
|
-
this.
|
|
7497
|
+
setSegmentLabel(segmentationId, segmentIndex, label) {
|
|
7498
|
+
this._setSegmentLabel(segmentationId, segmentIndex, label);
|
|
7186
7499
|
}
|
|
7187
|
-
|
|
7500
|
+
_setSegmentLabel(segmentationId, segmentIndex, label) {
|
|
7188
7501
|
let suppressEvents = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
7189
7502
|
const segmentation = this.getSegmentation(segmentationId);
|
|
7190
7503
|
if (segmentation === undefined) {
|
|
@@ -7202,16 +7515,14 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
7202
7515
|
});
|
|
7203
7516
|
}
|
|
7204
7517
|
}
|
|
7205
|
-
shouldRenderSegmentation(viewportDisplaySetInstanceUIDs,
|
|
7206
|
-
if (!viewportDisplaySetInstanceUIDs
|
|
7518
|
+
shouldRenderSegmentation(viewportDisplaySetInstanceUIDs, segmentationFrameOfReferenceUID) {
|
|
7519
|
+
if (!viewportDisplaySetInstanceUIDs?.length) {
|
|
7207
7520
|
return false;
|
|
7208
7521
|
}
|
|
7209
7522
|
const {
|
|
7210
7523
|
displaySetService
|
|
7211
7524
|
} = this.servicesManager.services;
|
|
7212
7525
|
let shouldDisplaySeg = false;
|
|
7213
|
-
const segDisplaySet = displaySetService.getDisplaySetByUID(segDisplaySetInstanceUID);
|
|
7214
|
-
const segFrameOfReferenceUID = this._getFrameOfReferenceUIDForSeg(segDisplaySet);
|
|
7215
7526
|
|
|
7216
7527
|
// check if the displaySet is sharing the same frameOfReferenceUID
|
|
7217
7528
|
// with the new segmentation
|
|
@@ -7220,7 +7531,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
7220
7531
|
|
|
7221
7532
|
// Todo: this might not be ideal for use cases such as 4D, since we
|
|
7222
7533
|
// don't want to show the segmentation for all the frames
|
|
7223
|
-
if (displaySet.isReconstructable && displaySet?.images?.[0]?.FrameOfReferenceUID ===
|
|
7534
|
+
if (displaySet.isReconstructable && displaySet?.images?.[0]?.FrameOfReferenceUID === segmentationFrameOfReferenceUID) {
|
|
7224
7535
|
shouldDisplaySeg = true;
|
|
7225
7536
|
break;
|
|
7226
7537
|
}
|
|
@@ -7374,7 +7685,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
7374
7685
|
}
|
|
7375
7686
|
_getSegmentationRepresentation(segmentationId, toolGroupId) {
|
|
7376
7687
|
const segmentationRepresentations = this.getSegmentationRepresentationsForToolGroup(toolGroupId);
|
|
7377
|
-
if (segmentationRepresentations
|
|
7688
|
+
if (!segmentationRepresentations?.length) {
|
|
7378
7689
|
return;
|
|
7379
7690
|
}
|
|
7380
7691
|
|
|
@@ -7659,7 +7970,8 @@ class CornerstoneCacheService {
|
|
|
7659
7970
|
}
|
|
7660
7971
|
_shouldRenderSegmentation(displaySets) {
|
|
7661
7972
|
const {
|
|
7662
|
-
segmentationService
|
|
7973
|
+
segmentationService,
|
|
7974
|
+
displaySetService
|
|
7663
7975
|
} = this.servicesManager.services;
|
|
7664
7976
|
const viewportDisplaySetInstanceUIDs = displaySets.map(_ref2 => {
|
|
7665
7977
|
let {
|
|
@@ -7673,7 +7985,8 @@ class CornerstoneCacheService {
|
|
|
7673
7985
|
const segmentations = segmentationService.getSegmentations();
|
|
7674
7986
|
for (const segmentation of segmentations) {
|
|
7675
7987
|
const segDisplaySetInstanceUID = segmentation.displaySetInstanceUID;
|
|
7676
|
-
const
|
|
7988
|
+
const segDisplaySet = displaySetService.getDisplaySetByUID(segDisplaySetInstanceUID);
|
|
7989
|
+
const shouldDisplaySeg = segmentationService.shouldRenderSegmentation(viewportDisplaySetInstanceUIDs, segDisplaySet.instances[0].FrameOfReferenceUID);
|
|
7677
7990
|
if (shouldDisplaySeg) {
|
|
7678
7991
|
return true;
|
|
7679
7992
|
}
|
|
@@ -7747,16 +8060,17 @@ const DEFAULT_TOOLGROUP_ID = 'default';
|
|
|
7747
8060
|
// Return true if the data contains the given display set UID OR the imageId
|
|
7748
8061
|
// if it is a composite object.
|
|
7749
8062
|
const dataContains = (data, displaySetUID, imageId) => {
|
|
7750
|
-
if (data.displaySetInstanceUID === displaySetUID)
|
|
8063
|
+
if (data.displaySetInstanceUID === displaySetUID) {
|
|
8064
|
+
return true;
|
|
8065
|
+
}
|
|
7751
8066
|
if (imageId && data.isCompositeStack && data.imageIds) {
|
|
7752
8067
|
return !!data.imageIds.find(dataId => dataId === imageId);
|
|
7753
8068
|
}
|
|
7754
8069
|
return false;
|
|
7755
8070
|
};
|
|
7756
8071
|
class ViewportInfo {
|
|
7757
|
-
constructor(
|
|
8072
|
+
constructor(viewportId) {
|
|
7758
8073
|
this.viewportId = '';
|
|
7759
|
-
this.viewportIndex = void 0;
|
|
7760
8074
|
this.element = void 0;
|
|
7761
8075
|
this.viewportOptions = void 0;
|
|
7762
8076
|
this.displaySetOptions = void 0;
|
|
@@ -7768,7 +8082,6 @@ class ViewportInfo {
|
|
|
7768
8082
|
this.viewportOptions = null;
|
|
7769
8083
|
this.displaySetOptions = null;
|
|
7770
8084
|
};
|
|
7771
|
-
this.viewportIndex = viewportIndex;
|
|
7772
8085
|
this.viewportId = viewportId;
|
|
7773
8086
|
this.setPublicViewportOptions({});
|
|
7774
8087
|
this.setPublicDisplaySetOptions([{}]);
|
|
@@ -7779,7 +8092,9 @@ class ViewportInfo {
|
|
|
7779
8092
|
* OR if it is a composite stack and contains the given imageId
|
|
7780
8093
|
*/
|
|
7781
8094
|
contains(displaySetUID, imageId) {
|
|
7782
|
-
if (!this.viewportData?.data)
|
|
8095
|
+
if (!this.viewportData?.data) {
|
|
8096
|
+
return false;
|
|
8097
|
+
}
|
|
7783
8098
|
if (this.viewportData.data.length) {
|
|
7784
8099
|
return !!this.viewportData.data.find(data => dataContains(data, displaySetUID, imageId));
|
|
7785
8100
|
}
|
|
@@ -7794,9 +8109,6 @@ class ViewportInfo {
|
|
|
7794
8109
|
setViewportId(viewportId) {
|
|
7795
8110
|
this.viewportId = viewportId;
|
|
7796
8111
|
}
|
|
7797
|
-
setViewportIndex(viewportIndex) {
|
|
7798
|
-
this.viewportIndex = viewportIndex;
|
|
7799
|
-
}
|
|
7800
8112
|
setElement(element) {
|
|
7801
8113
|
this.element = element;
|
|
7802
8114
|
}
|
|
@@ -7806,9 +8118,6 @@ class ViewportInfo {
|
|
|
7806
8118
|
getViewportData() {
|
|
7807
8119
|
return this.viewportData;
|
|
7808
8120
|
}
|
|
7809
|
-
getViewportIndex() {
|
|
7810
|
-
return this.viewportIndex;
|
|
7811
|
-
}
|
|
7812
8121
|
getElement() {
|
|
7813
8122
|
return this.element;
|
|
7814
8123
|
}
|
|
@@ -7819,13 +8128,14 @@ class ViewportInfo {
|
|
|
7819
8128
|
// map the displaySetOptions and check if they are undefined then set them to default values
|
|
7820
8129
|
const displaySetOptions = this.mapDisplaySetOptions(publicDisplaySetOptions);
|
|
7821
8130
|
this.setDisplaySetOptions(displaySetOptions);
|
|
8131
|
+
return this.displaySetOptions;
|
|
7822
8132
|
}
|
|
7823
8133
|
hasDisplaySet(displaySetInstanceUID) {
|
|
7824
8134
|
// Todo: currently this does not work for non image & referenceImage displaySets.
|
|
7825
8135
|
// Since SEG and other derived displaySets are loaded in a different way, and not
|
|
7826
8136
|
// via cornerstoneViewportService
|
|
7827
8137
|
let viewportData = this.getViewportData();
|
|
7828
|
-
if (viewportData.viewportType === esm.Enums.ViewportType.ORTHOGRAPHIC) {
|
|
8138
|
+
if (viewportData.viewportType === esm.Enums.ViewportType.ORTHOGRAPHIC || viewportData.viewportType === esm.Enums.ViewportType.VOLUME_3D) {
|
|
7829
8139
|
viewportData = viewportData;
|
|
7830
8140
|
return viewportData.data.some(_ref => {
|
|
7831
8141
|
let {
|
|
@@ -7865,6 +8175,7 @@ class ViewportInfo {
|
|
|
7865
8175
|
toolGroupId,
|
|
7866
8176
|
presentationIds
|
|
7867
8177
|
});
|
|
8178
|
+
return this.viewportOptions;
|
|
7868
8179
|
}
|
|
7869
8180
|
setViewportOptions(viewportOptions) {
|
|
7870
8181
|
this.viewportOptions = viewportOptions;
|
|
@@ -7959,7 +8270,6 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
7959
8270
|
constructor(servicesManager) {
|
|
7960
8271
|
super(CornerstoneViewportService_EVENTS);
|
|
7961
8272
|
this.renderingEngine = void 0;
|
|
7962
|
-
this.viewportsInfo = new Map();
|
|
7963
8273
|
this.viewportsById = new Map();
|
|
7964
8274
|
this.viewportGridResizeObserver = void 0;
|
|
7965
8275
|
this.viewportsDisplaySets = new Map();
|
|
@@ -7975,37 +8285,16 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
7975
8285
|
|
|
7976
8286
|
/**
|
|
7977
8287
|
* Adds the HTML element to the viewportService
|
|
7978
|
-
* @param {*}
|
|
8288
|
+
* @param {*} viewportId
|
|
7979
8289
|
* @param {*} elementRef
|
|
7980
8290
|
*/
|
|
7981
|
-
enableViewport(
|
|
7982
|
-
|
|
7983
|
-
// Not providing a viewportId is frowned upon because it does weird things
|
|
7984
|
-
// on moving them around, but it does mostly work.
|
|
7985
|
-
if (!viewportOptions.viewportId) {
|
|
7986
|
-
console.warn('Should provide viewport id externally', viewportOptions);
|
|
7987
|
-
viewportOptions.viewportId = this.getViewportId(viewportIndex) || `viewport-${viewportIndex}`;
|
|
7988
|
-
}
|
|
7989
|
-
const {
|
|
7990
|
-
viewportId
|
|
7991
|
-
} = viewportOptions;
|
|
7992
|
-
const viewportInfo = new Viewport(viewportIndex, viewportId);
|
|
7993
|
-
if (!viewportInfo.viewportId) {
|
|
7994
|
-
throw new Error('Should have viewport ID afterwards');
|
|
7995
|
-
}
|
|
8291
|
+
enableViewport(viewportId, elementRef) {
|
|
8292
|
+
const viewportInfo = new Viewport(viewportId);
|
|
7996
8293
|
viewportInfo.setElement(elementRef);
|
|
7997
|
-
this.viewportsInfo.set(viewportIndex, viewportInfo);
|
|
7998
8294
|
this.viewportsById.set(viewportId, viewportInfo);
|
|
7999
8295
|
}
|
|
8000
8296
|
getViewportIds() {
|
|
8001
|
-
|
|
8002
|
-
this.viewportsInfo.forEach(viewportInfo => {
|
|
8003
|
-
viewportIds.push(viewportInfo.getViewportId());
|
|
8004
|
-
});
|
|
8005
|
-
return viewportIds;
|
|
8006
|
-
}
|
|
8007
|
-
getViewportId(viewportIndex) {
|
|
8008
|
-
return this.viewportsInfo[viewportIndex]?.viewportId;
|
|
8297
|
+
return Array.from(this.viewportsById.keys());
|
|
8009
8298
|
}
|
|
8010
8299
|
|
|
8011
8300
|
/**
|
|
@@ -8059,34 +8348,38 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8059
8348
|
* created for every new viewport, this will be called whenever the set of
|
|
8060
8349
|
* viewports is changed, but NOT when the viewport position changes only.
|
|
8061
8350
|
*
|
|
8062
|
-
* @param
|
|
8351
|
+
* @param viewportId - The viewportId to disable
|
|
8063
8352
|
*/
|
|
8064
|
-
disableElement(
|
|
8065
|
-
|
|
8066
|
-
|
|
8067
|
-
|
|
8068
|
-
}
|
|
8069
|
-
const viewportId = viewportInfo.getViewportId();
|
|
8070
|
-
this.renderingEngine && this.renderingEngine.disableElement(viewportId);
|
|
8071
|
-
this.viewportsInfo.get(viewportIndex).destroy();
|
|
8072
|
-
this.viewportsInfo.delete(viewportIndex);
|
|
8353
|
+
disableElement(viewportId) {
|
|
8354
|
+
this.renderingEngine?.disableElement(viewportId);
|
|
8355
|
+
|
|
8356
|
+
// clean up
|
|
8073
8357
|
this.viewportsById.delete(viewportId);
|
|
8358
|
+
this.viewportsDisplaySets.delete(viewportId);
|
|
8074
8359
|
}
|
|
8075
8360
|
setPresentations(viewport, presentations) {
|
|
8076
8361
|
const properties = presentations?.lutPresentation?.properties;
|
|
8077
|
-
if (properties)
|
|
8362
|
+
if (properties) {
|
|
8363
|
+
viewport.setProperties(properties);
|
|
8364
|
+
}
|
|
8078
8365
|
const camera = presentations?.positionPresentation?.camera;
|
|
8079
|
-
if (camera)
|
|
8366
|
+
if (camera) {
|
|
8367
|
+
viewport.setCamera(camera);
|
|
8368
|
+
}
|
|
8080
8369
|
}
|
|
8081
|
-
getPresentation(
|
|
8082
|
-
const viewportInfo = this.
|
|
8083
|
-
if (!viewportInfo)
|
|
8370
|
+
getPresentation(viewportId) {
|
|
8371
|
+
const viewportInfo = this.viewportsById.get(viewportId);
|
|
8372
|
+
if (!viewportInfo) {
|
|
8373
|
+
return;
|
|
8374
|
+
}
|
|
8084
8375
|
const {
|
|
8085
8376
|
viewportType,
|
|
8086
8377
|
presentationIds
|
|
8087
8378
|
} = viewportInfo.getViewportOptions();
|
|
8088
|
-
const csViewport = this.
|
|
8089
|
-
if (!csViewport)
|
|
8379
|
+
const csViewport = this.getCornerstoneViewport(viewportId);
|
|
8380
|
+
if (!csViewport) {
|
|
8381
|
+
return;
|
|
8382
|
+
}
|
|
8090
8383
|
const properties = csViewport.getProperties();
|
|
8091
8384
|
if (properties.isComputedVOI) {
|
|
8092
8385
|
delete properties.voiRange;
|
|
@@ -8102,40 +8395,78 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8102
8395
|
camera
|
|
8103
8396
|
};
|
|
8104
8397
|
}
|
|
8398
|
+
storePresentation(_ref) {
|
|
8399
|
+
let {
|
|
8400
|
+
viewportId
|
|
8401
|
+
} = _ref;
|
|
8402
|
+
const stateSyncService = this.servicesManager.services.stateSyncService;
|
|
8403
|
+
let presentation;
|
|
8404
|
+
try {
|
|
8405
|
+
presentation = this.getPresentation(viewportId);
|
|
8406
|
+
} catch (error) {
|
|
8407
|
+
console.warn(error);
|
|
8408
|
+
}
|
|
8409
|
+
if (!presentation || !presentation.presentationIds) {
|
|
8410
|
+
return;
|
|
8411
|
+
}
|
|
8412
|
+
const {
|
|
8413
|
+
lutPresentationStore,
|
|
8414
|
+
positionPresentationStore
|
|
8415
|
+
} = stateSyncService.getState();
|
|
8416
|
+
const {
|
|
8417
|
+
presentationIds
|
|
8418
|
+
} = presentation;
|
|
8419
|
+
const {
|
|
8420
|
+
lutPresentationId,
|
|
8421
|
+
positionPresentationId
|
|
8422
|
+
} = presentationIds || {};
|
|
8423
|
+
const storeState = {};
|
|
8424
|
+
if (lutPresentationId) {
|
|
8425
|
+
storeState.lutPresentationStore = {
|
|
8426
|
+
...lutPresentationStore,
|
|
8427
|
+
[lutPresentationId]: presentation
|
|
8428
|
+
};
|
|
8429
|
+
}
|
|
8430
|
+
if (positionPresentationId) {
|
|
8431
|
+
storeState.positionPresentationStore = {
|
|
8432
|
+
...positionPresentationStore,
|
|
8433
|
+
[positionPresentationId]: presentation
|
|
8434
|
+
};
|
|
8435
|
+
}
|
|
8436
|
+
stateSyncService.store(storeState);
|
|
8437
|
+
}
|
|
8105
8438
|
|
|
8106
8439
|
/**
|
|
8107
|
-
*
|
|
8108
|
-
*
|
|
8109
|
-
* @param
|
|
8110
|
-
* @param
|
|
8111
|
-
* @param
|
|
8112
|
-
* @
|
|
8440
|
+
* Sets the viewport data for a viewport.
|
|
8441
|
+
* @param viewportId - The ID of the viewport to set the data for.
|
|
8442
|
+
* @param viewportData - The viewport data to set.
|
|
8443
|
+
* @param publicViewportOptions - The public viewport options.
|
|
8444
|
+
* @param publicDisplaySetOptions - The public display set options.
|
|
8445
|
+
* @param presentations - The presentations to set.
|
|
8113
8446
|
*/
|
|
8114
|
-
setViewportData(
|
|
8447
|
+
setViewportData(viewportId, viewportData, publicViewportOptions, publicDisplaySetOptions, presentations) {
|
|
8115
8448
|
const renderingEngine = this.getRenderingEngine();
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
}
|
|
8449
|
+
|
|
8450
|
+
// This is the old viewportInfo, which may have old options but we might be
|
|
8451
|
+
// using its viewport (same viewportId as the new viewportInfo)
|
|
8120
8452
|
const viewportInfo = this.viewportsById.get(viewportId);
|
|
8453
|
+
|
|
8454
|
+
// We should store the presentation for the current viewport since we can't only
|
|
8455
|
+
// rely to store it WHEN the viewport is disabled since we might keep around the
|
|
8456
|
+
// same viewport/element and just change the viewportData for it (drag and drop etc.)
|
|
8457
|
+
// the disableElement storePresentation handle would not be called in this case
|
|
8458
|
+
// and we would lose the presentation.
|
|
8459
|
+
this.storePresentation({
|
|
8460
|
+
viewportId: viewportInfo.getViewportId()
|
|
8461
|
+
});
|
|
8121
8462
|
if (!viewportInfo) {
|
|
8122
|
-
throw new Error('
|
|
8463
|
+
throw new Error('element is not enabled for the given viewportId');
|
|
8123
8464
|
}
|
|
8124
8465
|
|
|
8125
|
-
//
|
|
8126
|
-
|
|
8127
|
-
|
|
8128
|
-
|
|
8129
|
-
viewportInfo.viewportIndex = viewportIndex;
|
|
8130
|
-
}
|
|
8131
|
-
viewportInfo.setRenderingEngineId(renderingEngine.id);
|
|
8132
|
-
const {
|
|
8133
|
-
viewportOptions,
|
|
8134
|
-
displaySetOptions
|
|
8135
|
-
} = this._getViewportAndDisplaySetOptions(publicViewportOptions, publicDisplaySetOptions, viewportInfo);
|
|
8136
|
-
viewportInfo.setViewportOptions(viewportOptions);
|
|
8137
|
-
viewportInfo.setDisplaySetOptions(displaySetOptions);
|
|
8138
|
-
viewportInfo.setViewportData(viewportData);
|
|
8466
|
+
// override the viewportOptions and displaySetOptions with the public ones
|
|
8467
|
+
// since those are the newly set ones, we set them here so that it handles defaults
|
|
8468
|
+
const displaySetOptions = viewportInfo.setPublicDisplaySetOptions(publicDisplaySetOptions);
|
|
8469
|
+
const viewportOptions = viewportInfo.setPublicViewportOptions(publicViewportOptions);
|
|
8139
8470
|
const element = viewportInfo.getElement();
|
|
8140
8471
|
const type = viewportInfo.getViewportType();
|
|
8141
8472
|
const background = viewportInfo.getBackground();
|
|
@@ -8150,11 +8481,23 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8150
8481
|
}
|
|
8151
8482
|
};
|
|
8152
8483
|
|
|
8484
|
+
// Rendering Engine Id set should happen before enabling the element
|
|
8485
|
+
// since there are callbacks that depend on the renderingEngine id
|
|
8486
|
+
// Todo: however, this is a limitation which means that we can't change
|
|
8487
|
+
// the rendering engine id for a given viewport which might be a super edge
|
|
8488
|
+
// case
|
|
8489
|
+
viewportInfo.setRenderingEngineId(renderingEngine.id);
|
|
8490
|
+
|
|
8153
8491
|
// Todo: this is not optimal at all, we are re-enabling the already enabled
|
|
8154
8492
|
// element which is not what we want. But enabledElement as part of the
|
|
8155
8493
|
// renderingEngine is designed to be used like this. This will trigger
|
|
8156
8494
|
// ENABLED_ELEMENT again and again, which will run onEnableElement callbacks
|
|
8157
8495
|
renderingEngine.enableElement(viewportInput);
|
|
8496
|
+
viewportInfo.setViewportOptions(viewportOptions);
|
|
8497
|
+
viewportInfo.setDisplaySetOptions(displaySetOptions);
|
|
8498
|
+
viewportInfo.setViewportData(viewportData);
|
|
8499
|
+
viewportInfo.setViewportId(viewportId);
|
|
8500
|
+
this.viewportsById.set(viewportId, viewportInfo);
|
|
8158
8501
|
const viewport = renderingEngine.getViewport(viewportId);
|
|
8159
8502
|
this._setDisplaySets(viewport, viewportData, viewportInfo, presentations);
|
|
8160
8503
|
|
|
@@ -8163,7 +8506,6 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8163
8506
|
// invalid data.
|
|
8164
8507
|
this._broadcastEvent(this.EVENTS.VIEWPORT_DATA_CHANGED, {
|
|
8165
8508
|
viewportData,
|
|
8166
|
-
viewportIndex,
|
|
8167
8509
|
viewportId
|
|
8168
8510
|
});
|
|
8169
8511
|
}
|
|
@@ -8175,31 +8517,8 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8175
8517
|
const viewport = this.renderingEngine.getViewport(viewportId);
|
|
8176
8518
|
return viewport;
|
|
8177
8519
|
}
|
|
8178
|
-
getCornerstoneViewportByIndex(viewportIndex) {
|
|
8179
|
-
const viewportInfo = this.getViewportInfoByIndex(viewportIndex);
|
|
8180
|
-
if (!viewportInfo || !this.renderingEngine || this.renderingEngine.hasBeenDestroyed) {
|
|
8181
|
-
return null;
|
|
8182
|
-
}
|
|
8183
|
-
const viewport = this.renderingEngine.getViewport(viewportInfo.getViewportId());
|
|
8184
|
-
return viewport;
|
|
8185
|
-
}
|
|
8186
|
-
|
|
8187
|
-
/**
|
|
8188
|
-
* Returns the viewportIndex for the provided viewportId
|
|
8189
|
-
* @param {string} viewportId - the viewportId
|
|
8190
|
-
* @returns {number} - the viewportIndex
|
|
8191
|
-
*/
|
|
8192
|
-
getViewportInfoByIndex(viewportIndex) {
|
|
8193
|
-
return this.viewportsInfo.get(viewportIndex);
|
|
8194
|
-
}
|
|
8195
8520
|
getViewportInfo(viewportId) {
|
|
8196
|
-
|
|
8197
|
-
for (const [index, viewport] of this.viewportsInfo.entries()) {
|
|
8198
|
-
if (viewport.getViewportId() === viewportId) {
|
|
8199
|
-
return viewport;
|
|
8200
|
-
}
|
|
8201
|
-
}
|
|
8202
|
-
return null;
|
|
8521
|
+
return this.viewportsById.get(viewportId);
|
|
8203
8522
|
}
|
|
8204
8523
|
_setStackViewport(viewport, viewportData, viewportInfo, presentations) {
|
|
8205
8524
|
const displaySetOptions = viewportInfo.getDisplaySetOptions();
|
|
@@ -8236,9 +8555,13 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8236
8555
|
}
|
|
8237
8556
|
}
|
|
8238
8557
|
viewport.setStack(imageIds, initialImageIndexToUse).then(() => {
|
|
8239
|
-
viewport.setProperties(
|
|
8558
|
+
viewport.setProperties({
|
|
8559
|
+
...properties
|
|
8560
|
+
});
|
|
8240
8561
|
const camera = presentations.positionPresentation?.camera;
|
|
8241
|
-
if (camera)
|
|
8562
|
+
if (camera) {
|
|
8563
|
+
viewport.setCamera(camera);
|
|
8564
|
+
}
|
|
8242
8565
|
});
|
|
8243
8566
|
}
|
|
8244
8567
|
_getInitialImageIndexForViewport(viewportInfo, imageIds) {
|
|
@@ -8333,7 +8656,7 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8333
8656
|
});
|
|
8334
8657
|
}
|
|
8335
8658
|
this.viewportsDisplaySets.set(viewport.id, displaySetInstanceUIDs);
|
|
8336
|
-
if (hangingProtocolService.
|
|
8659
|
+
if (hangingProtocolService.getShouldPerformCustomImageLoad()) {
|
|
8337
8660
|
// delegate the volume loading to the hanging protocol service if it has a custom image load strategy
|
|
8338
8661
|
return hangingProtocolService.runImageLoadStrategy({
|
|
8339
8662
|
viewportId: viewport.id,
|
|
@@ -8395,11 +8718,11 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8395
8718
|
};
|
|
8396
8719
|
});
|
|
8397
8720
|
await viewport.setVolumes(volumeInputArray);
|
|
8398
|
-
volumesProperties.forEach(
|
|
8721
|
+
volumesProperties.forEach(_ref2 => {
|
|
8399
8722
|
let {
|
|
8400
8723
|
properties,
|
|
8401
8724
|
volumeId
|
|
8402
|
-
} =
|
|
8725
|
+
} = _ref2;
|
|
8403
8726
|
viewport.setProperties(properties, volumeId);
|
|
8404
8727
|
});
|
|
8405
8728
|
this.setPresentations(viewport, presentations);
|
|
@@ -8448,13 +8771,25 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8448
8771
|
continue;
|
|
8449
8772
|
}
|
|
8450
8773
|
|
|
8451
|
-
// otherwise, check if the hydrated segmentations are in the same
|
|
8774
|
+
// otherwise, check if the hydrated segmentations are in the same FrameOfReferenceUID
|
|
8452
8775
|
// as the primary displaySet, if so add the representation (since it was not there)
|
|
8453
8776
|
const {
|
|
8454
|
-
id: segDisplaySetInstanceUID
|
|
8455
|
-
type
|
|
8777
|
+
id: segDisplaySetInstanceUID
|
|
8456
8778
|
} = segmentation;
|
|
8457
|
-
|
|
8779
|
+
let segFrameOfReferenceUID = this._getFrameOfReferenceUID(segDisplaySetInstanceUID);
|
|
8780
|
+
if (!segFrameOfReferenceUID) {
|
|
8781
|
+
// if the segmentation displaySet does not have a FrameOfReferenceUID, we might check the
|
|
8782
|
+
// segmentation itself maybe it has a FrameOfReferenceUID
|
|
8783
|
+
const {
|
|
8784
|
+
FrameOfReferenceUID
|
|
8785
|
+
} = segmentation;
|
|
8786
|
+
if (FrameOfReferenceUID) {
|
|
8787
|
+
segFrameOfReferenceUID = FrameOfReferenceUID;
|
|
8788
|
+
}
|
|
8789
|
+
}
|
|
8790
|
+
if (!segFrameOfReferenceUID) {
|
|
8791
|
+
return;
|
|
8792
|
+
}
|
|
8458
8793
|
let shouldDisplaySeg = false;
|
|
8459
8794
|
for (const displaySetInstanceUID of displaySetInstanceUIDs) {
|
|
8460
8795
|
const primaryFrameOfReferenceUID = this._getFrameOfReferenceUID(displaySetInstanceUID);
|
|
@@ -8487,13 +8822,12 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8487
8822
|
|
|
8488
8823
|
// Todo: keepCamera is an interim solution until we have a better solution for
|
|
8489
8824
|
// keeping the camera position when the viewport data is changed
|
|
8490
|
-
updateViewport(
|
|
8825
|
+
updateViewport(viewportId, viewportData) {
|
|
8491
8826
|
let keepCamera = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
8492
|
-
const viewportInfo = this.
|
|
8493
|
-
const viewportId = viewportInfo.getViewportId();
|
|
8827
|
+
const viewportInfo = this.getViewportInfo(viewportId);
|
|
8494
8828
|
const viewport = this.getCornerstoneViewport(viewportId);
|
|
8495
8829
|
const viewportCamera = viewport.getCamera();
|
|
8496
|
-
if (viewport instanceof esm.VolumeViewport) {
|
|
8830
|
+
if (viewport instanceof esm.VolumeViewport || viewport instanceof esm.VolumeViewport3D) {
|
|
8497
8831
|
this._setVolumeViewport(viewport, viewportData, viewportInfo).then(() => {
|
|
8498
8832
|
if (keepCamera) {
|
|
8499
8833
|
viewport.setCamera(viewportCamera);
|
|
@@ -8548,23 +8882,6 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8548
8882
|
return slabThickness;
|
|
8549
8883
|
}
|
|
8550
8884
|
}
|
|
8551
|
-
_getViewportAndDisplaySetOptions(publicViewportOptions, publicDisplaySetOptions, viewportInfo) {
|
|
8552
|
-
const viewportIndex = viewportInfo.getViewportIndex();
|
|
8553
|
-
|
|
8554
|
-
// Creating a temporary viewportInfo to handle defaults
|
|
8555
|
-
const newViewportInfo = new Viewport(viewportIndex, viewportInfo.getViewportId());
|
|
8556
|
-
|
|
8557
|
-
// To handle setting the default values if missing for the viewportOptions and
|
|
8558
|
-
// displaySetOptions
|
|
8559
|
-
newViewportInfo.setPublicViewportOptions(publicViewportOptions);
|
|
8560
|
-
newViewportInfo.setPublicDisplaySetOptions(publicDisplaySetOptions);
|
|
8561
|
-
const newViewportOptions = newViewportInfo.getViewportOptions();
|
|
8562
|
-
const newDisplaySetOptions = newViewportInfo.getDisplaySetOptions();
|
|
8563
|
-
return {
|
|
8564
|
-
viewportOptions: newViewportOptions,
|
|
8565
|
-
displaySetOptions: newDisplaySetOptions
|
|
8566
|
-
};
|
|
8567
|
-
}
|
|
8568
8885
|
_getFrameOfReferenceUID(displaySetInstanceUID) {
|
|
8569
8886
|
const {
|
|
8570
8887
|
displaySetService
|
|
@@ -8602,28 +8919,28 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8602
8919
|
*
|
|
8603
8920
|
* @param measurement
|
|
8604
8921
|
* The measurement that is desired to view.
|
|
8605
|
-
* @param
|
|
8922
|
+
* @param activeViewportId - the index that was active at the time the jump
|
|
8606
8923
|
* was initiated.
|
|
8607
|
-
* @return the
|
|
8924
|
+
* @return the viewportId that the measurement should be displayed in.
|
|
8608
8925
|
*/
|
|
8609
|
-
|
|
8610
|
-
const viewportInfo = this.
|
|
8926
|
+
getViewportIdToJump(activeViewportId, displaySetInstanceUID, cameraProps) {
|
|
8927
|
+
const viewportInfo = this.getViewportInfo(activeViewportId);
|
|
8611
8928
|
const {
|
|
8612
8929
|
referencedImageId
|
|
8613
8930
|
} = cameraProps;
|
|
8614
8931
|
if (viewportInfo?.contains(displaySetInstanceUID, referencedImageId)) {
|
|
8615
|
-
return
|
|
8932
|
+
return activeViewportId;
|
|
8616
8933
|
}
|
|
8617
|
-
return [...this.viewportsById.values()].find(viewportInfo => viewportInfo.contains(displaySetInstanceUID, referencedImageId))?.
|
|
8934
|
+
return [...this.viewportsById.values()].find(viewportInfo => viewportInfo.contains(displaySetInstanceUID, referencedImageId))?.viewportId ?? null;
|
|
8618
8935
|
}
|
|
8619
8936
|
}
|
|
8620
8937
|
CornerstoneViewportService.REGISTRATION = {
|
|
8621
8938
|
name: 'cornerstoneViewportService',
|
|
8622
8939
|
altName: 'CornerstoneViewportService',
|
|
8623
|
-
create:
|
|
8940
|
+
create: _ref3 => {
|
|
8624
8941
|
let {
|
|
8625
8942
|
servicesManager
|
|
8626
|
-
} =
|
|
8943
|
+
} = _ref3;
|
|
8627
8944
|
return new CornerstoneViewportService(servicesManager);
|
|
8628
8945
|
}
|
|
8629
8946
|
};
|
|
@@ -8632,7 +8949,7 @@ CornerstoneViewportService.REGISTRATION = {
|
|
|
8632
8949
|
|
|
8633
8950
|
|
|
8634
8951
|
// EXTERNAL MODULE: ../../../node_modules/dicomweb-client/build/dicomweb-client.es.js
|
|
8635
|
-
var dicomweb_client_es = __webpack_require__(
|
|
8952
|
+
var dicomweb_client_es = __webpack_require__(97604);
|
|
8636
8953
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/dicomLoaderService.js
|
|
8637
8954
|
|
|
8638
8955
|
|
|
@@ -8707,7 +9024,7 @@ class DicomLoaderService {
|
|
|
8707
9024
|
// Use referenced imageInstance
|
|
8708
9025
|
const imageInstance = getImageInstance(dataset);
|
|
8709
9026
|
const nonImageInstance = getNonImageInstance(dataset);
|
|
8710
|
-
if (!imageInstance && !nonImageInstance || !nonImageInstance.imageId
|
|
9027
|
+
if (!imageInstance && !nonImageInstance || !nonImageInstance.imageId?.startsWith('dicomfile')) {
|
|
8711
9028
|
return;
|
|
8712
9029
|
}
|
|
8713
9030
|
const instance = imageInstance || nonImageInstance;
|
|
@@ -8824,7 +9141,6 @@ function getHandlesFromPoints(points) {
|
|
|
8824
9141
|
|
|
8825
9142
|
|
|
8826
9143
|
|
|
8827
|
-
|
|
8828
9144
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/index.ts
|
|
8829
9145
|
|
|
8830
9146
|
|
|
@@ -8849,11 +9165,10 @@ function src_extends() { src_extends = Object.assign ? Object.assign.bind() : fu
|
|
|
8849
9165
|
|
|
8850
9166
|
|
|
8851
9167
|
|
|
8852
|
-
|
|
8853
9168
|
|
|
8854
9169
|
|
|
8855
9170
|
const Component = /*#__PURE__*/react.lazy(() => {
|
|
8856
|
-
return Promise.all(/* import() */[__webpack_require__.e(
|
|
9171
|
+
return Promise.all(/* import() */[__webpack_require__.e(23), __webpack_require__.e(181)]).then(__webpack_require__.bind(__webpack_require__, 86181));
|
|
8857
9172
|
});
|
|
8858
9173
|
const OHIFCornerstoneViewport = props => {
|
|
8859
9174
|
return /*#__PURE__*/react.createElement(react.Suspense, {
|
|
@@ -8876,7 +9191,6 @@ const cornerstoneExtension = {
|
|
|
8876
9191
|
esm.imageLoadPoolManager.clearRequestStack(type);
|
|
8877
9192
|
esm.imageRetrievalPoolManager.clearRequestStack(type);
|
|
8878
9193
|
});
|
|
8879
|
-
destroy();
|
|
8880
9194
|
(0,state/* reset */.mc)();
|
|
8881
9195
|
},
|
|
8882
9196
|
/**
|
|
@@ -8956,7 +9270,7 @@ const cornerstoneExtension = {
|
|
|
8956
9270
|
|
|
8957
9271
|
/***/ }),
|
|
8958
9272
|
|
|
8959
|
-
/***/
|
|
9273
|
+
/***/ 73704:
|
|
8960
9274
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
8961
9275
|
|
|
8962
9276
|
"use strict";
|
|
@@ -8976,21 +9290,21 @@ const state = {
|
|
|
8976
9290
|
* @param {HTMLElement} dom Active viewport element.
|
|
8977
9291
|
* @return void
|
|
8978
9292
|
*/
|
|
8979
|
-
const setEnabledElement = (
|
|
9293
|
+
const setEnabledElement = (viewportId, element, context) => {
|
|
8980
9294
|
const targetContext = context || state.DEFAULT_CONTEXT;
|
|
8981
|
-
state.enabledElements[
|
|
9295
|
+
state.enabledElements[viewportId] = {
|
|
8982
9296
|
element,
|
|
8983
9297
|
context: targetContext
|
|
8984
9298
|
};
|
|
8985
9299
|
};
|
|
8986
9300
|
|
|
8987
9301
|
/**
|
|
8988
|
-
* Grabs the enabled element `dom` reference of an
|
|
9302
|
+
* Grabs the enabled element `dom` reference of an active viewport.
|
|
8989
9303
|
*
|
|
8990
9304
|
* @return {HTMLElement} Active viewport element.
|
|
8991
9305
|
*/
|
|
8992
|
-
const getEnabledElement =
|
|
8993
|
-
return state.enabledElements[
|
|
9306
|
+
const getEnabledElement = viewportId => {
|
|
9307
|
+
return state.enabledElements[viewportId];
|
|
8994
9308
|
};
|
|
8995
9309
|
const reset = () => {
|
|
8996
9310
|
state.enabledElements = {};
|
|
@@ -8999,14 +9313,14 @@ const reset = () => {
|
|
|
8999
9313
|
|
|
9000
9314
|
/***/ }),
|
|
9001
9315
|
|
|
9002
|
-
/***/
|
|
9316
|
+
/***/ 87172:
|
|
9003
9317
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
9004
9318
|
|
|
9005
9319
|
"use strict";
|
|
9006
9320
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
9007
9321
|
/* harmony export */ Z: () => (/* binding */ getSOPInstanceAttributes)
|
|
9008
9322
|
/* harmony export */ });
|
|
9009
|
-
/* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(
|
|
9323
|
+
/* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3743);
|
|
9010
9324
|
|
|
9011
9325
|
|
|
9012
9326
|
/**
|