@ohif/app 3.7.0-beta.11 → 3.7.0-beta.110
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.b9983325adf849bff6fd.js → 12.bundle.5ea15cb6633d8028e47d.js} +6 -6
- package/dist/{295.bundle.957b1159fec14b9199a1.js → 125.bundle.253395f320b72180da63.js} +6 -6
- package/dist/{351.bundle.0742237651aef9694a65.js → 181.bundle.ceb057236403bcb630ac.js} +226 -204
- package/dist/{351.css → 181.css} +1 -1
- package/dist/{744.bundle.4c4b884f90eb70482821.js → 19.bundle.03f809886c36c388d05c.js} +240 -381
- package/dist/{606.bundle.5d876f5f3dd8287f0a28.js → 202.bundle.d3490836f71e001dd30f.js} +2089 -692
- package/dist/{926.bundle.dbc9d0e591cb9217fda2.js → 220.bundle.f7e1c96c94245e70f2be.js} +990 -400
- package/dist/221.bundle.dc6dac346d724d6baeae.js +1779 -0
- package/dist/221.css +2 -0
- package/dist/{664.bundle.09abae984223969d1bde.js → 23.bundle.e008ad788170f2ed5569.js} +5 -6
- package/dist/{976.bundle.9cc2382162214ea0af2b.js → 236.bundle.7b906cd27864d65f32c0.js} +89 -105
- package/dist/{55.bundle.550a823e75eb608e8d5e.js → 250.bundle.8084960e3318cda37317.js} +52 -36
- package/dist/{973.bundle.4584df05b320b94cace5.js → 281.bundle.c9854cc25c839e49c2c8.js} +18 -14
- package/dist/{82.bundle.9a0e7f08d4bce18d302f.js → 342.bundle.7d6c1e6bda1c67d729a7.js} +1802 -489
- package/dist/{404.bundle.3d65ff813eead20462d3.js → 359.bundle.72d017719489ff11057b.js} +47 -134
- package/dist/{192.bundle.950e5380ea63c6d635d5.js → 370.bundle.e55d75ff1bdccee16cde.js} +117 -103
- package/dist/{790.bundle.7327fec7833ceea2784b.js → 410.bundle.5b41c68cb0f210a83f13.js} +11 -9
- package/dist/{151.bundle.31ea35044218837bf73f.js → 417.bundle.af0a207c29b109f84159.js} +49 -17
- package/dist/{569.bundle.c8e771a8d28e237b32be.js → 451.bundle.9fd36f52ff69594f0669.js} +86 -106
- package/dist/{581.bundle.dc6197189f7c88c27d4c.js → 471.bundle.b3d77b83b1593c09a504.js} +78 -99
- package/dist/{199.bundle.f50ffd85a4334de2f5c1.js → 506.bundle.468dc6db2a9bfa96bb44.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.74d59dec1983ef3efcdc.js +532 -0
- package/dist/{984.bundle.119557c018e6371b4628.js → 663.bundle.a6196baf5853e7d3f7c7.js} +68 -38
- package/dist/{205.bundle.b5a473c200dcf2bbcdb4.js → 686.bundle.dccef1f36e4bc79bcc48.js} +6 -6
- package/dist/{50.bundle.65ff60818862eda39d12.js → 687.bundle.e2c9c42ad3989a14d513.js} +218 -9
- package/dist/{331.bundle.bd0c13931a21d53086c9.js → 743.bundle.489f7df3a089d4d374e1.js} +26294 -21326
- package/dist/757.bundle.ec8301d8e70d2b990f65.js +17067 -0
- package/dist/{728.bundle.d13856835357400fef82.js → 774.bundle.4b2dc46a35012b898e1a.js} +95 -64
- package/dist/{381.bundle.0905e683605fcbc0895f.js → 775.bundle.2285e7e0e67878948c0d.js} +16 -16
- package/dist/{283.bundle.1015e87c3a47b1f1379c.js → 788.bundle.f4493409508bdffa7af8.js} +120 -370
- package/dist/{642.bundle.8905e515ce593e57ceb1.js → 814.bundle.10a2cbf02b044387e68b.js} +6 -6
- package/dist/{707.bundle.f774f3e4a687ddd60a32.js → 82.bundle.9c6461625afd2e38b997.js} +1203 -804
- package/dist/{799.bundle.758558e64147e5aad612.js → 822.bundle.891f2e57b1b7bc2f4cb4.js} +81 -34
- package/dist/{953.bundle.3b0189ebc11cf0946f18.js → 886.bundle.4b3a7f2079d085fdbcb3.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.9ea4506963ef8b2d84ba.js} +7095 -979
- package/dist/{208.bundle.7f610a302dc54c4924da.js → 99.bundle.334c4bd4e4e81aaf45ad.js} +86 -105
- package/dist/_redirects +1 -1
- package/dist/app-config.js +35 -17
- package/dist/app.bundle.css +13 -12
- package/dist/{app.bundle.3d598a4738bdc22950d3.js → app.bundle.fd6ac18b8874825722a0.js} +72771 -67313
- 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 +2 -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 +21 -22
- package/dist/616.bundle.de530ae226dfa5573f6e.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 → 82.css} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
(
|
|
1
|
+
(self["webpackChunk"] = self["webpackChunk"] || []).push([[82],{
|
|
2
2
|
|
|
3
|
-
/***/
|
|
3
|
+
/***/ 78227:
|
|
4
4
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
5
5
|
|
|
6
6
|
"use strict";
|
|
@@ -9,44 +9,44 @@ __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),
|
|
16
16
|
toolNames: () => (/* reexport */ toolNames)
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
-
// NAMESPACE OBJECT: ../../../extensions/cornerstone/src/types/index.ts
|
|
20
|
-
var types_namespaceObject = {};
|
|
21
|
-
__webpack_require__.r(types_namespaceObject);
|
|
22
|
-
|
|
23
19
|
// NAMESPACE OBJECT: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/utils/index.ts
|
|
24
20
|
var utils_namespaceObject = {};
|
|
25
21
|
__webpack_require__.r(utils_namespaceObject);
|
|
26
22
|
__webpack_require__.d(utils_namespaceObject, {
|
|
23
|
+
getDisplayUnit: () => (utils_getDisplayUnit),
|
|
27
24
|
getFirstAnnotationSelected: () => (getFirstAnnotationSelected),
|
|
28
25
|
getHandlesFromPoints: () => (getHandlesFromPoints),
|
|
29
|
-
getModalityUnit: () => (utils_getModalityUnit),
|
|
30
26
|
getSOPInstanceAttributes: () => (getSOPInstanceAttributes/* default */.Z),
|
|
31
27
|
isAnnotationSelected: () => (isAnnotationSelected),
|
|
32
28
|
setAnnotationSelected: () => (setAnnotationSelected)
|
|
33
29
|
});
|
|
34
30
|
|
|
31
|
+
// NAMESPACE OBJECT: ../../../extensions/cornerstone/src/types/index.ts
|
|
32
|
+
var types_namespaceObject = {};
|
|
33
|
+
__webpack_require__.r(types_namespaceObject);
|
|
34
|
+
|
|
35
35
|
// 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__(
|
|
36
|
+
var react = __webpack_require__(43001);
|
|
37
|
+
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js + 331 modules
|
|
38
|
+
var esm = __webpack_require__(3743);
|
|
39
|
+
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js + 348 modules
|
|
40
|
+
var dist_esm = __webpack_require__(14957);
|
|
41
|
+
// EXTERNAL MODULE: ../../core/src/index.ts + 65 modules
|
|
42
|
+
var src = __webpack_require__(71771);
|
|
43
43
|
// 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__(
|
|
44
|
+
var streaming_image_volume_loader_dist_esm = __webpack_require__(7087);
|
|
45
45
|
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/dicom-image-loader/dist/dynamic-import/cornerstoneDICOMImageLoader.min.js
|
|
46
|
-
var cornerstoneDICOMImageLoader_min = __webpack_require__(
|
|
46
|
+
var cornerstoneDICOMImageLoader_min = __webpack_require__(61539);
|
|
47
47
|
var cornerstoneDICOMImageLoader_min_default = /*#__PURE__*/__webpack_require__.n(cornerstoneDICOMImageLoader_min);
|
|
48
48
|
// EXTERNAL MODULE: ../../../node_modules/dicom-parser/dist/dicomParser.min.js
|
|
49
|
-
var dicomParser_min = __webpack_require__(
|
|
49
|
+
var dicomParser_min = __webpack_require__(56660);
|
|
50
50
|
var dicomParser_min_default = /*#__PURE__*/__webpack_require__.n(dicomParser_min);
|
|
51
51
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/initWADOImageLoader.js
|
|
52
52
|
|
|
@@ -76,7 +76,7 @@ function initWebWorkers(appConfig) {
|
|
|
76
76
|
initialized = true;
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
-
function initWADOImageLoader(userAuthenticationService, appConfig) {
|
|
79
|
+
function initWADOImageLoader(userAuthenticationService, appConfig, extensionManager) {
|
|
80
80
|
(cornerstoneDICOMImageLoader_min_default()).external.cornerstone = esm;
|
|
81
81
|
(cornerstoneDICOMImageLoader_min_default()).external.dicomParser = (dicomParser_min_default());
|
|
82
82
|
registerVolumeLoader('cornerstoneStreamingImageVolume', streaming_image_volume_loader_dist_esm/* cornerstoneStreamingImageVolumeLoader */.IU);
|
|
@@ -87,21 +87,17 @@ function initWADOImageLoader(userAuthenticationService, appConfig) {
|
|
|
87
87
|
// will convert everything to integers (to be able to work with cornerstone-2d).
|
|
88
88
|
// Until the default is set to true (which is the case for cornerstone3D),
|
|
89
89
|
// we should set this flag to false.
|
|
90
|
-
convertFloatPixelDataToInt: false
|
|
90
|
+
convertFloatPixelDataToInt: false,
|
|
91
|
+
use16BitDataType: Boolean(appConfig.use16BitDataType)
|
|
91
92
|
},
|
|
92
93
|
beforeSend: function (xhr) {
|
|
94
|
+
//TODO should be removed in the future and request emitted by DicomWebDataSource
|
|
95
|
+
const sourceConfig = extensionManager.getActiveDataSource()?.[0].getConfig() ?? {};
|
|
93
96
|
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
|
|
97
|
+
const acceptHeader = src.utils.generateAcceptHeader(sourceConfig.acceptHeader, sourceConfig.requestTransferSyntaxUID, sourceConfig.omitQuotationForMultipartRequest);
|
|
100
98
|
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=*',
|
|
99
|
+
Accept: acceptHeader
|
|
103
100
|
};
|
|
104
|
-
|
|
105
101
|
if (headers) {
|
|
106
102
|
Object.assign(xhrRequestHeaders, headers);
|
|
107
103
|
}
|
|
@@ -116,14 +112,14 @@ function initWADOImageLoader(userAuthenticationService, appConfig) {
|
|
|
116
112
|
function destroy() {
|
|
117
113
|
// Note: we don't want to call .terminate on the webWorkerManager since
|
|
118
114
|
// that resets the config
|
|
119
|
-
const webWorkers =
|
|
115
|
+
const webWorkers = webWorkerManager.webWorkers;
|
|
120
116
|
for (let i = 0; i < webWorkers.length; i++) {
|
|
121
117
|
webWorkers[i].worker.terminate();
|
|
122
118
|
}
|
|
123
119
|
webWorkers.length = 0;
|
|
124
120
|
}
|
|
125
|
-
// EXTERNAL MODULE: ../../ui/src/index.js +
|
|
126
|
-
var ui_src = __webpack_require__(
|
|
121
|
+
// EXTERNAL MODULE: ../../ui/src/index.js + 485 modules
|
|
122
|
+
var ui_src = __webpack_require__(71783);
|
|
127
123
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/callInputDialog.tsx
|
|
128
124
|
|
|
129
125
|
|
|
@@ -157,7 +153,9 @@ function callInputDialog(uiDialogService, data, callback) {
|
|
|
157
153
|
} = _ref;
|
|
158
154
|
switch (action.id) {
|
|
159
155
|
case 'save':
|
|
160
|
-
if (typeof validateFunc === 'function' && !validateFunc(value.label))
|
|
156
|
+
if (typeof validateFunc === 'function' && !validateFunc(value.label)) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
161
159
|
callback(value.label, action.id);
|
|
162
160
|
break;
|
|
163
161
|
case 'cancel':
|
|
@@ -187,11 +185,11 @@ function callInputDialog(uiDialogService, data, callback) {
|
|
|
187
185
|
actions: [{
|
|
188
186
|
id: 'cancel',
|
|
189
187
|
text: 'Cancel',
|
|
190
|
-
type: ui_src/* ButtonEnums.type */.LZ.
|
|
188
|
+
type: ui_src/* ButtonEnums.type */.LZ.dt.secondary
|
|
191
189
|
}, {
|
|
192
190
|
id: 'save',
|
|
193
191
|
text: 'Save',
|
|
194
|
-
type: ui_src/* ButtonEnums.type */.LZ.
|
|
192
|
+
type: ui_src/* ButtonEnums.type */.LZ.dt.primary
|
|
195
193
|
}],
|
|
196
194
|
onSubmit: onSubmitHandler,
|
|
197
195
|
body: _ref2 => {
|
|
@@ -201,7 +199,7 @@ function callInputDialog(uiDialogService, data, callback) {
|
|
|
201
199
|
} = _ref2;
|
|
202
200
|
return /*#__PURE__*/react.createElement(ui_src/* Input */.II, {
|
|
203
201
|
autoFocus: true,
|
|
204
|
-
className: "
|
|
202
|
+
className: "border-primary-main bg-black",
|
|
205
203
|
type: "text",
|
|
206
204
|
id: "annotation",
|
|
207
205
|
label: inputLabel,
|
|
@@ -232,17 +230,17 @@ function callInputDialog(uiDialogService, data, callback) {
|
|
|
232
230
|
}
|
|
233
231
|
/* harmony default export */ const utils_callInputDialog = (callInputDialog);
|
|
234
232
|
// EXTERNAL MODULE: ../../../extensions/cornerstone/src/state.ts
|
|
235
|
-
var state = __webpack_require__(
|
|
233
|
+
var state = __webpack_require__(73704);
|
|
236
234
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/getActiveViewportEnabledElement.ts
|
|
237
235
|
|
|
238
236
|
|
|
239
237
|
function getActiveViewportEnabledElement(viewportGridService) {
|
|
240
238
|
const {
|
|
241
|
-
|
|
239
|
+
activeViewportId
|
|
242
240
|
} = viewportGridService.getState();
|
|
243
241
|
const {
|
|
244
242
|
element
|
|
245
|
-
} = (0,state/* getEnabledElement */.K8)(
|
|
243
|
+
} = (0,state/* getEnabledElement */.K8)(activeViewportId) || {};
|
|
246
244
|
const enabledElement = (0,esm.getEnabledElement)(element);
|
|
247
245
|
return enabledElement;
|
|
248
246
|
}
|
|
@@ -322,11 +320,12 @@ function onCompletedCalibrationLine(servicesManager, csToolsEvent) {
|
|
|
322
320
|
const currentColumnPixelSpacing = calibratedPixelSpacing?.[1] || imagePlaneModule?.columnPixelSpacing || 1;
|
|
323
321
|
const adjustCalibration = newLength => {
|
|
324
322
|
const spacingScale = newLength / length;
|
|
325
|
-
const rowSpacing = spacingScale * currentRowPixelSpacing;
|
|
326
|
-
const colSpacing = spacingScale * currentColumnPixelSpacing;
|
|
327
323
|
|
|
328
324
|
// trigger resize of the viewport to adjust the world/pixel mapping
|
|
329
|
-
calibrateImageSpacing(imageId, viewport.getRenderingEngine(),
|
|
325
|
+
calibrateImageSpacing(imageId, viewport.getRenderingEngine(), {
|
|
326
|
+
type: 'User',
|
|
327
|
+
scale: 1 / spacingScale
|
|
328
|
+
});
|
|
330
329
|
};
|
|
331
330
|
return new Promise((resolve, reject) => {
|
|
332
331
|
if (!uiDialogService) {
|
|
@@ -358,9 +357,223 @@ function onCompletedCalibrationLine(servicesManager, csToolsEvent) {
|
|
|
358
357
|
});
|
|
359
358
|
});
|
|
360
359
|
}
|
|
360
|
+
// EXTERNAL MODULE: ../../core/src/utils/index.js + 25 modules
|
|
361
|
+
var utils = __webpack_require__(77250);
|
|
362
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/tools/ImageOverlayViewerTool.tsx
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Image Overlay Viewer tool is not a traditional tool that requires user interactin.
|
|
369
|
+
* But it is used to display Pixel Overlays. And it will provide toggling capability.
|
|
370
|
+
*
|
|
371
|
+
* The documentation for Overlay Plane Module of DICOM can be found in [C.9.2 of
|
|
372
|
+
* Part-3 of DICOM standard](https://dicom.nema.org/medical/dicom/2018b/output/chtml/part03/sect_C.9.2.html)
|
|
373
|
+
*
|
|
374
|
+
* Image Overlay rendered by this tool can be toggled on and off using
|
|
375
|
+
* toolGroup.setToolEnabled() and toolGroup.setToolDisabled()
|
|
376
|
+
*/
|
|
377
|
+
class ImageOverlayViewerTool extends dist_esm.AnnotationDisplayTool {
|
|
378
|
+
constructor() {
|
|
379
|
+
let toolProps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
380
|
+
let defaultToolProps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
381
|
+
supportedInteractionTypes: [],
|
|
382
|
+
configuration: {
|
|
383
|
+
fillColor: [255, 127, 127, 255]
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
super(toolProps, defaultToolProps);
|
|
387
|
+
this._cachedOverlayMetadata = new Map();
|
|
388
|
+
this._cachedStats = {};
|
|
389
|
+
this.onSetToolDisabled = () => {
|
|
390
|
+
this._cachedStats = {};
|
|
391
|
+
this._cachedOverlayMetadata = new Map();
|
|
392
|
+
};
|
|
393
|
+
this.renderAnnotation = (enabledElement, svgDrawingHelper) => {
|
|
394
|
+
const {
|
|
395
|
+
viewport
|
|
396
|
+
} = enabledElement;
|
|
397
|
+
const imageId = this.getReferencedImageId(viewport);
|
|
398
|
+
if (!imageId) {
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
const overlays = this._cachedOverlayMetadata.get(imageId) ?? esm.metaData.get('overlayPlaneModule', imageId)?.overlays;
|
|
402
|
+
|
|
403
|
+
// no overlays
|
|
404
|
+
if (!overlays?.length) {
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
this._cachedOverlayMetadata.set(imageId, overlays);
|
|
408
|
+
this._getCachedStat(imageId, overlays, this.configuration.fillColor).then(cachedStat => {
|
|
409
|
+
cachedStat.overlays.forEach(overlay => {
|
|
410
|
+
this._renderOverlay(enabledElement, svgDrawingHelper, overlay);
|
|
411
|
+
});
|
|
412
|
+
});
|
|
413
|
+
return true;
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
getReferencedImageId(viewport) {
|
|
417
|
+
if (viewport instanceof esm.VolumeViewport) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
const targetId = this.getTargetId(viewport);
|
|
421
|
+
return targetId.split('imageId:')[1];
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Render to DOM
|
|
425
|
+
*
|
|
426
|
+
* @param enabledElement
|
|
427
|
+
* @param svgDrawingHelper
|
|
428
|
+
* @param overlayData
|
|
429
|
+
* @returns
|
|
430
|
+
*/
|
|
431
|
+
_renderOverlay(enabledElement, svgDrawingHelper, overlayData) {
|
|
432
|
+
const {
|
|
433
|
+
viewport
|
|
434
|
+
} = enabledElement;
|
|
435
|
+
const imageId = this.getReferencedImageId(viewport);
|
|
436
|
+
if (!imageId) {
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Decide the rendering position of the overlay image on the current canvas
|
|
441
|
+
const {
|
|
442
|
+
_id,
|
|
443
|
+
columns: width,
|
|
444
|
+
rows: height,
|
|
445
|
+
x,
|
|
446
|
+
y
|
|
447
|
+
} = overlayData;
|
|
448
|
+
const overlayTopLeftWorldPos = esm.utilities.imageToWorldCoords(imageId, [x - 1,
|
|
449
|
+
// Remind that top-left corner's (x, y) is be (1, 1)
|
|
450
|
+
y - 1]);
|
|
451
|
+
const overlayTopLeftOnCanvas = viewport.worldToCanvas(overlayTopLeftWorldPos);
|
|
452
|
+
const overlayBottomRightWorldPos = esm.utilities.imageToWorldCoords(imageId, [width, height]);
|
|
453
|
+
const overlayBottomRightOnCanvas = viewport.worldToCanvas(overlayBottomRightWorldPos);
|
|
454
|
+
|
|
455
|
+
// add image to the annotations svg layer
|
|
456
|
+
const svgns = 'http://www.w3.org/2000/svg';
|
|
457
|
+
const svgNodeHash = `image-overlay-${_id}`;
|
|
458
|
+
const existingImageElement = svgDrawingHelper.getSvgNode(svgNodeHash);
|
|
459
|
+
const attributes = {
|
|
460
|
+
'data-id': svgNodeHash,
|
|
461
|
+
width: overlayBottomRightOnCanvas[0] - overlayTopLeftOnCanvas[0],
|
|
462
|
+
height: overlayBottomRightOnCanvas[1] - overlayTopLeftOnCanvas[1],
|
|
463
|
+
x: overlayTopLeftOnCanvas[0],
|
|
464
|
+
y: overlayTopLeftOnCanvas[1],
|
|
465
|
+
href: overlayData.dataUrl
|
|
466
|
+
};
|
|
467
|
+
if (isNaN(attributes.x) || isNaN(attributes.y) || isNaN(attributes.width) || isNaN(attributes.height)) {
|
|
468
|
+
console.warn('Invalid rendering attribute for image overlay', attributes['data-id']);
|
|
469
|
+
return false;
|
|
470
|
+
}
|
|
471
|
+
if (existingImageElement) {
|
|
472
|
+
dist_esm.drawing.setAttributesIfNecessary(attributes, existingImageElement);
|
|
473
|
+
svgDrawingHelper.setNodeTouched(svgNodeHash);
|
|
474
|
+
} else {
|
|
475
|
+
const newImageElement = document.createElementNS(svgns, 'image');
|
|
476
|
+
dist_esm.drawing.setNewAttributesIfValid(attributes, newImageElement);
|
|
477
|
+
svgDrawingHelper.appendNode(newImageElement, svgNodeHash);
|
|
478
|
+
}
|
|
479
|
+
return true;
|
|
480
|
+
}
|
|
481
|
+
async _getCachedStat(imageId, overlayMetadata, color) {
|
|
482
|
+
if (this._cachedStats[imageId] && this._isSameColor(this._cachedStats[imageId].color, color)) {
|
|
483
|
+
return this._cachedStats[imageId];
|
|
484
|
+
}
|
|
485
|
+
const overlays = await Promise.all(overlayMetadata.filter(overlay => overlay.pixelData).map(async (overlay, idx) => {
|
|
486
|
+
let pixelData = null;
|
|
487
|
+
if (overlay.pixelData.Value) {
|
|
488
|
+
pixelData = overlay.pixelData.Value;
|
|
489
|
+
} else if (overlay.pixelData instanceof Array) {
|
|
490
|
+
pixelData = overlay.pixelData[0];
|
|
491
|
+
} else if (overlay.pixelData.retrieveBulkData) {
|
|
492
|
+
pixelData = await overlay.pixelData.retrieveBulkData();
|
|
493
|
+
}
|
|
494
|
+
if (!pixelData) {
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
const dataUrl = this._renderOverlayToDataUrl({
|
|
498
|
+
width: overlay.columns,
|
|
499
|
+
height: overlay.rows
|
|
500
|
+
}, color, pixelData);
|
|
501
|
+
return {
|
|
502
|
+
...overlay,
|
|
503
|
+
_id: (0,utils/* guid */.M8)(),
|
|
504
|
+
dataUrl,
|
|
505
|
+
// this will be a data url expression of the rendered image
|
|
506
|
+
color
|
|
507
|
+
};
|
|
508
|
+
}));
|
|
509
|
+
this._cachedStats[imageId] = {
|
|
510
|
+
color: color,
|
|
511
|
+
overlays: overlays.filter(overlay => overlay)
|
|
512
|
+
};
|
|
513
|
+
return this._cachedStats[imageId];
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* compare two RGBA expression of colors.
|
|
518
|
+
*
|
|
519
|
+
* @param color1
|
|
520
|
+
* @param color2
|
|
521
|
+
* @returns
|
|
522
|
+
*/
|
|
523
|
+
_isSameColor(color1, color2) {
|
|
524
|
+
return color1 && color2 && color1[0] === color2[0] && color1[1] === color2[1] && color1[2] === color2[2] && color1[3] === color2[3];
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* pixelData of overlayPlane module is an array of bits corresponding
|
|
529
|
+
* to each of the underlying pixels of the image.
|
|
530
|
+
* Let's create pixel data from bit array of overlay data
|
|
531
|
+
*
|
|
532
|
+
* @param pixelDataRaw
|
|
533
|
+
* @param color
|
|
534
|
+
* @returns
|
|
535
|
+
*/
|
|
536
|
+
_renderOverlayToDataUrl(_ref, color, pixelDataRaw) {
|
|
537
|
+
let {
|
|
538
|
+
width,
|
|
539
|
+
height
|
|
540
|
+
} = _ref;
|
|
541
|
+
const pixelDataView = new DataView(pixelDataRaw);
|
|
542
|
+
const totalBits = width * height;
|
|
543
|
+
const canvas = document.createElement('canvas');
|
|
544
|
+
canvas.width = width;
|
|
545
|
+
canvas.height = height;
|
|
546
|
+
const ctx = canvas.getContext('2d');
|
|
547
|
+
ctx.clearRect(0, 0, width, height); // make it transparent
|
|
548
|
+
ctx.globalCompositeOperation = 'copy';
|
|
549
|
+
const imageData = ctx.getImageData(0, 0, width, height);
|
|
550
|
+
const data = imageData.data;
|
|
551
|
+
for (let i = 0, bitIdx = 0, byteIdx = 0; i < totalBits; i++) {
|
|
552
|
+
if (pixelDataView.getUint8(byteIdx) & 1 << bitIdx) {
|
|
553
|
+
data[i * 4] = color[0];
|
|
554
|
+
data[i * 4 + 1] = color[1];
|
|
555
|
+
data[i * 4 + 2] = color[2];
|
|
556
|
+
data[i * 4 + 3] = color[3];
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// next bit, byte
|
|
560
|
+
if (bitIdx >= 7) {
|
|
561
|
+
bitIdx = 0;
|
|
562
|
+
byteIdx++;
|
|
563
|
+
} else {
|
|
564
|
+
bitIdx++;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
ctx.putImageData(imageData, 0, 0);
|
|
568
|
+
return canvas.toDataURL();
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
ImageOverlayViewerTool.toolName = 'ImageOverlayViewer';
|
|
572
|
+
/* harmony default export */ const tools_ImageOverlayViewerTool = (ImageOverlayViewerTool);
|
|
361
573
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/initCornerstoneTools.js
|
|
362
574
|
|
|
363
575
|
|
|
576
|
+
|
|
364
577
|
function initCornerstoneTools() {
|
|
365
578
|
let configuration = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
366
579
|
dist_esm.CrosshairsTool.isAnnotation = false;
|
|
@@ -390,6 +603,10 @@ function initCornerstoneTools() {
|
|
|
390
603
|
(0,dist_esm.addTool)(dist_esm.ReferenceLinesTool);
|
|
391
604
|
(0,dist_esm.addTool)(tools_CalibrationLineTool);
|
|
392
605
|
(0,dist_esm.addTool)(dist_esm.TrackballRotateTool);
|
|
606
|
+
(0,dist_esm.addTool)(dist_esm.CircleScissorsTool);
|
|
607
|
+
(0,dist_esm.addTool)(dist_esm.RectangleScissorsTool);
|
|
608
|
+
(0,dist_esm.addTool)(dist_esm.SphereScissorsTool);
|
|
609
|
+
(0,dist_esm.addTool)(tools_ImageOverlayViewerTool);
|
|
393
610
|
|
|
394
611
|
// Modify annotation tools to use dashed lines on SR
|
|
395
612
|
const annotationStyle = {
|
|
@@ -428,13 +645,17 @@ const toolNames = {
|
|
|
428
645
|
SegmentationDisplay: dist_esm.SegmentationDisplayTool.toolName,
|
|
429
646
|
ReferenceLines: dist_esm.ReferenceLinesTool.toolName,
|
|
430
647
|
CalibrationLine: tools_CalibrationLineTool.toolName,
|
|
431
|
-
TrackballRotateTool: dist_esm.TrackballRotateTool.toolName
|
|
648
|
+
TrackballRotateTool: dist_esm.TrackballRotateTool.toolName,
|
|
649
|
+
CircleScissors: dist_esm.CircleScissorsTool.toolName,
|
|
650
|
+
RectangleScissors: dist_esm.RectangleScissorsTool.toolName,
|
|
651
|
+
SphereScissors: dist_esm.SphereScissorsTool.toolName,
|
|
652
|
+
ImageOverlayViewer: tools_ImageOverlayViewerTool.toolName
|
|
432
653
|
};
|
|
433
654
|
|
|
434
655
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/constants/supportedTools.js
|
|
435
656
|
/* harmony default export */ const supportedTools = (['Length', 'EllipticalROI', 'CircleROI', 'Bidirectional', 'ArrowAnnotate', 'Angle', 'CobbAngle', 'Probe', 'RectangleROI', 'PlanarFreehandROI']);
|
|
436
657
|
// EXTERNAL MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/utils/getSOPInstanceAttributes.js
|
|
437
|
-
var getSOPInstanceAttributes = __webpack_require__(
|
|
658
|
+
var getSOPInstanceAttributes = __webpack_require__(87172);
|
|
438
659
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/Length.ts
|
|
439
660
|
|
|
440
661
|
|
|
@@ -537,9 +758,9 @@ function getMappedAnnotations(annotation, displaySetService) {
|
|
|
537
758
|
SeriesNumber
|
|
538
759
|
} = displaySet;
|
|
539
760
|
const {
|
|
540
|
-
length
|
|
761
|
+
length,
|
|
762
|
+
unit = 'mm'
|
|
541
763
|
} = targetStats;
|
|
542
|
-
const unit = 'mm';
|
|
543
764
|
annotations.push({
|
|
544
765
|
SeriesInstanceUID,
|
|
545
766
|
SOPInstanceUID,
|
|
@@ -566,10 +787,13 @@ function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
|
|
|
566
787
|
values.push('Cornerstone:Length');
|
|
567
788
|
mappedAnnotations.forEach(annotation => {
|
|
568
789
|
const {
|
|
569
|
-
length
|
|
790
|
+
length,
|
|
791
|
+
unit
|
|
570
792
|
} = annotation;
|
|
571
|
-
columns.push(`Length
|
|
793
|
+
columns.push(`Length`);
|
|
572
794
|
values.push(length);
|
|
795
|
+
columns.push('Unit');
|
|
796
|
+
values.push(unit);
|
|
573
797
|
});
|
|
574
798
|
if (FrameOfReferenceUID) {
|
|
575
799
|
columns.push('FrameOfReferenceUID');
|
|
@@ -598,7 +822,8 @@ function getDisplayText(mappedAnnotations, displaySet) {
|
|
|
598
822
|
length,
|
|
599
823
|
SeriesNumber,
|
|
600
824
|
SOPInstanceUID,
|
|
601
|
-
frameNumber
|
|
825
|
+
frameNumber,
|
|
826
|
+
unit
|
|
602
827
|
} = mappedAnnotations[0];
|
|
603
828
|
const instance = displaySet.images.find(image => image.SOPInstanceUID === SOPInstanceUID);
|
|
604
829
|
let InstanceNumber;
|
|
@@ -607,16 +832,77 @@ function getDisplayText(mappedAnnotations, displaySet) {
|
|
|
607
832
|
}
|
|
608
833
|
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
|
609
834
|
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
|
|
610
|
-
if (length === null || length === undefined)
|
|
835
|
+
if (length === null || length === undefined) {
|
|
836
|
+
return displayText;
|
|
837
|
+
}
|
|
611
838
|
const roundedLength = src.utils.roundNumber(length, 2);
|
|
612
|
-
displayText.push(`${roundedLength}
|
|
839
|
+
displayText.push(`${roundedLength} ${unit} (S: ${SeriesNumber}${instanceText}${frameText})`);
|
|
613
840
|
return displayText;
|
|
614
841
|
}
|
|
615
842
|
/* harmony default export */ const measurementServiceMappings_Length = (Length);
|
|
843
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/utils/getHandlesFromPoints.js
|
|
844
|
+
function getHandlesFromPoints(points) {
|
|
845
|
+
if (points.longAxis && points.shortAxis) {
|
|
846
|
+
const handles = {};
|
|
847
|
+
handles.start = points.longAxis[0];
|
|
848
|
+
handles.end = points.longAxis[1];
|
|
849
|
+
handles.perpendicularStart = points.longAxis[0];
|
|
850
|
+
handles.perpendicularEnd = points.longAxis[1];
|
|
851
|
+
return handles;
|
|
852
|
+
}
|
|
853
|
+
return points.map((p, i) => i % 10 === 0 ? {
|
|
854
|
+
start: p
|
|
855
|
+
} : {
|
|
856
|
+
end: p
|
|
857
|
+
}).reduce((obj, item) => Object.assign(obj, {
|
|
858
|
+
...item
|
|
859
|
+
}), {});
|
|
860
|
+
}
|
|
861
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/utils/selection.ts
|
|
862
|
+
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* Check whether an annotation from imaging library is selected or not.
|
|
866
|
+
* @param {string} annotationUID uid of imaging library annotation
|
|
867
|
+
* @returns boolean
|
|
868
|
+
*/
|
|
869
|
+
function isAnnotationSelected(annotationUID) {
|
|
870
|
+
return dist_esm.annotation.selection.isAnnotationSelected(annotationUID);
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
/**
|
|
874
|
+
* Change an annotation from imaging library's selected property.
|
|
875
|
+
* @param annotationUID - uid of imaging library annotation
|
|
876
|
+
* @param selected - new value for selected
|
|
877
|
+
*/
|
|
878
|
+
function setAnnotationSelected(annotationUID, selected) {
|
|
879
|
+
const isCurrentSelected = isAnnotationSelected(annotationUID);
|
|
880
|
+
// branch cut, avoid invoking imaging library unnecessarily.
|
|
881
|
+
if (isCurrentSelected !== selected) {
|
|
882
|
+
dist_esm.annotation.selection.setAnnotationSelected(annotationUID, selected);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
function getFirstAnnotationSelected(element) {
|
|
886
|
+
const [selectedAnnotationUID] = dist_esm.annotation.selection.getAnnotationsSelected() || [];
|
|
887
|
+
if (selectedAnnotationUID) {
|
|
888
|
+
return dist_esm.annotation.state.getAnnotation(selectedAnnotationUID);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/utils/getDisplayUnit.js
|
|
893
|
+
const getDisplayUnit = unit => unit == null ? '' : unit;
|
|
894
|
+
/* harmony default export */ const utils_getDisplayUnit = (getDisplayUnit);
|
|
895
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/utils/index.ts
|
|
896
|
+
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
|
|
616
901
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/Bidirectional.ts
|
|
617
902
|
|
|
618
903
|
|
|
619
904
|
|
|
905
|
+
|
|
620
906
|
const Bidirectional = {
|
|
621
907
|
toAnnotation: measurement => {},
|
|
622
908
|
toMeasurement: (csToolsEventDetail, displaySetService, cornerstoneViewportService, getValueTypeFromToolType) => {
|
|
@@ -711,9 +997,9 @@ function Bidirectional_getMappedAnnotations(annotation, displaySetService) {
|
|
|
711
997
|
} = displaySet;
|
|
712
998
|
const {
|
|
713
999
|
length,
|
|
714
|
-
width
|
|
1000
|
+
width,
|
|
1001
|
+
unit
|
|
715
1002
|
} = targetStats;
|
|
716
|
-
const unit = 'mm';
|
|
717
1003
|
annotations.push({
|
|
718
1004
|
SeriesInstanceUID,
|
|
719
1005
|
SOPInstanceUID,
|
|
@@ -742,10 +1028,11 @@ function Bidirectional_getReport(mappedAnnotations, points, FrameOfReferenceUID)
|
|
|
742
1028
|
mappedAnnotations.forEach(annotation => {
|
|
743
1029
|
const {
|
|
744
1030
|
length,
|
|
745
|
-
width
|
|
1031
|
+
width,
|
|
1032
|
+
unit
|
|
746
1033
|
} = annotation;
|
|
747
|
-
columns.push(`Length
|
|
748
|
-
values.push(length, width);
|
|
1034
|
+
columns.push(`Length`, `Width`, 'Unit');
|
|
1035
|
+
values.push(length, width, unit);
|
|
749
1036
|
});
|
|
750
1037
|
if (FrameOfReferenceUID) {
|
|
751
1038
|
columns.push('FrameOfReferenceUID');
|
|
@@ -773,6 +1060,7 @@ function Bidirectional_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
773
1060
|
const {
|
|
774
1061
|
length,
|
|
775
1062
|
width,
|
|
1063
|
+
unit,
|
|
776
1064
|
SeriesNumber,
|
|
777
1065
|
SOPInstanceUID,
|
|
778
1066
|
frameNumber
|
|
@@ -786,22 +1074,11 @@ function Bidirectional_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
786
1074
|
}
|
|
787
1075
|
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
|
788
1076
|
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
|
|
789
|
-
displayText.push(`L: ${roundedLength}
|
|
790
|
-
displayText.push(`W: ${roundedWidth}
|
|
1077
|
+
displayText.push(`L: ${roundedLength} ${utils_getDisplayUnit(unit)} (S: ${SeriesNumber}${instanceText}${frameText})`);
|
|
1078
|
+
displayText.push(`W: ${roundedWidth} ${utils_getDisplayUnit(unit)}`);
|
|
791
1079
|
return displayText;
|
|
792
1080
|
}
|
|
793
1081
|
/* 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
1082
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/EllipticalROI.ts
|
|
806
1083
|
|
|
807
1084
|
|
|
@@ -904,16 +1181,18 @@ function EllipticalROI_getMappedAnnotations(annotation, displaySetService) {
|
|
|
904
1181
|
stdDev,
|
|
905
1182
|
max,
|
|
906
1183
|
area,
|
|
907
|
-
Modality
|
|
1184
|
+
Modality,
|
|
1185
|
+
areaUnit,
|
|
1186
|
+
modalityUnit
|
|
908
1187
|
} = targetStats;
|
|
909
|
-
const unit = utils_getModalityUnit(Modality);
|
|
910
1188
|
annotations.push({
|
|
911
1189
|
SeriesInstanceUID,
|
|
912
1190
|
SOPInstanceUID,
|
|
913
1191
|
SeriesNumber,
|
|
914
1192
|
frameNumber,
|
|
915
1193
|
Modality,
|
|
916
|
-
unit,
|
|
1194
|
+
unit: modalityUnit,
|
|
1195
|
+
areaUnit,
|
|
917
1196
|
mean,
|
|
918
1197
|
stdDev,
|
|
919
1198
|
max,
|
|
@@ -941,13 +1220,14 @@ function EllipticalROI_getReport(mappedAnnotations, points, FrameOfReferenceUID)
|
|
|
941
1220
|
stdDev,
|
|
942
1221
|
max,
|
|
943
1222
|
area,
|
|
944
|
-
unit
|
|
1223
|
+
unit,
|
|
1224
|
+
areaUnit
|
|
945
1225
|
} = annotation;
|
|
946
1226
|
if (!mean || !unit || !max || !area) {
|
|
947
1227
|
return;
|
|
948
1228
|
}
|
|
949
|
-
columns.push(`max (${unit})`, `mean (${unit})`, `std (${unit})`,
|
|
950
|
-
values.push(max, mean, stdDev, area);
|
|
1229
|
+
columns.push(`max (${unit})`, `mean (${unit})`, `std (${unit})`, 'Area', 'Unit');
|
|
1230
|
+
values.push(max, mean, stdDev, area, areaUnit);
|
|
951
1231
|
});
|
|
952
1232
|
if (FrameOfReferenceUID) {
|
|
953
1233
|
columns.push('FrameOfReferenceUID');
|
|
@@ -975,7 +1255,8 @@ function EllipticalROI_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
975
1255
|
const {
|
|
976
1256
|
area,
|
|
977
1257
|
SOPInstanceUID,
|
|
978
|
-
frameNumber
|
|
1258
|
+
frameNumber,
|
|
1259
|
+
areaUnit
|
|
979
1260
|
} = mappedAnnotations[0];
|
|
980
1261
|
const instance = displaySet.images.find(image => image.SOPInstanceUID === SOPInstanceUID);
|
|
981
1262
|
let InstanceNumber;
|
|
@@ -984,10 +1265,8 @@ function EllipticalROI_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
984
1265
|
}
|
|
985
1266
|
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
|
986
1267
|
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>`);
|
|
1268
|
+
const roundedArea = src.utils.roundNumber(area, 2);
|
|
1269
|
+
displayText.push(`${roundedArea} ${utils_getDisplayUnit(areaUnit)}`);
|
|
991
1270
|
|
|
992
1271
|
// Todo: we need a better UI for displaying all these information
|
|
993
1272
|
mappedAnnotations.forEach(mappedAnnotation => {
|
|
@@ -999,7 +1278,7 @@ function EllipticalROI_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
999
1278
|
let maxStr = '';
|
|
1000
1279
|
if (max) {
|
|
1001
1280
|
const roundedMax = src.utils.roundNumber(max, 2);
|
|
1002
|
-
maxStr = `Max: ${roundedMax} <small>${unit}</small> `;
|
|
1281
|
+
maxStr = `Max: ${roundedMax} <small>${utils_getDisplayUnit(unit)}</small> `;
|
|
1003
1282
|
}
|
|
1004
1283
|
const str = `${maxStr}(S:${SeriesNumber}${instanceText}${frameText})`;
|
|
1005
1284
|
if (!displayText.includes(str)) {
|
|
@@ -1111,20 +1390,22 @@ function CircleROI_getMappedAnnotations(annotation, DisplaySetService) {
|
|
|
1111
1390
|
stdDev,
|
|
1112
1391
|
max,
|
|
1113
1392
|
area,
|
|
1114
|
-
Modality
|
|
1393
|
+
Modality,
|
|
1394
|
+
areaUnit,
|
|
1395
|
+
modalityUnit
|
|
1115
1396
|
} = targetStats;
|
|
1116
|
-
const unit = utils_getModalityUnit(Modality);
|
|
1117
1397
|
annotations.push({
|
|
1118
1398
|
SeriesInstanceUID,
|
|
1119
1399
|
SOPInstanceUID,
|
|
1120
1400
|
SeriesNumber,
|
|
1121
1401
|
frameNumber,
|
|
1122
1402
|
Modality,
|
|
1123
|
-
unit,
|
|
1403
|
+
unit: modalityUnit,
|
|
1124
1404
|
mean,
|
|
1125
1405
|
stdDev,
|
|
1126
1406
|
max,
|
|
1127
|
-
area
|
|
1407
|
+
area,
|
|
1408
|
+
areaUnit
|
|
1128
1409
|
});
|
|
1129
1410
|
});
|
|
1130
1411
|
return annotations;
|
|
@@ -1148,13 +1429,14 @@ function CircleROI_getReport(mappedAnnotations, points, FrameOfReferenceUID) {
|
|
|
1148
1429
|
stdDev,
|
|
1149
1430
|
max,
|
|
1150
1431
|
area,
|
|
1151
|
-
unit
|
|
1432
|
+
unit,
|
|
1433
|
+
areaUnit
|
|
1152
1434
|
} = annotation;
|
|
1153
1435
|
if (!mean || !unit || !max || !area) {
|
|
1154
1436
|
return;
|
|
1155
1437
|
}
|
|
1156
|
-
columns.push(`max (${unit})`, `mean (${unit})`, `std (${unit})`,
|
|
1157
|
-
values.push(max, mean, stdDev, area);
|
|
1438
|
+
columns.push(`max (${unit})`, `mean (${unit})`, `std (${unit})`, 'Area', 'Unit');
|
|
1439
|
+
values.push(max, mean, stdDev, area, areaUnit);
|
|
1158
1440
|
});
|
|
1159
1441
|
if (FrameOfReferenceUID) {
|
|
1160
1442
|
columns.push('FrameOfReferenceUID');
|
|
@@ -1182,7 +1464,8 @@ function CircleROI_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
1182
1464
|
const {
|
|
1183
1465
|
area,
|
|
1184
1466
|
SOPInstanceUID,
|
|
1185
|
-
frameNumber
|
|
1467
|
+
frameNumber,
|
|
1468
|
+
areaUnit
|
|
1186
1469
|
} = mappedAnnotations[0];
|
|
1187
1470
|
const instance = displaySet.images.find(image => image.SOPInstanceUID === SOPInstanceUID);
|
|
1188
1471
|
let InstanceNumber;
|
|
@@ -1194,7 +1477,7 @@ function CircleROI_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
1194
1477
|
|
|
1195
1478
|
// Area sometimes becomes undefined if `preventHandleOutsideImage` is off.
|
|
1196
1479
|
const roundedArea = src.utils.roundNumber(area || 0, 2);
|
|
1197
|
-
displayText.push(`${roundedArea}
|
|
1480
|
+
displayText.push(`${roundedArea} ${utils_getDisplayUnit(areaUnit)}`);
|
|
1198
1481
|
|
|
1199
1482
|
// Todo: we need a better UI for displaying all these information
|
|
1200
1483
|
mappedAnnotations.forEach(mappedAnnotation => {
|
|
@@ -1206,7 +1489,7 @@ function CircleROI_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
1206
1489
|
let maxStr = '';
|
|
1207
1490
|
if (max) {
|
|
1208
1491
|
const roundedMax = src.utils.roundNumber(max, 2);
|
|
1209
|
-
maxStr = `Max: ${roundedMax} <small>${unit}</small> `;
|
|
1492
|
+
maxStr = `Max: ${roundedMax} <small>${utils_getDisplayUnit(unit)}</small> `;
|
|
1210
1493
|
}
|
|
1211
1494
|
const str = `${maxStr}(S:${SeriesNumber}${instanceText}${frameText})`;
|
|
1212
1495
|
if (!displayText.includes(str)) {
|
|
@@ -1345,6 +1628,7 @@ function ArrowAnnotate_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
1345
1628
|
|
|
1346
1629
|
|
|
1347
1630
|
|
|
1631
|
+
|
|
1348
1632
|
const CobbAngle = {
|
|
1349
1633
|
toAnnotation: measurement => {},
|
|
1350
1634
|
/**
|
|
@@ -1515,9 +1799,11 @@ function CobbAngle_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
1515
1799
|
}
|
|
1516
1800
|
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
|
1517
1801
|
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
|
|
1518
|
-
if (angle === undefined)
|
|
1802
|
+
if (angle === undefined) {
|
|
1803
|
+
return displayText;
|
|
1804
|
+
}
|
|
1519
1805
|
const roundedAngle = src.utils.roundNumber(angle, 2);
|
|
1520
|
-
displayText.push(`${roundedAngle} ${unit} (S: ${SeriesNumber}${instanceText}${frameText})`);
|
|
1806
|
+
displayText.push(`${roundedAngle} ${utils_getDisplayUnit(unit)} (S: ${SeriesNumber}${instanceText}${frameText})`);
|
|
1521
1807
|
return displayText;
|
|
1522
1808
|
}
|
|
1523
1809
|
/* harmony default export */ const measurementServiceMappings_CobbAngle = (CobbAngle);
|
|
@@ -1525,6 +1811,7 @@ function CobbAngle_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
1525
1811
|
|
|
1526
1812
|
|
|
1527
1813
|
|
|
1814
|
+
|
|
1528
1815
|
const Angle = {
|
|
1529
1816
|
toAnnotation: measurement => {},
|
|
1530
1817
|
/**
|
|
@@ -1695,9 +1982,11 @@ function Angle_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
1695
1982
|
}
|
|
1696
1983
|
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
|
1697
1984
|
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
|
|
1698
|
-
if (angle === undefined)
|
|
1985
|
+
if (angle === undefined) {
|
|
1986
|
+
return displayText;
|
|
1987
|
+
}
|
|
1699
1988
|
const roundedAngle = src.utils.roundNumber(angle, 2);
|
|
1700
|
-
displayText.push(`${roundedAngle} ${unit} (S: ${SeriesNumber}${instanceText}${frameText})`);
|
|
1989
|
+
displayText.push(`${roundedAngle} ${utils_getDisplayUnit(unit)} (S: ${SeriesNumber}${instanceText}${frameText})`);
|
|
1701
1990
|
return displayText;
|
|
1702
1991
|
}
|
|
1703
1992
|
/* harmony default export */ const measurementServiceMappings_Angle = (Angle);
|
|
@@ -1937,20 +2226,22 @@ function RectangleROI_getMappedAnnotations(annotation, DisplaySetService) {
|
|
|
1937
2226
|
stdDev,
|
|
1938
2227
|
max,
|
|
1939
2228
|
area,
|
|
1940
|
-
Modality
|
|
2229
|
+
Modality,
|
|
2230
|
+
modalityUnit,
|
|
2231
|
+
areaUnit
|
|
1941
2232
|
} = targetStats;
|
|
1942
|
-
const unit = utils_getModalityUnit(Modality);
|
|
1943
2233
|
annotations.push({
|
|
1944
2234
|
SeriesInstanceUID,
|
|
1945
2235
|
SOPInstanceUID,
|
|
1946
2236
|
SeriesNumber,
|
|
1947
2237
|
frameNumber,
|
|
1948
2238
|
Modality,
|
|
1949
|
-
unit,
|
|
2239
|
+
unit: modalityUnit,
|
|
1950
2240
|
mean,
|
|
1951
2241
|
stdDev,
|
|
1952
2242
|
max,
|
|
1953
|
-
area
|
|
2243
|
+
area,
|
|
2244
|
+
areaUnit
|
|
1954
2245
|
});
|
|
1955
2246
|
});
|
|
1956
2247
|
return annotations;
|
|
@@ -1974,13 +2265,14 @@ function RectangleROI_getReport(mappedAnnotations, points, FrameOfReferenceUID)
|
|
|
1974
2265
|
stdDev,
|
|
1975
2266
|
max,
|
|
1976
2267
|
area,
|
|
1977
|
-
unit
|
|
2268
|
+
unit,
|
|
2269
|
+
areaUnit
|
|
1978
2270
|
} = annotation;
|
|
1979
2271
|
if (!mean || !unit || !max || !area) {
|
|
1980
2272
|
return;
|
|
1981
2273
|
}
|
|
1982
|
-
columns.push(`
|
|
1983
|
-
values.push(max, mean, stdDev, area);
|
|
2274
|
+
columns.push(`Maximum`, `Mean`, `Std Dev`, 'Pixel Unit', `Area`, 'Unit');
|
|
2275
|
+
values.push(max, mean, stdDev, unit, area, areaUnit);
|
|
1984
2276
|
});
|
|
1985
2277
|
if (FrameOfReferenceUID) {
|
|
1986
2278
|
columns.push('FrameOfReferenceUID');
|
|
@@ -2008,7 +2300,8 @@ function RectangleROI_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
2008
2300
|
const {
|
|
2009
2301
|
area,
|
|
2010
2302
|
SOPInstanceUID,
|
|
2011
|
-
frameNumber
|
|
2303
|
+
frameNumber,
|
|
2304
|
+
areaUnit
|
|
2012
2305
|
} = mappedAnnotations[0];
|
|
2013
2306
|
const instance = displaySet.images.find(image => image.SOPInstanceUID === SOPInstanceUID);
|
|
2014
2307
|
let InstanceNumber;
|
|
@@ -2020,7 +2313,7 @@ function RectangleROI_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
2020
2313
|
|
|
2021
2314
|
// Area sometimes becomes undefined if `preventHandleOutsideImage` is off.
|
|
2022
2315
|
const roundedArea = src.utils.roundNumber(area || 0, 2);
|
|
2023
|
-
displayText.push(`${roundedArea}
|
|
2316
|
+
displayText.push(`${roundedArea} ${utils_getDisplayUnit(areaUnit)}`);
|
|
2024
2317
|
|
|
2025
2318
|
// Todo: we need a better UI for displaying all these information
|
|
2026
2319
|
mappedAnnotations.forEach(mappedAnnotation => {
|
|
@@ -2032,7 +2325,7 @@ function RectangleROI_getDisplayText(mappedAnnotations, displaySet) {
|
|
|
2032
2325
|
let maxStr = '';
|
|
2033
2326
|
if (max) {
|
|
2034
2327
|
const roundedMax = src.utils.roundNumber(max, 2);
|
|
2035
|
-
maxStr = `Max: ${roundedMax} <small>${unit}</small> `;
|
|
2328
|
+
maxStr = `Max: ${roundedMax} <small>${utils_getDisplayUnit(unit)}</small> `;
|
|
2036
2329
|
}
|
|
2037
2330
|
const str = `${maxStr}(S:${SeriesNumber}${instanceText}${frameText})`;
|
|
2038
2331
|
if (!displayText.includes(str)) {
|
|
@@ -2515,7 +2808,7 @@ function getInterleavedFrames(imageIds) {
|
|
|
2515
2808
|
}
|
|
2516
2809
|
while (!prefetchQueuedFilled.currentPositionDownToMinimum || !prefetchQueuedFilled.currentPositionUpToMaximum) {
|
|
2517
2810
|
if (!prefetchQueuedFilled.currentPositionDownToMinimum) {
|
|
2518
|
-
// Add imageId
|
|
2811
|
+
// Add imageId below
|
|
2519
2812
|
lowerImageIdIndex--;
|
|
2520
2813
|
imageIdsToPrefetch.push({
|
|
2521
2814
|
imageId: imageIds[lowerImageIdIndex],
|
|
@@ -2540,7 +2833,7 @@ function getInterleavedFrames(imageIds) {
|
|
|
2540
2833
|
return imageIdsToPrefetch;
|
|
2541
2834
|
}
|
|
2542
2835
|
// EXTERNAL MODULE: ../../../node_modules/lodash/lodash.js
|
|
2543
|
-
var lodash = __webpack_require__(
|
|
2836
|
+
var lodash = __webpack_require__(44379);
|
|
2544
2837
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/interleaveCenterLoader.ts
|
|
2545
2838
|
|
|
2546
2839
|
|
|
@@ -2730,8 +3023,12 @@ function getNthFrames(imageIds) {
|
|
|
2730
3023
|
* @returns [] reordered to be breadth first traversal of lists
|
|
2731
3024
|
*/
|
|
2732
3025
|
function interleave(lists) {
|
|
2733
|
-
if (!lists || !lists.length)
|
|
2734
|
-
|
|
3026
|
+
if (!lists || !lists.length) {
|
|
3027
|
+
return [];
|
|
3028
|
+
}
|
|
3029
|
+
if (lists.length === 1) {
|
|
3030
|
+
return lists[0];
|
|
3031
|
+
}
|
|
2735
3032
|
console.time('interleave');
|
|
2736
3033
|
const useLists = [...lists];
|
|
2737
3034
|
const ret = [];
|
|
@@ -3004,6 +3301,7 @@ const DEFAULT_CONTEXT_MENU_CLICKS = {
|
|
|
3004
3301
|
commands: [{
|
|
3005
3302
|
commandName: 'showCornerstoneContextMenu',
|
|
3006
3303
|
commandOptions: {
|
|
3304
|
+
requireNearbyToolData: true,
|
|
3007
3305
|
menuId: 'measurementsContextMenu'
|
|
3008
3306
|
}
|
|
3009
3307
|
}]
|
|
@@ -3020,9 +3318,15 @@ const DEFAULT_CONTEXT_MENU_CLICKS = {
|
|
|
3020
3318
|
function getEventName(evt) {
|
|
3021
3319
|
const button = evt.detail.event.which;
|
|
3022
3320
|
const nameArr = [];
|
|
3023
|
-
if (evt.detail.event.altKey)
|
|
3024
|
-
|
|
3025
|
-
|
|
3321
|
+
if (evt.detail.event.altKey) {
|
|
3322
|
+
nameArr.push('alt');
|
|
3323
|
+
}
|
|
3324
|
+
if (evt.detail.event.ctrlKey) {
|
|
3325
|
+
nameArr.push('ctrl');
|
|
3326
|
+
}
|
|
3327
|
+
if (evt.detail.event.shiftKey) {
|
|
3328
|
+
nameArr.push('shift');
|
|
3329
|
+
}
|
|
3026
3330
|
nameArr.push('button');
|
|
3027
3331
|
nameArr.push(button);
|
|
3028
3332
|
return nameArr.join('');
|
|
@@ -3040,9 +3344,18 @@ function initContextMenu(_ref) {
|
|
|
3040
3344
|
const cornerstoneViewportHandleEvent = (name, evt) => {
|
|
3041
3345
|
const customizations = customizationService.get('cornerstoneViewportClickCommands') || DEFAULT_CONTEXT_MENU_CLICKS;
|
|
3042
3346
|
const toRun = customizations[name];
|
|
3043
|
-
|
|
3347
|
+
if (!toRun) {
|
|
3348
|
+
return;
|
|
3349
|
+
}
|
|
3350
|
+
|
|
3351
|
+
// only find nearbyToolData if required, for the click (which closes the context menu
|
|
3352
|
+
// we don't need to find nearbyToolData)
|
|
3353
|
+
let nearbyToolData = null;
|
|
3354
|
+
if (toRun.commands.some(command => command.commandOptions?.requireNearbyToolData)) {
|
|
3355
|
+
nearbyToolData = findNearbyToolData(commandsManager, evt);
|
|
3356
|
+
}
|
|
3044
3357
|
const options = {
|
|
3045
|
-
nearbyToolData
|
|
3358
|
+
nearbyToolData,
|
|
3046
3359
|
event: evt
|
|
3047
3360
|
};
|
|
3048
3361
|
commandsManager.run(toRun, options);
|
|
@@ -3057,10 +3370,11 @@ function initContextMenu(_ref) {
|
|
|
3057
3370
|
element
|
|
3058
3371
|
} = evt.detail;
|
|
3059
3372
|
const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId);
|
|
3060
|
-
if (!viewportInfo)
|
|
3061
|
-
|
|
3373
|
+
if (!viewportInfo) {
|
|
3374
|
+
return;
|
|
3375
|
+
}
|
|
3062
3376
|
// TODO check update upstream
|
|
3063
|
-
(0,state/* setEnabledElement */.Yc)(
|
|
3377
|
+
(0,state/* setEnabledElement */.Yc)(viewportId, element);
|
|
3064
3378
|
element.addEventListener(cs3DToolsEvents.MOUSE_CLICK, cornerstoneViewportHandleClick);
|
|
3065
3379
|
}
|
|
3066
3380
|
function elementDisabledHandler(evt) {
|
|
@@ -3094,9 +3408,15 @@ const DEFAULT_DOUBLE_CLICK = {
|
|
|
3094
3408
|
*/
|
|
3095
3409
|
function getDoubleClickEventName(evt) {
|
|
3096
3410
|
const nameArr = [];
|
|
3097
|
-
if (evt.detail.event.altKey)
|
|
3098
|
-
|
|
3099
|
-
|
|
3411
|
+
if (evt.detail.event.altKey) {
|
|
3412
|
+
nameArr.push('alt');
|
|
3413
|
+
}
|
|
3414
|
+
if (evt.detail.event.ctrlKey) {
|
|
3415
|
+
nameArr.push('ctrl');
|
|
3416
|
+
}
|
|
3417
|
+
if (evt.detail.event.shiftKey) {
|
|
3418
|
+
nameArr.push('shift');
|
|
3419
|
+
}
|
|
3100
3420
|
nameArr.push('doubleClick');
|
|
3101
3421
|
return nameArr.join('');
|
|
3102
3422
|
}
|
|
@@ -3137,6 +3457,49 @@ function initDoubleClick(_ref) {
|
|
|
3137
3457
|
esm.eventTarget.addEventListener(esm.EVENTS.ELEMENT_DISABLED, elementDisabledHandler.bind(null));
|
|
3138
3458
|
}
|
|
3139
3459
|
/* harmony default export */ const src_initDoubleClick = (initDoubleClick);
|
|
3460
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/initViewTiming.ts
|
|
3461
|
+
|
|
3462
|
+
|
|
3463
|
+
const {
|
|
3464
|
+
TimingEnum
|
|
3465
|
+
} = src.Types;
|
|
3466
|
+
const IMAGE_TIMING_KEYS = [TimingEnum.DISPLAY_SETS_TO_ALL_IMAGES, TimingEnum.DISPLAY_SETS_TO_FIRST_IMAGE, TimingEnum.STUDY_TO_FIRST_IMAGE];
|
|
3467
|
+
const imageTiming = {
|
|
3468
|
+
viewportsWaiting: 0
|
|
3469
|
+
};
|
|
3470
|
+
|
|
3471
|
+
/**
|
|
3472
|
+
* Defines the initial view timing reporting.
|
|
3473
|
+
* This allows knowing how many viewports are waiting for initial views and
|
|
3474
|
+
* when the IMAGE_RENDERED gets sent out.
|
|
3475
|
+
* The first image rendered will fire the FIRST_IMAGE timeEnd logs, while
|
|
3476
|
+
* the last of the enabled viewport will fire the ALL_IMAGES timeEnd logs.
|
|
3477
|
+
*
|
|
3478
|
+
*/
|
|
3479
|
+
|
|
3480
|
+
function initViewTiming(_ref) {
|
|
3481
|
+
let {
|
|
3482
|
+
element
|
|
3483
|
+
} = _ref;
|
|
3484
|
+
if (!IMAGE_TIMING_KEYS.find(key => src/* log */.cM.timingKeys[key])) {
|
|
3485
|
+
return;
|
|
3486
|
+
}
|
|
3487
|
+
imageTiming.viewportsWaiting += 1;
|
|
3488
|
+
element.addEventListener(esm.EVENTS.IMAGE_RENDERED, imageRenderedListener);
|
|
3489
|
+
}
|
|
3490
|
+
function imageRenderedListener(evt) {
|
|
3491
|
+
if (evt.detail.viewportStatus === 'preRender') {
|
|
3492
|
+
return;
|
|
3493
|
+
}
|
|
3494
|
+
src/* log */.cM.timeEnd(TimingEnum.DISPLAY_SETS_TO_FIRST_IMAGE);
|
|
3495
|
+
src/* log */.cM.timeEnd(TimingEnum.STUDY_TO_FIRST_IMAGE);
|
|
3496
|
+
src/* log */.cM.timeEnd(TimingEnum.SCRIPT_TO_VIEW);
|
|
3497
|
+
imageTiming.viewportsWaiting -= 1;
|
|
3498
|
+
evt.detail.element.removeEventListener(esm.EVENTS.IMAGE_RENDERED, imageRenderedListener);
|
|
3499
|
+
if (!imageTiming.viewportsWaiting) {
|
|
3500
|
+
src/* log */.cM.timeEnd(TimingEnum.DISPLAY_SETS_TO_ALL_IMAGES);
|
|
3501
|
+
}
|
|
3502
|
+
}
|
|
3140
3503
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/init.tsx
|
|
3141
3504
|
|
|
3142
3505
|
|
|
@@ -3155,6 +3518,7 @@ function initDoubleClick(_ref) {
|
|
|
3155
3518
|
|
|
3156
3519
|
|
|
3157
3520
|
|
|
3521
|
+
|
|
3158
3522
|
// TODO: Cypress tests are currently grabbing this from the window?
|
|
3159
3523
|
window.cornerstone = esm;
|
|
3160
3524
|
window.cornerstoneTools = dist_esm;
|
|
@@ -3169,7 +3533,24 @@ async function init(_ref) {
|
|
|
3169
3533
|
configuration,
|
|
3170
3534
|
appConfig
|
|
3171
3535
|
} = _ref;
|
|
3172
|
-
|
|
3536
|
+
// Note: this should run first before initializing the cornerstone
|
|
3537
|
+
// DO NOT CHANGE THE ORDER
|
|
3538
|
+
const value = appConfig.useSharedArrayBuffer;
|
|
3539
|
+
let sharedArrayBufferDisabled = false;
|
|
3540
|
+
if (value === 'AUTO') {
|
|
3541
|
+
esm.setUseSharedArrayBuffer(esm.Enums.SharedArrayBufferModes.AUTO);
|
|
3542
|
+
} else if (value === 'FALSE' || value === false) {
|
|
3543
|
+
esm.setUseSharedArrayBuffer(esm.Enums.SharedArrayBufferModes.FALSE);
|
|
3544
|
+
sharedArrayBufferDisabled = true;
|
|
3545
|
+
} else {
|
|
3546
|
+
esm.setUseSharedArrayBuffer(esm.Enums.SharedArrayBufferModes.TRUE);
|
|
3547
|
+
}
|
|
3548
|
+
await (0,esm.init)({
|
|
3549
|
+
rendering: {
|
|
3550
|
+
preferSizeOverAccuracy: Boolean(appConfig.use16BitDataType),
|
|
3551
|
+
useNorm16Texture: Boolean(appConfig.use16BitDataType)
|
|
3552
|
+
}
|
|
3553
|
+
});
|
|
3173
3554
|
|
|
3174
3555
|
// For debugging e2e tests that are failing on CI
|
|
3175
3556
|
esm.setUseCPURendering(Boolean(appConfig.useCPURendering));
|
|
@@ -3181,34 +3562,35 @@ async function init(_ref) {
|
|
|
3181
3562
|
}
|
|
3182
3563
|
});
|
|
3183
3564
|
|
|
3184
|
-
// For debugging large datasets
|
|
3185
|
-
const
|
|
3186
|
-
|
|
3187
|
-
|
|
3565
|
+
// For debugging large datasets, otherwise prefer the defaults
|
|
3566
|
+
const {
|
|
3567
|
+
maxCacheSize
|
|
3568
|
+
} = appConfig;
|
|
3569
|
+
if (maxCacheSize) {
|
|
3570
|
+
esm.cache.setMaxCacheSize(maxCacheSize);
|
|
3571
|
+
}
|
|
3188
3572
|
initCornerstoneTools();
|
|
3189
3573
|
esm.Settings.getRuntimeSettings().set('useCursors', Boolean(appConfig.useCursors));
|
|
3190
3574
|
const {
|
|
3191
3575
|
userAuthenticationService,
|
|
3192
|
-
measurementService,
|
|
3193
3576
|
customizationService,
|
|
3194
|
-
displaySetService,
|
|
3195
|
-
uiDialogService,
|
|
3196
3577
|
uiModalService,
|
|
3197
3578
|
uiNotificationService,
|
|
3198
3579
|
cineService,
|
|
3199
3580
|
cornerstoneViewportService,
|
|
3200
3581
|
hangingProtocolService,
|
|
3201
3582
|
toolGroupService,
|
|
3583
|
+
toolbarService,
|
|
3202
3584
|
viewportGridService,
|
|
3203
3585
|
stateSyncService
|
|
3204
3586
|
} = servicesManager.services;
|
|
3205
3587
|
window.services = servicesManager.services;
|
|
3206
3588
|
window.extensionManager = extensionManager;
|
|
3207
3589
|
window.commandsManager = commandsManager;
|
|
3208
|
-
if (appConfig.showWarningMessageForCrossOrigin && !window.crossOriginIsolated) {
|
|
3590
|
+
if (appConfig.showWarningMessageForCrossOrigin && !window.crossOriginIsolated && !sharedArrayBufferDisabled) {
|
|
3209
3591
|
uiNotificationService.show({
|
|
3210
3592
|
title: 'Cross Origin Isolation',
|
|
3211
|
-
message: 'Cross Origin Isolation is not enabled,
|
|
3593
|
+
message: 'Cross Origin Isolation is not enabled, read more about it here: https://docs.ohif.org/faq/',
|
|
3212
3594
|
type: 'warning'
|
|
3213
3595
|
});
|
|
3214
3596
|
}
|
|
@@ -3254,7 +3636,7 @@ async function init(_ref) {
|
|
|
3254
3636
|
thumbnail: appConfig?.maxNumRequests?.thumbnail || 75,
|
|
3255
3637
|
prefetch: appConfig?.maxNumRequests?.prefetch || 10
|
|
3256
3638
|
};
|
|
3257
|
-
initWADOImageLoader(userAuthenticationService, appConfig);
|
|
3639
|
+
initWADOImageLoader(userAuthenticationService, appConfig, extensionManager);
|
|
3258
3640
|
|
|
3259
3641
|
/* Measurement Service */
|
|
3260
3642
|
this.measurementServiceSource = connectToolsToMeasurementService(servicesManager);
|
|
@@ -3289,11 +3671,51 @@ async function init(_ref) {
|
|
|
3289
3671
|
customizationService,
|
|
3290
3672
|
commandsManager
|
|
3291
3673
|
});
|
|
3292
|
-
|
|
3674
|
+
|
|
3675
|
+
/**
|
|
3676
|
+
* When a viewport gets a new display set, this call will go through all the
|
|
3677
|
+
* active tools in the toolbar, and call any commands registered in the
|
|
3678
|
+
* toolbar service with a callback to re-enable on displaying the viewport.
|
|
3679
|
+
*/
|
|
3680
|
+
const toolbarEventListener = evt => {
|
|
3293
3681
|
const {
|
|
3294
3682
|
element
|
|
3295
3683
|
} = evt.detail;
|
|
3296
|
-
|
|
3684
|
+
const activeTools = toolbarService.getActiveTools();
|
|
3685
|
+
activeTools.forEach(tool => {
|
|
3686
|
+
const toolData = toolbarService.getNestedButton(tool);
|
|
3687
|
+
const commands = toolData?.listeners?.[evt.type];
|
|
3688
|
+
commandsManager.run(commands, {
|
|
3689
|
+
element,
|
|
3690
|
+
evt
|
|
3691
|
+
});
|
|
3692
|
+
});
|
|
3693
|
+
};
|
|
3694
|
+
|
|
3695
|
+
/** Listens for active viewport events and fires the toolbar listeners */
|
|
3696
|
+
const activeViewportEventListener = evt => {
|
|
3697
|
+
const {
|
|
3698
|
+
viewportId
|
|
3699
|
+
} = evt;
|
|
3700
|
+
const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
|
|
3701
|
+
const activeTools = toolbarService.getActiveTools();
|
|
3702
|
+
activeTools.forEach(tool => {
|
|
3703
|
+
if (!toolGroup?._toolInstances?.[tool]) {
|
|
3704
|
+
return;
|
|
3705
|
+
}
|
|
3706
|
+
|
|
3707
|
+
// check if tool is active on the new viewport
|
|
3708
|
+
const toolEnabled = toolGroup._toolInstances[tool].mode === dist_esm.Enums.ToolModes.Enabled;
|
|
3709
|
+
if (!toolEnabled) {
|
|
3710
|
+
return;
|
|
3711
|
+
}
|
|
3712
|
+
const button = toolbarService.getNestedButton(tool);
|
|
3713
|
+
const commands = button?.listeners?.[evt.type];
|
|
3714
|
+
commandsManager.run(commands, {
|
|
3715
|
+
viewportId,
|
|
3716
|
+
evt
|
|
3717
|
+
});
|
|
3718
|
+
});
|
|
3297
3719
|
};
|
|
3298
3720
|
const resetCrosshairs = evt => {
|
|
3299
3721
|
const {
|
|
@@ -3316,12 +3738,22 @@ async function init(_ref) {
|
|
|
3316
3738
|
toolGroup.setToolEnabled('Crosshairs');
|
|
3317
3739
|
}
|
|
3318
3740
|
};
|
|
3741
|
+
esm.eventTarget.addEventListener(esm.EVENTS.STACK_VIEWPORT_NEW_STACK, evt => {
|
|
3742
|
+
const {
|
|
3743
|
+
element
|
|
3744
|
+
} = evt.detail;
|
|
3745
|
+
dist_esm.utilities.stackContextPrefetch.enable(element);
|
|
3746
|
+
});
|
|
3319
3747
|
function elementEnabledHandler(evt) {
|
|
3320
3748
|
const {
|
|
3321
3749
|
element
|
|
3322
3750
|
} = evt.detail;
|
|
3323
3751
|
element.addEventListener(esm.EVENTS.CAMERA_RESET, resetCrosshairs);
|
|
3324
|
-
esm.eventTarget.addEventListener(esm.EVENTS.STACK_VIEWPORT_NEW_STACK,
|
|
3752
|
+
esm.eventTarget.addEventListener(esm.EVENTS.STACK_VIEWPORT_NEW_STACK, toolbarEventListener);
|
|
3753
|
+
initViewTiming({
|
|
3754
|
+
element,
|
|
3755
|
+
eventTarget: esm.eventTarget
|
|
3756
|
+
});
|
|
3325
3757
|
}
|
|
3326
3758
|
function elementDisabledHandler(evt) {
|
|
3327
3759
|
const {
|
|
@@ -3338,31 +3770,7 @@ async function init(_ref) {
|
|
|
3338
3770
|
|
|
3339
3771
|
esm.eventTarget.addEventListener(esm.EVENTS.ELEMENT_ENABLED, elementEnabledHandler.bind(null));
|
|
3340
3772
|
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
|
-
});
|
|
3773
|
+
viewportGridService.subscribe(viewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED, activeViewportEventListener);
|
|
3366
3774
|
}
|
|
3367
3775
|
function CPUModal() {
|
|
3368
3776
|
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 +3795,12 @@ function _showCPURenderingModal(uiModalService, hangingProtocolService) {
|
|
|
3387
3795
|
});
|
|
3388
3796
|
}
|
|
3389
3797
|
// EXTERNAL MODULE: ../../../node_modules/react-dropzone/dist/es/index.js + 5 modules
|
|
3390
|
-
var es = __webpack_require__(
|
|
3798
|
+
var es = __webpack_require__(74834);
|
|
3391
3799
|
// EXTERNAL MODULE: ../../../node_modules/prop-types/index.js
|
|
3392
|
-
var prop_types = __webpack_require__(
|
|
3800
|
+
var prop_types = __webpack_require__(3827);
|
|
3393
3801
|
var prop_types_default = /*#__PURE__*/__webpack_require__.n(prop_types);
|
|
3394
3802
|
// EXTERNAL MODULE: ../../../node_modules/classnames/index.js
|
|
3395
|
-
var classnames = __webpack_require__(
|
|
3803
|
+
var classnames = __webpack_require__(44921);
|
|
3396
3804
|
var classnames_default = /*#__PURE__*/__webpack_require__.n(classnames);
|
|
3397
3805
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/DicomFileUploader.ts
|
|
3398
3806
|
|
|
@@ -3541,7 +3949,9 @@ class DicomFileUploader extends src/* PubSubService */.hC {
|
|
|
3541
3949
|
request.addEventListener('loadend', cleanUpCallback);
|
|
3542
3950
|
}
|
|
3543
3951
|
_checkDicomFile(arrayBuffer) {
|
|
3544
|
-
if (arrayBuffer.length <= 132)
|
|
3952
|
+
if (arrayBuffer.length <= 132) {
|
|
3953
|
+
return false;
|
|
3954
|
+
}
|
|
3545
3955
|
const arr = new Uint8Array(arrayBuffer.slice(128, 132));
|
|
3546
3956
|
// bytes from 128 to 132 must be "DICM"
|
|
3547
3957
|
return Array.from('DICM').every((char, i) => char.charCodeAt(0) === arr[i]);
|
|
@@ -3560,7 +3970,6 @@ const DicomUploadProgressItem = /*#__PURE__*/(0,react.memo)(_ref => {
|
|
|
3560
3970
|
const [percentComplete, setPercentComplete] = (0,react.useState)(dicomFileUploader.getPercentComplete());
|
|
3561
3971
|
const [failedReason, setFailedReason] = (0,react.useState)('');
|
|
3562
3972
|
const [status, setStatus] = (0,react.useState)(dicomFileUploader.getStatus());
|
|
3563
|
-
console.info(`${dicomFileUploader.getFileId()}`);
|
|
3564
3973
|
const isComplete = (0,react.useCallback)(() => {
|
|
3565
3974
|
return status === UploadStatus.Failed || status === UploadStatus.Cancelled || status === UploadStatus.Success;
|
|
3566
3975
|
}, [status]);
|
|
@@ -3601,25 +4010,25 @@ const DicomUploadProgressItem = /*#__PURE__*/(0,react.memo)(_ref => {
|
|
|
3601
4010
|
}
|
|
3602
4011
|
};
|
|
3603
4012
|
return /*#__PURE__*/react.createElement("div", {
|
|
3604
|
-
className: "
|
|
4013
|
+
className: "min-h-14 border-secondary-light flex w-full items-center overflow-hidden border-b p-2.5 text-lg"
|
|
3605
4014
|
}, /*#__PURE__*/react.createElement("div", {
|
|
3606
|
-
className: "
|
|
4015
|
+
className: "self-top flex w-0 shrink grow flex-col gap-1"
|
|
3607
4016
|
}, /*#__PURE__*/react.createElement("div", {
|
|
3608
4017
|
className: "flex gap-4"
|
|
3609
4018
|
}, /*#__PURE__*/react.createElement("div", {
|
|
3610
|
-
className: "flex w-6
|
|
4019
|
+
className: "flex w-6 shrink-0 items-center justify-center"
|
|
3611
4020
|
}, getStatusIcon()), /*#__PURE__*/react.createElement("div", {
|
|
3612
|
-
className: "text-ellipsis whitespace-nowrap
|
|
4021
|
+
className: "overflow-hidden text-ellipsis whitespace-nowrap"
|
|
3613
4022
|
}, dicomFileUploader.getFileName())), failedReason && /*#__PURE__*/react.createElement("div", {
|
|
3614
4023
|
className: "pl-10"
|
|
3615
4024
|
}, failedReason)), /*#__PURE__*/react.createElement("div", {
|
|
3616
|
-
className: "w-24
|
|
4025
|
+
className: "flex w-24 items-center"
|
|
3617
4026
|
}, !isComplete() && /*#__PURE__*/react.createElement(react.Fragment, null, dicomFileUploader.getStatus() === UploadStatus.InProgress && /*#__PURE__*/react.createElement("div", {
|
|
3618
4027
|
className: "w-10 text-right"
|
|
3619
4028
|
}, percentComplete, "%"), /*#__PURE__*/react.createElement("div", {
|
|
3620
|
-
className: "flex cursor-pointer
|
|
4029
|
+
className: "ml-auto flex cursor-pointer"
|
|
3621
4030
|
}, /*#__PURE__*/react.createElement(ui_src/* Icon */.JO, {
|
|
3622
|
-
className: "
|
|
4031
|
+
className: "text-primary-active self-center",
|
|
3623
4032
|
name: "close",
|
|
3624
4033
|
onClick: cancelUpload
|
|
3625
4034
|
})))));
|
|
@@ -3846,7 +4255,7 @@ function DicomUploadProgress(_ref) {
|
|
|
3846
4255
|
}, []);
|
|
3847
4256
|
const getNumCompletedAndTimeRemainingComponent = () => {
|
|
3848
4257
|
return /*#__PURE__*/react.createElement("div", {
|
|
3849
|
-
className: "
|
|
4258
|
+
className: "bg-primary-dark flex h-14 items-center px-1 pb-4 text-lg"
|
|
3850
4259
|
}, numFilesCompleted === dicomFileUploaderArr.length ? /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("span", {
|
|
3851
4260
|
className: NO_WRAP_ELLIPSIS_CLASS_NAMES
|
|
3852
4261
|
}, `${dicomFileUploaderArr.length} ${dicomFileUploaderArr.length > 1 ? 'files' : 'file'} completed.`), /*#__PURE__*/react.createElement(ui_src/* Button */.zx, {
|
|
@@ -3861,13 +4270,13 @@ function DicomUploadProgress(_ref) {
|
|
|
3861
4270
|
}, ' files completed.', "\xA0"), /*#__PURE__*/react.createElement("span", {
|
|
3862
4271
|
className: NO_WRAP_ELLIPSIS_CLASS_NAMES
|
|
3863
4272
|
}, timeRemaining ? `Less than ${getFormattedTimeRemaining()} remaining. ` : ''), /*#__PURE__*/react.createElement("span", {
|
|
3864
|
-
className: classnames_default()(NO_WRAP_ELLIPSIS_CLASS_NAMES, '
|
|
4273
|
+
className: classnames_default()(NO_WRAP_ELLIPSIS_CLASS_NAMES, 'text-primary-active hover:text-primary-light active:text-aqua-pale ml-auto cursor-pointer'),
|
|
3865
4274
|
onClick: cancelAllUploads
|
|
3866
4275
|
}, "Cancel All Uploads")));
|
|
3867
4276
|
};
|
|
3868
4277
|
const getShowFailedOnlyIconComponent = () => {
|
|
3869
4278
|
return /*#__PURE__*/react.createElement("div", {
|
|
3870
|
-
className: "ml-auto flex justify-center
|
|
4279
|
+
className: "ml-auto flex w-6 justify-center"
|
|
3871
4280
|
}, numFails > 0 && /*#__PURE__*/react.createElement("div", {
|
|
3872
4281
|
onClick: () => setShowFailedOnly(currentShowFailedOnly => !currentShowFailedOnly)
|
|
3873
4282
|
}, /*#__PURE__*/react.createElement(ui_src/* Icon */.JO, {
|
|
@@ -3877,28 +4286,28 @@ function DicomUploadProgress(_ref) {
|
|
|
3877
4286
|
};
|
|
3878
4287
|
const getPercentCompleteComponent = () => {
|
|
3879
4288
|
return /*#__PURE__*/react.createElement("div", {
|
|
3880
|
-
className: "overflow-y-scroll
|
|
4289
|
+
className: "ohif-scrollbar border-secondary-light overflow-y-scroll border-b px-2"
|
|
3881
4290
|
}, /*#__PURE__*/react.createElement("div", {
|
|
3882
|
-
className: "flex w-full p-2.5
|
|
4291
|
+
className: "min-h-14 flex w-full items-center p-2.5"
|
|
3883
4292
|
}, numFilesCompleted === dicomFileUploaderArr.length ? /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
3884
|
-
className: "text-
|
|
4293
|
+
className: "text-primary-light text-xl"
|
|
3885
4294
|
}, numFails > 0 ? `Completed with ${numFails} ${numFails > 1 ? 'errors' : 'error'}!` : 'Completed!'), getShowFailedOnlyIconComponent()) : /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
3886
4295
|
ref: progressBarContainerRef,
|
|
3887
4296
|
className: "flex-grow"
|
|
3888
4297
|
}, /*#__PURE__*/react.createElement(ui_src/* ProgressLoadingBar */.YE, {
|
|
3889
4298
|
progress: showInfiniteProgressBar() ? undefined : Math.min(100, percentComplete)
|
|
3890
4299
|
})), /*#__PURE__*/react.createElement("div", {
|
|
3891
|
-
className: "
|
|
4300
|
+
className: "ml-1 flex w-24 items-center"
|
|
3892
4301
|
}, /*#__PURE__*/react.createElement("div", {
|
|
3893
4302
|
className: "w-10 text-right"
|
|
3894
4303
|
}, `${getPercentCompleteRounded()}%`), getShowFailedOnlyIconComponent()))));
|
|
3895
4304
|
};
|
|
3896
4305
|
return /*#__PURE__*/react.createElement("div", {
|
|
3897
|
-
className: "flex flex-col
|
|
4306
|
+
className: "flex grow flex-col"
|
|
3898
4307
|
}, getNumCompletedAndTimeRemainingComponent(), /*#__PURE__*/react.createElement("div", {
|
|
3899
|
-
className: "flex flex-col bg-black text-lg
|
|
4308
|
+
className: "flex grow flex-col overflow-hidden bg-black text-lg"
|
|
3900
4309
|
}, getPercentCompleteComponent(), /*#__PURE__*/react.createElement("div", {
|
|
3901
|
-
className: "overflow-y-scroll
|
|
4310
|
+
className: "ohif-scrollbar h-1 grow overflow-y-scroll px-2"
|
|
3902
4311
|
}, dicomFileUploaderArr.filter(dicomFileUploader => !showFailedOnly || dicomFileUploader.getStatus() === UploadStatus.Failed).map(dicomFileUploader => /*#__PURE__*/react.createElement(DicomUpload_DicomUploadProgressItem, {
|
|
3903
4312
|
key: dicomFileUploader.getFileId(),
|
|
3904
4313
|
dicomFileUploader: dicomFileUploader
|
|
@@ -3945,7 +4354,7 @@ function DicomUpload(_ref) {
|
|
|
3945
4354
|
getRootProps
|
|
3946
4355
|
} = _ref2;
|
|
3947
4356
|
return /*#__PURE__*/react.createElement("div", _extends({}, getRootProps(), {
|
|
3948
|
-
className: "
|
|
4357
|
+
className: "dicom-upload-drop-area-border-dash m-5 flex h-full flex-col items-center justify-center"
|
|
3949
4358
|
}), /*#__PURE__*/react.createElement("div", {
|
|
3950
4359
|
className: "flex gap-3"
|
|
3951
4360
|
}, /*#__PURE__*/react.createElement(es/* default */.Z, {
|
|
@@ -3969,7 +4378,7 @@ function DicomUpload(_ref) {
|
|
|
3969
4378
|
getInputProps
|
|
3970
4379
|
} = _ref4;
|
|
3971
4380
|
return /*#__PURE__*/react.createElement("div", getRootProps(), /*#__PURE__*/react.createElement(ui_src/* Button */.zx, {
|
|
3972
|
-
type: ui_src/* ButtonEnums.type */.LZ.
|
|
4381
|
+
type: ui_src/* ButtonEnums.type */.LZ.dt.secondary,
|
|
3973
4382
|
disabled: false,
|
|
3974
4383
|
onClick: () => {}
|
|
3975
4384
|
}, 'Add folder', /*#__PURE__*/react.createElement("input", _extends({}, getInputProps(), {
|
|
@@ -3979,7 +4388,7 @@ function DicomUpload(_ref) {
|
|
|
3979
4388
|
})), /*#__PURE__*/react.createElement("div", {
|
|
3980
4389
|
className: "pt-5"
|
|
3981
4390
|
}, "or drag images or folders here"), /*#__PURE__*/react.createElement("div", {
|
|
3982
|
-
className: "
|
|
4391
|
+
className: "text-aqua-pale pt-3 text-lg"
|
|
3983
4392
|
}, "(DICOM files supported)"));
|
|
3984
4393
|
});
|
|
3985
4394
|
};
|
|
@@ -4043,7 +4452,7 @@ function getCustomizationModule() {
|
|
|
4043
4452
|
}
|
|
4044
4453
|
/* harmony default export */ const src_getCustomizationModule = (getCustomizationModule);
|
|
4045
4454
|
// EXTERNAL MODULE: ../../../node_modules/html2canvas/dist/html2canvas.esm.js
|
|
4046
|
-
var html2canvas_esm = __webpack_require__(
|
|
4455
|
+
var html2canvas_esm = __webpack_require__(76010);
|
|
4047
4456
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/CornerstoneViewportDownloadForm.tsx
|
|
4048
4457
|
|
|
4049
4458
|
|
|
@@ -4059,10 +4468,10 @@ const VIEWPORT_ID = 'cornerstone-viewport-download-form';
|
|
|
4059
4468
|
const CornerstoneViewportDownloadForm = _ref => {
|
|
4060
4469
|
let {
|
|
4061
4470
|
onClose,
|
|
4062
|
-
|
|
4471
|
+
activeViewportId: activeViewportIdProp,
|
|
4063
4472
|
cornerstoneViewportService
|
|
4064
4473
|
} = _ref;
|
|
4065
|
-
const enabledElement = (0,state/* getEnabledElement */.K8)(
|
|
4474
|
+
const enabledElement = (0,state/* getEnabledElement */.K8)(activeViewportIdProp);
|
|
4066
4475
|
const activeViewportElement = enabledElement?.element;
|
|
4067
4476
|
const activeViewportEnabledElement = (0,esm.getEnabledElement)(activeViewportElement);
|
|
4068
4477
|
const {
|
|
@@ -4181,13 +4590,18 @@ const CornerstoneViewportDownloadForm = _ref => {
|
|
|
4181
4590
|
const imageId = viewport.getCurrentImageId();
|
|
4182
4591
|
const properties = viewport.getProperties();
|
|
4183
4592
|
downloadViewport.setStack([imageId]).then(() => {
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4593
|
+
try {
|
|
4594
|
+
downloadViewport.setProperties(properties);
|
|
4595
|
+
const newWidth = Math.min(width || image.width, MAX_TEXTURE_SIZE);
|
|
4596
|
+
const newHeight = Math.min(height || image.height, MAX_TEXTURE_SIZE);
|
|
4597
|
+
resolve({
|
|
4598
|
+
width: newWidth,
|
|
4599
|
+
height: newHeight
|
|
4600
|
+
});
|
|
4601
|
+
} catch (e) {
|
|
4602
|
+
// Happens on clicking the cancel button
|
|
4603
|
+
console.warn('Unable to set properties', e);
|
|
4604
|
+
}
|
|
4191
4605
|
});
|
|
4192
4606
|
} else if (downloadViewport instanceof esm.VolumeViewport) {
|
|
4193
4607
|
const actors = viewport.getActors();
|
|
@@ -4264,74 +4678,74 @@ const CornerstoneViewportDownloadForm = _ref => {
|
|
|
4264
4678
|
};
|
|
4265
4679
|
CornerstoneViewportDownloadForm.propTypes = {
|
|
4266
4680
|
onClose: (prop_types_default()).func,
|
|
4267
|
-
|
|
4681
|
+
activeViewportId: (prop_types_default()).string.isRequired
|
|
4268
4682
|
};
|
|
4269
4683
|
/* 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
4684
|
;// 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 = [];
|
|
4685
|
+
const STACK_SYNC_NAME = 'stackImageSync';
|
|
4300
4686
|
function toggleStackImageSync(_ref) {
|
|
4301
4687
|
let {
|
|
4302
4688
|
toggledState,
|
|
4303
4689
|
servicesManager,
|
|
4304
|
-
|
|
4690
|
+
viewports: providedViewports
|
|
4305
4691
|
} = _ref;
|
|
4692
|
+
if (!toggledState) {
|
|
4693
|
+
return disableSync(STACK_SYNC_NAME, servicesManager);
|
|
4694
|
+
}
|
|
4306
4695
|
const {
|
|
4307
4696
|
syncGroupService,
|
|
4308
4697
|
viewportGridService,
|
|
4309
4698
|
displaySetService,
|
|
4310
4699
|
cornerstoneViewportService
|
|
4311
4700
|
} = servicesManager.services;
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4701
|
+
const viewports = providedViewports || getReconstructableStackViewports(viewportGridService, displaySetService);
|
|
4702
|
+
|
|
4703
|
+
// create synchronization group and add the viewports to it.
|
|
4704
|
+
viewports.forEach(gridViewport => {
|
|
4705
|
+
const {
|
|
4706
|
+
viewportId
|
|
4707
|
+
} = gridViewport.viewportOptions;
|
|
4708
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
4709
|
+
if (!viewport) {
|
|
4710
|
+
return;
|
|
4711
|
+
}
|
|
4712
|
+
syncGroupService.addViewportToSyncGroup(viewportId, viewport.getRenderingEngine().id, {
|
|
4713
|
+
type: 'stackimage',
|
|
4714
|
+
id: STACK_SYNC_NAME,
|
|
4715
|
+
source: true,
|
|
4716
|
+
target: true
|
|
4325
4717
|
});
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4718
|
+
});
|
|
4719
|
+
}
|
|
4720
|
+
function disableSync(syncName, servicesManager) {
|
|
4721
|
+
const {
|
|
4722
|
+
syncGroupService,
|
|
4723
|
+
viewportGridService,
|
|
4724
|
+
displaySetService,
|
|
4725
|
+
cornerstoneViewportService
|
|
4726
|
+
} = servicesManager.services;
|
|
4727
|
+
const viewports = getReconstructableStackViewports(viewportGridService, displaySetService);
|
|
4728
|
+
viewports.forEach(gridViewport => {
|
|
4729
|
+
const {
|
|
4730
|
+
viewportId
|
|
4731
|
+
} = gridViewport.viewportOptions;
|
|
4732
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
4733
|
+
if (!viewport) {
|
|
4734
|
+
return;
|
|
4735
|
+
}
|
|
4736
|
+
syncGroupService.removeViewportFromSyncGroup(viewport.id, viewport.getRenderingEngine().id, syncName);
|
|
4737
|
+
});
|
|
4738
|
+
}
|
|
4329
4739
|
|
|
4330
|
-
|
|
4740
|
+
/**
|
|
4741
|
+
* Gets the consistent spacing stack viewport types, which are the ones which
|
|
4742
|
+
* can be navigated using the stack image sync right now.
|
|
4743
|
+
*/
|
|
4744
|
+
function getReconstructableStackViewports(viewportGridService, displaySetService) {
|
|
4331
4745
|
let {
|
|
4332
4746
|
viewports
|
|
4333
4747
|
} = viewportGridService.getState();
|
|
4334
|
-
|
|
4748
|
+
viewports = [...viewports.values()];
|
|
4335
4749
|
// filter empty viewports
|
|
4336
4750
|
viewports = viewports.filter(viewport => viewport.displaySetInstanceUIDs && viewport.displaySetInstanceUIDs.length);
|
|
4337
4751
|
|
|
@@ -4342,103 +4756,16 @@ function toggleStackImageSync(_ref) {
|
|
|
4342
4756
|
} = viewport;
|
|
4343
4757
|
for (const displaySetInstanceUID of displaySetInstanceUIDs) {
|
|
4344
4758
|
const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
|
|
4759
|
+
|
|
4760
|
+
// TODO - add a better test than isReconstructable
|
|
4345
4761
|
if (displaySet && displaySet.isReconstructable) {
|
|
4346
4762
|
return true;
|
|
4347
4763
|
}
|
|
4348
4764
|
return false;
|
|
4349
4765
|
}
|
|
4350
4766
|
});
|
|
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
|
-
});
|
|
4410
|
-
}
|
|
4411
|
-
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/utils/selection.ts
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
/**
|
|
4415
|
-
* Check whether an annotation from imaging library is selected or not.
|
|
4416
|
-
* @param {string} annotationUID uid of imaging library annotation
|
|
4417
|
-
* @returns boolean
|
|
4418
|
-
*/
|
|
4419
|
-
function isAnnotationSelected(annotationUID) {
|
|
4420
|
-
return dist_esm.annotation.selection.isAnnotationSelected(annotationUID);
|
|
4421
|
-
}
|
|
4422
|
-
|
|
4423
|
-
/**
|
|
4424
|
-
* Change an annotation from imaging library's selected property.
|
|
4425
|
-
* @param annotationUID - uid of imaging library annotation
|
|
4426
|
-
* @param selected - new value for selected
|
|
4427
|
-
*/
|
|
4428
|
-
function setAnnotationSelected(annotationUID, selected) {
|
|
4429
|
-
const isCurrentSelected = isAnnotationSelected(annotationUID);
|
|
4430
|
-
// branch cut, avoid invoking imaging library unnecessarily.
|
|
4431
|
-
if (isCurrentSelected !== selected) {
|
|
4432
|
-
dist_esm.annotation.selection.setAnnotationSelected(annotationUID, selected);
|
|
4433
|
-
}
|
|
4434
|
-
}
|
|
4435
|
-
function getFirstAnnotationSelected(element) {
|
|
4436
|
-
const [selectedAnnotationUID] = dist_esm.annotation.selection.getAnnotationsSelected() || [];
|
|
4437
|
-
if (selectedAnnotationUID) {
|
|
4438
|
-
return dist_esm.annotation.state.getAnnotation(selectedAnnotationUID);
|
|
4439
|
-
}
|
|
4767
|
+
return viewports;
|
|
4440
4768
|
}
|
|
4441
|
-
|
|
4442
4769
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/commandsModule.ts
|
|
4443
4770
|
|
|
4444
4771
|
|
|
@@ -4583,7 +4910,7 @@ function commandsModule(_ref) {
|
|
|
4583
4910
|
* @param props - containing the updates to apply
|
|
4584
4911
|
* @param props.measurementKey - chooses the measurement key to apply the
|
|
4585
4912
|
* code to. This will typically be finding or site to apply a
|
|
4586
|
-
*
|
|
4913
|
+
* finding code or a findingSites code.
|
|
4587
4914
|
* @param props.code - A coding scheme value from DICOM, including:
|
|
4588
4915
|
* * CodeValue - the language independent code, for example '1234'
|
|
4589
4916
|
* * CodingSchemeDesignator - the issue of the code value
|
|
@@ -4650,8 +4977,7 @@ function commandsModule(_ref) {
|
|
|
4650
4977
|
console.warn('No viewport found for viewportId:', viewportId);
|
|
4651
4978
|
return;
|
|
4652
4979
|
}
|
|
4653
|
-
|
|
4654
|
-
viewportGridService.setActiveViewportIndex(viewportIndex);
|
|
4980
|
+
viewportGridService.setActiveViewportId(viewportId);
|
|
4655
4981
|
},
|
|
4656
4982
|
arrowTextCallback: _ref7 => {
|
|
4657
4983
|
let {
|
|
@@ -4660,6 +4986,22 @@ function commandsModule(_ref) {
|
|
|
4660
4986
|
} = _ref7;
|
|
4661
4987
|
utils_callInputDialog(uiDialogService, data, callback);
|
|
4662
4988
|
},
|
|
4989
|
+
cleanUpCrosshairs: () => {
|
|
4990
|
+
// if the crosshairs tool is active, deactivate it and set window level active
|
|
4991
|
+
// since we are going back to main non-mpr HP
|
|
4992
|
+
const activeViewportToolGroup = toolGroupService.getToolGroup(null);
|
|
4993
|
+
if (activeViewportToolGroup._toolInstances?.Crosshairs?.mode === dist_esm.Enums.ToolModes.Active) {
|
|
4994
|
+
actions.toolbarServiceRecordInteraction({
|
|
4995
|
+
interactionType: 'tool',
|
|
4996
|
+
commands: [{
|
|
4997
|
+
commandOptions: {
|
|
4998
|
+
toolName: 'WindowLevel'
|
|
4999
|
+
},
|
|
5000
|
+
context: 'CORNERSTONE'
|
|
5001
|
+
}]
|
|
5002
|
+
});
|
|
5003
|
+
}
|
|
5004
|
+
},
|
|
4663
5005
|
toggleCine: () => {
|
|
4664
5006
|
const {
|
|
4665
5007
|
viewports
|
|
@@ -4716,10 +5058,16 @@ function commandsModule(_ref) {
|
|
|
4716
5058
|
toolbarServiceRecordInteraction: props => {
|
|
4717
5059
|
toolbarService.recordInteraction(props);
|
|
4718
5060
|
},
|
|
5061
|
+
// Enable or disable a toggleable command, without calling the activation
|
|
5062
|
+
// Used to setup already active tools from hanging protocols
|
|
5063
|
+
setToolbarToggled: props => {
|
|
5064
|
+
toolbarService.setToggled(props.toolId, props.isActive ?? true);
|
|
5065
|
+
},
|
|
4719
5066
|
setToolActive: _ref9 => {
|
|
4720
5067
|
let {
|
|
4721
5068
|
toolName,
|
|
4722
|
-
toolGroupId = null
|
|
5069
|
+
toolGroupId = null,
|
|
5070
|
+
toggledState
|
|
4723
5071
|
} = _ref9;
|
|
4724
5072
|
if (toolName === 'Crosshairs') {
|
|
4725
5073
|
const activeViewportToolGroup = toolGroupService.getToolGroup(null);
|
|
@@ -4735,23 +5083,12 @@ function commandsModule(_ref) {
|
|
|
4735
5083
|
}
|
|
4736
5084
|
const {
|
|
4737
5085
|
viewports
|
|
4738
|
-
} = viewportGridService.getState()
|
|
4739
|
-
|
|
4740
|
-
};
|
|
4741
|
-
const toolGroup = toolGroupService.getToolGroup(toolGroupId);
|
|
4742
|
-
const toolGroupViewportIds = toolGroup?.getViewportIds?.();
|
|
4743
|
-
|
|
4744
|
-
// if toolGroup has been destroyed, or its viewports have been removed
|
|
4745
|
-
if (!toolGroupViewportIds || !toolGroupViewportIds.length) {
|
|
5086
|
+
} = viewportGridService.getState();
|
|
5087
|
+
if (!viewports.size) {
|
|
4746
5088
|
return;
|
|
4747
5089
|
}
|
|
4748
|
-
const
|
|
4749
|
-
|
|
4750
|
-
return false;
|
|
4751
|
-
}
|
|
4752
|
-
return toolGroupViewportIds.includes(viewport.viewportOptions.viewportId);
|
|
4753
|
-
});
|
|
4754
|
-
if (!filteredViewports.length) {
|
|
5090
|
+
const toolGroup = toolGroupService.getToolGroup(toolGroupId);
|
|
5091
|
+
if (!toolGroup) {
|
|
4755
5092
|
return;
|
|
4756
5093
|
}
|
|
4757
5094
|
if (!toolGroup.getToolInstance(toolName)) {
|
|
@@ -4773,6 +5110,14 @@ function commandsModule(_ref) {
|
|
|
4773
5110
|
toolGroup.setToolPassive(activeToolName);
|
|
4774
5111
|
}
|
|
4775
5112
|
}
|
|
5113
|
+
|
|
5114
|
+
// If there is a toggle state, then simply set the enabled/disabled state without
|
|
5115
|
+
// setting the tool active.
|
|
5116
|
+
if (toggledState != null) {
|
|
5117
|
+
toggledState ? toolGroup.setToolEnabled(toolName) : toolGroup.setToolDisabled(toolName);
|
|
5118
|
+
return;
|
|
5119
|
+
}
|
|
5120
|
+
|
|
4776
5121
|
// Set the new toolName to be active
|
|
4777
5122
|
toolGroup.setToolActive(toolName, {
|
|
4778
5123
|
bindings: [{
|
|
@@ -4782,9 +5127,9 @@ function commandsModule(_ref) {
|
|
|
4782
5127
|
},
|
|
4783
5128
|
showDownloadViewportModal: () => {
|
|
4784
5129
|
const {
|
|
4785
|
-
|
|
5130
|
+
activeViewportId
|
|
4786
5131
|
} = viewportGridService.getState();
|
|
4787
|
-
if (!cornerstoneViewportService.
|
|
5132
|
+
if (!cornerstoneViewportService.getCornerstoneViewport(activeViewportId)) {
|
|
4788
5133
|
// Cannot download a non-cornerstone viewport (image).
|
|
4789
5134
|
uiNotificationService.show({
|
|
4790
5135
|
title: 'Download Image',
|
|
@@ -4801,7 +5146,7 @@ function commandsModule(_ref) {
|
|
|
4801
5146
|
content: utils_CornerstoneViewportDownloadForm,
|
|
4802
5147
|
title: 'Download High Quality Image',
|
|
4803
5148
|
contentProps: {
|
|
4804
|
-
|
|
5149
|
+
activeViewportId,
|
|
4805
5150
|
onClose: uiModalService.hide,
|
|
4806
5151
|
cornerstoneViewportService
|
|
4807
5152
|
}
|
|
@@ -4882,15 +5227,13 @@ function commandsModule(_ref) {
|
|
|
4882
5227
|
const {
|
|
4883
5228
|
viewport
|
|
4884
5229
|
} = enabledElement;
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
viewport.render();
|
|
4893
|
-
}
|
|
5230
|
+
const {
|
|
5231
|
+
invert
|
|
5232
|
+
} = viewport.getProperties();
|
|
5233
|
+
viewport.setProperties({
|
|
5234
|
+
invert: !invert
|
|
5235
|
+
});
|
|
5236
|
+
viewport.render();
|
|
4894
5237
|
},
|
|
4895
5238
|
resetViewport: () => {
|
|
4896
5239
|
const enabledElement = _getActiveViewportEnabledElement();
|
|
@@ -4904,7 +5247,7 @@ function commandsModule(_ref) {
|
|
|
4904
5247
|
viewport.resetProperties();
|
|
4905
5248
|
viewport.resetCamera();
|
|
4906
5249
|
} else {
|
|
4907
|
-
|
|
5250
|
+
viewport.resetProperties();
|
|
4908
5251
|
viewport.resetCamera();
|
|
4909
5252
|
}
|
|
4910
5253
|
viewport.render();
|
|
@@ -4993,12 +5336,12 @@ function commandsModule(_ref) {
|
|
|
4993
5336
|
},
|
|
4994
5337
|
setViewportColormap: _ref15 => {
|
|
4995
5338
|
let {
|
|
4996
|
-
|
|
5339
|
+
viewportId,
|
|
4997
5340
|
displaySetInstanceUID,
|
|
4998
5341
|
colormap,
|
|
4999
5342
|
immediate = false
|
|
5000
5343
|
} = _ref15;
|
|
5001
|
-
const viewport = cornerstoneViewportService.
|
|
5344
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
5002
5345
|
const actorEntries = viewport.getActors();
|
|
5003
5346
|
const actorEntry = actorEntries.find(actorEntry => {
|
|
5004
5347
|
return actorEntry.uid.includes(displaySetInstanceUID);
|
|
@@ -5015,51 +5358,53 @@ function commandsModule(_ref) {
|
|
|
5015
5358
|
viewport.render();
|
|
5016
5359
|
}
|
|
5017
5360
|
},
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
} = viewportGridService.getState();
|
|
5023
|
-
const nextViewportIndex = (activeViewportIndex + 1) % viewports.length;
|
|
5024
|
-
viewportGridService.setActiveViewportIndex(nextViewportIndex);
|
|
5025
|
-
},
|
|
5026
|
-
decrementActiveViewport: () => {
|
|
5361
|
+
changeActiveViewport: _ref16 => {
|
|
5362
|
+
let {
|
|
5363
|
+
direction = 1
|
|
5364
|
+
} = _ref16;
|
|
5027
5365
|
const {
|
|
5028
|
-
|
|
5366
|
+
activeViewportId,
|
|
5029
5367
|
viewports
|
|
5030
5368
|
} = viewportGridService.getState();
|
|
5031
|
-
const
|
|
5032
|
-
|
|
5369
|
+
const viewportIds = Array.from(viewports.keys());
|
|
5370
|
+
const currentIndex = viewportIds.indexOf(activeViewportId);
|
|
5371
|
+
const nextViewportIndex = (currentIndex + direction + viewportIds.length) % viewportIds.length;
|
|
5372
|
+
viewportGridService.setActiveViewportId(viewportIds[nextViewportIndex]);
|
|
5033
5373
|
},
|
|
5034
|
-
toggleStackImageSync:
|
|
5374
|
+
toggleStackImageSync: _ref17 => {
|
|
5035
5375
|
let {
|
|
5036
5376
|
toggledState
|
|
5037
|
-
} =
|
|
5377
|
+
} = _ref17;
|
|
5038
5378
|
toggleStackImageSync({
|
|
5039
|
-
getEnabledElement: esm.getEnabledElement,
|
|
5040
5379
|
servicesManager,
|
|
5041
5380
|
toggledState
|
|
5042
|
-
});
|
|
5043
|
-
},
|
|
5044
|
-
|
|
5045
|
-
let {
|
|
5046
|
-
toggledState
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
if (!toggledState) {
|
|
5055
|
-
toolGroup.setToolDisabled(dist_esm.ReferenceLinesTool.toolName);
|
|
5381
|
+
});
|
|
5382
|
+
},
|
|
5383
|
+
setSourceViewportForReferenceLinesTool: _ref18 => {
|
|
5384
|
+
let {
|
|
5385
|
+
toggledState,
|
|
5386
|
+
viewportId
|
|
5387
|
+
} = _ref18;
|
|
5388
|
+
if (!viewportId) {
|
|
5389
|
+
const {
|
|
5390
|
+
activeViewportId
|
|
5391
|
+
} = viewportGridService.getState();
|
|
5392
|
+
viewportId = activeViewportId;
|
|
5056
5393
|
}
|
|
5394
|
+
const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
|
|
5057
5395
|
toolGroup.setToolConfiguration(dist_esm.ReferenceLinesTool.toolName, {
|
|
5058
5396
|
sourceViewportId: viewportId
|
|
5059
5397
|
}, true // overwrite
|
|
5060
5398
|
);
|
|
5399
|
+
},
|
|
5061
5400
|
|
|
5062
|
-
|
|
5401
|
+
storePresentation: _ref19 => {
|
|
5402
|
+
let {
|
|
5403
|
+
viewportId
|
|
5404
|
+
} = _ref19;
|
|
5405
|
+
cornerstoneViewportService.storePresentation({
|
|
5406
|
+
viewportId
|
|
5407
|
+
});
|
|
5063
5408
|
}
|
|
5064
5409
|
};
|
|
5065
5410
|
const definitions = {
|
|
@@ -5114,10 +5459,13 @@ function commandsModule(_ref) {
|
|
|
5114
5459
|
}
|
|
5115
5460
|
},
|
|
5116
5461
|
incrementActiveViewport: {
|
|
5117
|
-
commandFn: actions.
|
|
5462
|
+
commandFn: actions.changeActiveViewport
|
|
5118
5463
|
},
|
|
5119
5464
|
decrementActiveViewport: {
|
|
5120
|
-
commandFn: actions.
|
|
5465
|
+
commandFn: actions.changeActiveViewport,
|
|
5466
|
+
options: {
|
|
5467
|
+
direction: -1
|
|
5468
|
+
}
|
|
5121
5469
|
},
|
|
5122
5470
|
flipViewportHorizontal: {
|
|
5123
5471
|
commandFn: actions.flipViewportHorizontal
|
|
@@ -5194,8 +5542,17 @@ function commandsModule(_ref) {
|
|
|
5194
5542
|
toggleStackImageSync: {
|
|
5195
5543
|
commandFn: actions.toggleStackImageSync
|
|
5196
5544
|
},
|
|
5197
|
-
|
|
5198
|
-
commandFn: actions.
|
|
5545
|
+
setSourceViewportForReferenceLinesTool: {
|
|
5546
|
+
commandFn: actions.setSourceViewportForReferenceLinesTool
|
|
5547
|
+
},
|
|
5548
|
+
storePresentation: {
|
|
5549
|
+
commandFn: actions.storePresentation
|
|
5550
|
+
},
|
|
5551
|
+
setToolbarToggled: {
|
|
5552
|
+
commandFn: actions.setToolbarToggled
|
|
5553
|
+
},
|
|
5554
|
+
cleanUpCrosshairs: {
|
|
5555
|
+
commandFn: actions.cleanUpCrosshairs
|
|
5199
5556
|
}
|
|
5200
5557
|
};
|
|
5201
5558
|
return {
|
|
@@ -5210,9 +5567,8 @@ const mpr = {
|
|
|
5210
5567
|
id: 'mpr',
|
|
5211
5568
|
name: 'Multi-Planar Reconstruction',
|
|
5212
5569
|
locked: true,
|
|
5213
|
-
hasUpdatedPriorsInformation: false,
|
|
5214
5570
|
createdDate: '2021-02-23',
|
|
5215
|
-
modifiedDate: '2023-
|
|
5571
|
+
modifiedDate: '2023-08-15',
|
|
5216
5572
|
availableTo: {},
|
|
5217
5573
|
editableBy: {},
|
|
5218
5574
|
// Unknown number of priors referenced - so just match any study
|
|
@@ -5230,16 +5586,7 @@ const mpr = {
|
|
|
5230
5586
|
}],
|
|
5231
5587
|
// Turns off crosshairs when switching out of MPR mode
|
|
5232
5588
|
onProtocolExit: [{
|
|
5233
|
-
commandName: '
|
|
5234
|
-
commandOptions: {
|
|
5235
|
-
interactionType: 'tool',
|
|
5236
|
-
commands: [{
|
|
5237
|
-
commandOptions: {
|
|
5238
|
-
toolName: 'WindowLevel'
|
|
5239
|
-
},
|
|
5240
|
-
context: 'CORNERSTONE'
|
|
5241
|
-
}]
|
|
5242
|
-
}
|
|
5589
|
+
commandName: 'cleanUpCrosshairs'
|
|
5243
5590
|
}]
|
|
5244
5591
|
},
|
|
5245
5592
|
displaySetSelectors: {
|
|
@@ -5283,6 +5630,7 @@ const mpr = {
|
|
|
5283
5630
|
},
|
|
5284
5631
|
viewports: [{
|
|
5285
5632
|
viewportOptions: {
|
|
5633
|
+
viewportId: 'mpr-axial',
|
|
5286
5634
|
toolGroupId: 'mpr',
|
|
5287
5635
|
viewportType: 'volume',
|
|
5288
5636
|
orientation: 'axial',
|
|
@@ -5301,6 +5649,7 @@ const mpr = {
|
|
|
5301
5649
|
}]
|
|
5302
5650
|
}, {
|
|
5303
5651
|
viewportOptions: {
|
|
5652
|
+
viewportId: 'mpr-sagittal',
|
|
5304
5653
|
toolGroupId: 'mpr',
|
|
5305
5654
|
viewportType: 'volume',
|
|
5306
5655
|
orientation: 'sagittal',
|
|
@@ -5319,6 +5668,7 @@ const mpr = {
|
|
|
5319
5668
|
}]
|
|
5320
5669
|
}, {
|
|
5321
5670
|
viewportOptions: {
|
|
5671
|
+
viewportId: 'mpr-coronal',
|
|
5322
5672
|
toolGroupId: 'mpr',
|
|
5323
5673
|
viewportType: 'volume',
|
|
5324
5674
|
orientation: 'coronal',
|
|
@@ -5341,7 +5691,6 @@ const mpr = {
|
|
|
5341
5691
|
const mprAnd3DVolumeViewport = {
|
|
5342
5692
|
id: 'mprAnd3DVolumeViewport',
|
|
5343
5693
|
locked: true,
|
|
5344
|
-
hasUpdatedPriorsInformation: false,
|
|
5345
5694
|
name: 'mpr',
|
|
5346
5695
|
createdDate: '2023-03-15T10:29:44.894Z',
|
|
5347
5696
|
modifiedDate: '2023-03-15T10:29:44.894Z',
|
|
@@ -5530,9 +5879,9 @@ class ToolGroupService {
|
|
|
5530
5879
|
return dist_esm.ToolGroupManager.getToolGroupForViewport(viewportId, renderingEngine.id);
|
|
5531
5880
|
}
|
|
5532
5881
|
getActiveToolForViewport(viewportId) {
|
|
5533
|
-
const toolGroup =
|
|
5882
|
+
const toolGroup = this.getToolGroupForViewport(viewportId);
|
|
5534
5883
|
if (!toolGroup) {
|
|
5535
|
-
return
|
|
5884
|
+
return;
|
|
5536
5885
|
}
|
|
5537
5886
|
return toolGroup.getActivePrimaryMouseButtonTool();
|
|
5538
5887
|
}
|
|
@@ -5595,9 +5944,8 @@ class ToolGroupService {
|
|
|
5595
5944
|
this._setToolsMode(toolGroup, tools);
|
|
5596
5945
|
}
|
|
5597
5946
|
createToolGroupAndAddTools(toolGroupId, tools) {
|
|
5598
|
-
let configs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
5599
5947
|
const toolGroup = this.createToolGroup(toolGroupId);
|
|
5600
|
-
this.addToolsToToolGroup(toolGroupId, tools
|
|
5948
|
+
this.addToolsToToolGroup(toolGroupId, tools);
|
|
5601
5949
|
return toolGroup;
|
|
5602
5950
|
}
|
|
5603
5951
|
|
|
@@ -5643,30 +5991,6 @@ class ToolGroupService {
|
|
|
5643
5991
|
const toolInstance = toolGroup.getToolInstance(toolName);
|
|
5644
5992
|
toolInstance.configuration = config;
|
|
5645
5993
|
}
|
|
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
5994
|
_setToolsMode(toolGroup, tools) {
|
|
5671
5995
|
const {
|
|
5672
5996
|
active,
|
|
@@ -5710,29 +6034,46 @@ class ToolGroupService {
|
|
|
5710
6034
|
});
|
|
5711
6035
|
}
|
|
5712
6036
|
}
|
|
5713
|
-
_addTools(toolGroup, tools
|
|
5714
|
-
const
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
6037
|
+
_addTools(toolGroup, tools) {
|
|
6038
|
+
const addTools = tools => {
|
|
6039
|
+
tools.forEach(_ref5 => {
|
|
6040
|
+
let {
|
|
6041
|
+
toolName,
|
|
6042
|
+
parentTool,
|
|
6043
|
+
configuration
|
|
6044
|
+
} = _ref5;
|
|
6045
|
+
if (parentTool) {
|
|
6046
|
+
toolGroup.addToolInstance(toolName, parentTool, {
|
|
6047
|
+
...configuration
|
|
6048
|
+
});
|
|
6049
|
+
} else {
|
|
6050
|
+
toolGroup.addTool(toolName, {
|
|
6051
|
+
...configuration
|
|
6052
|
+
});
|
|
6053
|
+
}
|
|
5725
6054
|
});
|
|
5726
|
-
}
|
|
6055
|
+
};
|
|
6056
|
+
if (tools.active) {
|
|
6057
|
+
addTools(tools.active);
|
|
6058
|
+
}
|
|
6059
|
+
if (tools.passive) {
|
|
6060
|
+
addTools(tools.passive);
|
|
6061
|
+
}
|
|
6062
|
+
if (tools.enabled) {
|
|
6063
|
+
addTools(tools.enabled);
|
|
6064
|
+
}
|
|
6065
|
+
if (tools.disabled) {
|
|
6066
|
+
addTools(tools.disabled);
|
|
6067
|
+
}
|
|
5727
6068
|
}
|
|
5728
6069
|
}
|
|
5729
6070
|
ToolGroupService.REGISTRATION = {
|
|
5730
6071
|
name: 'toolGroupService',
|
|
5731
6072
|
altName: 'ToolGroupService',
|
|
5732
|
-
create:
|
|
6073
|
+
create: _ref6 => {
|
|
5733
6074
|
let {
|
|
5734
6075
|
servicesManager
|
|
5735
|
-
} =
|
|
6076
|
+
} = _ref6;
|
|
5736
6077
|
return new ToolGroupService(servicesManager);
|
|
5737
6078
|
}
|
|
5738
6079
|
};
|
|
@@ -5789,7 +6130,7 @@ class SyncGroupService {
|
|
|
5789
6130
|
* @param type is the type of the synchronizer to create
|
|
5790
6131
|
* @param creator
|
|
5791
6132
|
*/
|
|
5792
|
-
|
|
6133
|
+
addSynchronizerType(type, creator) {
|
|
5793
6134
|
this.synchronizerCreators[type.toLowerCase()] = creator;
|
|
5794
6135
|
}
|
|
5795
6136
|
_getOrCreateSynchronizer(type, id, options) {
|
|
@@ -5867,10 +6208,10 @@ SyncGroupService.REGISTRATION = {
|
|
|
5867
6208
|
|
|
5868
6209
|
/* harmony default export */ const services_SyncGroupService = (SyncGroupService);
|
|
5869
6210
|
// EXTERNAL MODULE: ../../../node_modules/lodash.clonedeep/index.js
|
|
5870
|
-
var lodash_clonedeep = __webpack_require__(
|
|
6211
|
+
var lodash_clonedeep = __webpack_require__(11677);
|
|
5871
6212
|
var lodash_clonedeep_default = /*#__PURE__*/__webpack_require__.n(lodash_clonedeep);
|
|
5872
6213
|
// EXTERNAL MODULE: ../../../node_modules/lodash.isequal/index.js
|
|
5873
|
-
var lodash_isequal = __webpack_require__(
|
|
6214
|
+
var lodash_isequal = __webpack_require__(10311);
|
|
5874
6215
|
var lodash_isequal_default = /*#__PURE__*/__webpack_require__.n(lodash_isequal);
|
|
5875
6216
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/transitions.ts
|
|
5876
6217
|
/**
|
|
@@ -6026,6 +6367,82 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6026
6367
|
segmentation
|
|
6027
6368
|
});
|
|
6028
6369
|
};
|
|
6370
|
+
// Todo: this should not run on the main thread
|
|
6371
|
+
this.calculateCentroids = (segmentationId, segmentIndex) => {
|
|
6372
|
+
const segmentation = this.getSegmentation(segmentationId);
|
|
6373
|
+
const volume = this.getLabelmapVolume(segmentationId);
|
|
6374
|
+
const {
|
|
6375
|
+
dimensions,
|
|
6376
|
+
imageData
|
|
6377
|
+
} = volume;
|
|
6378
|
+
const scalarData = volume.getScalarData();
|
|
6379
|
+
const [dimX, dimY, numFrames] = dimensions;
|
|
6380
|
+
const frameLength = dimX * dimY;
|
|
6381
|
+
const segmentIndices = segmentIndex ? [segmentIndex] : segmentation.segments.filter(segment => segment?.segmentIndex).map(segment => segment.segmentIndex);
|
|
6382
|
+
const segmentIndicesSet = new Set(segmentIndices);
|
|
6383
|
+
const centroids = new Map();
|
|
6384
|
+
for (const index of segmentIndicesSet) {
|
|
6385
|
+
centroids.set(index, {
|
|
6386
|
+
x: 0,
|
|
6387
|
+
y: 0,
|
|
6388
|
+
z: 0,
|
|
6389
|
+
count: 0
|
|
6390
|
+
});
|
|
6391
|
+
}
|
|
6392
|
+
let voxelIndex = 0;
|
|
6393
|
+
for (let frame = 0; frame < numFrames; frame++) {
|
|
6394
|
+
for (let p = 0; p < frameLength; p++) {
|
|
6395
|
+
const segmentIndex = scalarData[voxelIndex++];
|
|
6396
|
+
if (segmentIndicesSet.has(segmentIndex)) {
|
|
6397
|
+
const centroid = centroids.get(segmentIndex);
|
|
6398
|
+
centroid.x += p % dimX;
|
|
6399
|
+
centroid.y += p / dimX | 0;
|
|
6400
|
+
centroid.z += frame;
|
|
6401
|
+
centroid.count++;
|
|
6402
|
+
}
|
|
6403
|
+
}
|
|
6404
|
+
}
|
|
6405
|
+
const result = new Map();
|
|
6406
|
+
for (const [index, centroid] of centroids) {
|
|
6407
|
+
const count = centroid.count;
|
|
6408
|
+
const normalizedCentroid = {
|
|
6409
|
+
x: centroid.x / count,
|
|
6410
|
+
y: centroid.y / count,
|
|
6411
|
+
z: centroid.z / count
|
|
6412
|
+
};
|
|
6413
|
+
normalizedCentroid.world = imageData.indexToWorld([normalizedCentroid.x, normalizedCentroid.y, normalizedCentroid.z]);
|
|
6414
|
+
result.set(index, normalizedCentroid);
|
|
6415
|
+
}
|
|
6416
|
+
this.setCentroids(segmentationId, result);
|
|
6417
|
+
return result;
|
|
6418
|
+
};
|
|
6419
|
+
this.setCentroids = (segmentationId, centroids) => {
|
|
6420
|
+
const segmentation = this.getSegmentation(segmentationId);
|
|
6421
|
+
const imageData = this.getLabelmapVolume(segmentationId).imageData; // Assuming this method returns imageData
|
|
6422
|
+
|
|
6423
|
+
if (!segmentation.cachedStats) {
|
|
6424
|
+
segmentation.cachedStats = {
|
|
6425
|
+
segmentCenter: {}
|
|
6426
|
+
};
|
|
6427
|
+
} else if (!segmentation.cachedStats.segmentCenter) {
|
|
6428
|
+
segmentation.cachedStats.segmentCenter = {};
|
|
6429
|
+
}
|
|
6430
|
+
for (const [segmentIndex, centroid] of centroids) {
|
|
6431
|
+
let world = centroid.world;
|
|
6432
|
+
|
|
6433
|
+
// If world coordinates are not provided, calculate them
|
|
6434
|
+
if (!world || world.length === 0) {
|
|
6435
|
+
world = imageData.indexToWorld(centroid.image);
|
|
6436
|
+
}
|
|
6437
|
+
segmentation.cachedStats.segmentCenter[segmentIndex] = {
|
|
6438
|
+
center: {
|
|
6439
|
+
image: centroid.image,
|
|
6440
|
+
world: world
|
|
6441
|
+
}
|
|
6442
|
+
};
|
|
6443
|
+
}
|
|
6444
|
+
this.addOrUpdateSegmentation(segmentation, true, true);
|
|
6445
|
+
};
|
|
6029
6446
|
this.createSegmentationForDisplaySet = async (displaySetInstanceUID, options) => {
|
|
6030
6447
|
const {
|
|
6031
6448
|
displaySetService
|
|
@@ -6043,7 +6460,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6043
6460
|
volumeId: segmentationId,
|
|
6044
6461
|
targetBuffer: {
|
|
6045
6462
|
type: 'Uint8Array',
|
|
6046
|
-
sharedArrayBuffer:
|
|
6463
|
+
sharedArrayBuffer: window.SharedArrayBuffer
|
|
6047
6464
|
}
|
|
6048
6465
|
});
|
|
6049
6466
|
const defaultScheme = this._getDefaultSegmentationScheme();
|
|
@@ -6055,6 +6472,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6055
6472
|
// We should set it as active by default, as it created for display
|
|
6056
6473
|
isActive: true,
|
|
6057
6474
|
type: representationType,
|
|
6475
|
+
FrameOfReferenceUID: options?.FrameOfReferenceUID || displaySet.instances?.[0]?.FrameOfReferenceUID,
|
|
6058
6476
|
representationData: {
|
|
6059
6477
|
LABELMAP: {
|
|
6060
6478
|
volumeId: segmentationId,
|
|
@@ -6078,6 +6496,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6078
6496
|
this.addSegmentationRepresentationToToolGroup = async function (toolGroupId, segmentationId) {
|
|
6079
6497
|
let hydrateSegmentation = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
6080
6498
|
let representationType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : dist_esm.Enums.SegmentationRepresentations.Labelmap;
|
|
6499
|
+
let suppressEvents = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
6081
6500
|
const segmentation = _this.getSegmentation(segmentationId);
|
|
6082
6501
|
if (!segmentation) {
|
|
6083
6502
|
throw new Error(`Segmentation with segmentationId ${segmentationId} not found.`);
|
|
@@ -6122,12 +6541,17 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6122
6541
|
if (visibility !== undefined) {
|
|
6123
6542
|
_this._setSegmentVisibility(segmentationId, segmentIndex, visibility, toolGroupId, suppressEvents);
|
|
6124
6543
|
}
|
|
6125
|
-
if (isLocked
|
|
6544
|
+
if (isLocked) {
|
|
6126
6545
|
_this._setSegmentLocked(segmentationId, segmentIndex, isLocked, suppressEvents);
|
|
6127
6546
|
}
|
|
6128
6547
|
}
|
|
6548
|
+
if (!suppressEvents) {
|
|
6549
|
+
_this._broadcastEvent(_this.EVENTS.SEGMENTATION_UPDATED, {
|
|
6550
|
+
segmentation
|
|
6551
|
+
});
|
|
6552
|
+
}
|
|
6129
6553
|
};
|
|
6130
|
-
this.
|
|
6554
|
+
this.setSegmentRGBAColor = (segmentationId, segmentIndex, rgbaColor, toolGroupId) => {
|
|
6131
6555
|
const segmentation = this.getSegmentation(segmentationId);
|
|
6132
6556
|
if (segmentation === undefined) {
|
|
6133
6557
|
throw new Error(`no segmentation for segmentationId: ${segmentationId}`);
|
|
@@ -6153,6 +6577,9 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6153
6577
|
throw new Error(`Segmentation with segmentationId ${segmentationId} not found.`);
|
|
6154
6578
|
}
|
|
6155
6579
|
segmentation.hydrated = true;
|
|
6580
|
+
|
|
6581
|
+
// Not all segmentations have dipslaysets, some of them are derived in the client
|
|
6582
|
+
_this._setDisplaySetIsHydrated(segmentationId, true);
|
|
6156
6583
|
if (!suppressEvents) {
|
|
6157
6584
|
_this._broadcastEvent(_this.EVENTS.SEGMENTATION_UPDATED, {
|
|
6158
6585
|
segmentation
|
|
@@ -6160,7 +6587,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6160
6587
|
}
|
|
6161
6588
|
};
|
|
6162
6589
|
this.getConfiguration = toolGroupId => {
|
|
6163
|
-
toolGroupId = toolGroupId ?? this.
|
|
6590
|
+
toolGroupId = toolGroupId ?? this._getApplicableToolGroupId();
|
|
6164
6591
|
const brushSize = 1;
|
|
6165
6592
|
// const brushSize = cstUtils.segmentation.getBrushSizeForToolGroup(
|
|
6166
6593
|
// toolGroupId
|
|
@@ -6287,7 +6714,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6287
6714
|
if (segmentInfo === undefined) {
|
|
6288
6715
|
throw new Error(`Segment ${segmentIndex} not yet added to segmentation: ${segmentationId}`);
|
|
6289
6716
|
}
|
|
6290
|
-
toolGroupId = toolGroupId ?? _this.
|
|
6717
|
+
toolGroupId = toolGroupId ?? _this._getApplicableToolGroupId();
|
|
6291
6718
|
const segmentationRepresentation = _this._getSegmentationRepresentation(segmentationId, toolGroupId);
|
|
6292
6719
|
if (!segmentationRepresentation) {
|
|
6293
6720
|
throw new Error('Must add representation to toolgroup before setting segments');
|
|
@@ -6314,7 +6741,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6314
6741
|
if (segmentInfo === undefined) {
|
|
6315
6742
|
throw new Error(`Segment ${segmentIndex} not yet added to segmentation: ${segmentationId}`);
|
|
6316
6743
|
}
|
|
6317
|
-
toolGroupId = toolGroupId ?? _this.
|
|
6744
|
+
toolGroupId = toolGroupId ?? _this._getApplicableToolGroupId();
|
|
6318
6745
|
const segmentationRepresentation = _this._getSegmentationRepresentation(segmentationId, toolGroupId);
|
|
6319
6746
|
if (!segmentationRepresentation) {
|
|
6320
6747
|
throw new Error('Must add representation to toolgroup before setting segments');
|
|
@@ -6436,12 +6863,18 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6436
6863
|
});
|
|
6437
6864
|
});
|
|
6438
6865
|
};
|
|
6439
|
-
this.
|
|
6866
|
+
this._getApplicableToolGroupId = () => {
|
|
6440
6867
|
const {
|
|
6441
|
-
toolGroupService
|
|
6868
|
+
toolGroupService,
|
|
6869
|
+
viewportGridService,
|
|
6870
|
+
cornerstoneViewportService
|
|
6442
6871
|
} = this.servicesManager.services;
|
|
6443
|
-
const
|
|
6444
|
-
|
|
6872
|
+
const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportGridService.getActiveViewportId());
|
|
6873
|
+
if (!viewportInfo) {
|
|
6874
|
+
const toolGroupIds = toolGroupService.getToolGroupIds();
|
|
6875
|
+
return toolGroupIds[0];
|
|
6876
|
+
}
|
|
6877
|
+
return viewportInfo.getToolGroupId();
|
|
6445
6878
|
};
|
|
6446
6879
|
this.getNextColorLUTIndex = () => {
|
|
6447
6880
|
let i = 0;
|
|
@@ -6467,34 +6900,40 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6467
6900
|
this._initSegmentationService();
|
|
6468
6901
|
}
|
|
6469
6902
|
/**
|
|
6470
|
-
*
|
|
6471
|
-
* the segment.
|
|
6472
|
-
* @param
|
|
6473
|
-
* segment to.
|
|
6474
|
-
*
|
|
6475
|
-
*
|
|
6476
|
-
*
|
|
6477
|
-
*
|
|
6478
|
-
*
|
|
6479
|
-
*
|
|
6480
|
-
*
|
|
6481
|
-
*
|
|
6903
|
+
* Adds a new segment to the specified segmentation.
|
|
6904
|
+
* @param segmentationId - The ID of the segmentation to add the segment to.
|
|
6905
|
+
* @param config - An object containing the configuration options for the new segment.
|
|
6906
|
+
* - segmentIndex: (optional) The index of the segment to add. If not provided, the next available index will be used.
|
|
6907
|
+
* - 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.
|
|
6908
|
+
* - properties: (optional) An object containing the properties of the new segment.
|
|
6909
|
+
* - label: (optional) The label of the new segment. If not provided, a default label will be used.
|
|
6910
|
+
* - color: (optional) The color of the new segment in RGB format. If not provided, a default color will be used.
|
|
6911
|
+
* - opacity: (optional) The opacity of the new segment. If not provided, a default opacity will be used.
|
|
6912
|
+
* - visibility: (optional) Whether the new segment should be visible. If not provided, the segment will be visible by default.
|
|
6913
|
+
* - isLocked: (optional) Whether the new segment should be locked for editing. If not provided, the segment will not be locked by default.
|
|
6914
|
+
* - 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
6915
|
*/
|
|
6483
|
-
addSegment(segmentationId
|
|
6484
|
-
|
|
6916
|
+
addSegment(segmentationId) {
|
|
6917
|
+
let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
6918
|
+
if (config?.segmentIndex === 0) {
|
|
6485
6919
|
throw new Error('Segment index 0 is reserved for "no label"');
|
|
6486
6920
|
}
|
|
6487
|
-
toolGroupId = toolGroupId ?? this.
|
|
6921
|
+
const toolGroupId = config.toolGroupId ?? this._getApplicableToolGroupId();
|
|
6488
6922
|
const {
|
|
6489
6923
|
segmentationRepresentationUID,
|
|
6490
6924
|
segmentation
|
|
6491
6925
|
} = this._getSegmentationInfo(segmentationId, toolGroupId);
|
|
6926
|
+
let segmentIndex = config.segmentIndex;
|
|
6927
|
+
if (!segmentIndex) {
|
|
6928
|
+
// grab the next available segment index
|
|
6929
|
+
segmentIndex = segmentation.segments.length === 0 ? 1 : segmentation.segments.length;
|
|
6930
|
+
}
|
|
6492
6931
|
if (this._getSegmentInfo(segmentation, segmentIndex)) {
|
|
6493
6932
|
throw new Error(`Segment ${segmentIndex} already exists`);
|
|
6494
6933
|
}
|
|
6495
6934
|
const rgbaColor = dist_esm.segmentation.config.color.getColorForSegmentIndex(toolGroupId, segmentationRepresentationUID, segmentIndex);
|
|
6496
6935
|
segmentation.segments[segmentIndex] = {
|
|
6497
|
-
label: properties
|
|
6936
|
+
label: config.properties?.label ?? `Segment ${segmentIndex}`,
|
|
6498
6937
|
segmentIndex: segmentIndex,
|
|
6499
6938
|
color: [rgbaColor[0], rgbaColor[1], rgbaColor[2]],
|
|
6500
6939
|
opacity: rgbaColor[3],
|
|
@@ -6502,15 +6941,18 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6502
6941
|
isLocked: false
|
|
6503
6942
|
};
|
|
6504
6943
|
segmentation.segmentCount++;
|
|
6944
|
+
|
|
6945
|
+
// make the newly added segment the active segment
|
|
6946
|
+
this._setActiveSegment(segmentationId, segmentIndex);
|
|
6505
6947
|
const suppressEvents = true;
|
|
6506
|
-
if (properties !== undefined) {
|
|
6948
|
+
if (config.properties !== undefined) {
|
|
6507
6949
|
const {
|
|
6508
6950
|
color: newColor,
|
|
6509
6951
|
opacity,
|
|
6510
6952
|
isLocked,
|
|
6511
6953
|
visibility,
|
|
6512
6954
|
active
|
|
6513
|
-
} = properties;
|
|
6955
|
+
} = config.properties;
|
|
6514
6956
|
if (newColor !== undefined) {
|
|
6515
6957
|
this._setSegmentColor(segmentationId, segmentIndex, newColor, toolGroupId, suppressEvents);
|
|
6516
6958
|
}
|
|
@@ -6520,7 +6962,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6520
6962
|
if (visibility !== undefined) {
|
|
6521
6963
|
this._setSegmentVisibility(segmentationId, segmentIndex, visibility, toolGroupId, suppressEvents);
|
|
6522
6964
|
}
|
|
6523
|
-
if (active
|
|
6965
|
+
if (active === true) {
|
|
6524
6966
|
this._setActiveSegment(segmentationId, segmentIndex, suppressEvents);
|
|
6525
6967
|
}
|
|
6526
6968
|
if (isLocked !== undefined) {
|
|
@@ -6590,12 +7032,21 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6590
7032
|
let suppressEvents = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
6591
7033
|
this._setSegmentVisibility(segmentationId, segmentIndex, isVisible, toolGroupId, suppressEvents);
|
|
6592
7034
|
}
|
|
6593
|
-
|
|
7035
|
+
setSegmentLocked(segmentationId, segmentIndex, isLocked) {
|
|
6594
7036
|
const suppressEvents = false;
|
|
6595
7037
|
this._setSegmentLocked(segmentationId, segmentIndex, isLocked, suppressEvents);
|
|
6596
7038
|
}
|
|
6597
|
-
|
|
6598
|
-
|
|
7039
|
+
|
|
7040
|
+
/**
|
|
7041
|
+
* Toggles the locked state of a segment in a segmentation.
|
|
7042
|
+
* @param segmentationId - The ID of the segmentation.
|
|
7043
|
+
* @param segmentIndex - The index of the segment to toggle.
|
|
7044
|
+
*/
|
|
7045
|
+
toggleSegmentLocked(segmentationId, segmentIndex) {
|
|
7046
|
+
const segmentation = this.getSegmentation(segmentationId);
|
|
7047
|
+
const segment = this._getSegmentInfo(segmentation, segmentIndex);
|
|
7048
|
+
const isLocked = !segment.isLocked;
|
|
7049
|
+
this._setSegmentLocked(segmentationId, segmentIndex, isLocked);
|
|
6599
7050
|
}
|
|
6600
7051
|
setSegmentColor(segmentationId, segmentIndex, color, toolGroupId) {
|
|
6601
7052
|
this._setSegmentColor(segmentationId, segmentIndex, color, toolGroupId);
|
|
@@ -6604,11 +7055,11 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6604
7055
|
this._setSegmentOpacity(segmentationId, segmentIndex, opacity, toolGroupId);
|
|
6605
7056
|
}
|
|
6606
7057
|
setActiveSegmentationForToolGroup(segmentationId, toolGroupId) {
|
|
6607
|
-
toolGroupId = toolGroupId ?? this.
|
|
7058
|
+
toolGroupId = toolGroupId ?? this._getApplicableToolGroupId();
|
|
6608
7059
|
const suppressEvents = false;
|
|
6609
7060
|
this._setActiveSegmentationForToolGroup(segmentationId, toolGroupId, suppressEvents);
|
|
6610
7061
|
}
|
|
6611
|
-
|
|
7062
|
+
setActiveSegment(segmentationId, segmentIndex) {
|
|
6612
7063
|
this._setActiveSegment(segmentationId, segmentIndex, false);
|
|
6613
7064
|
}
|
|
6614
7065
|
|
|
@@ -6634,6 +7085,21 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6634
7085
|
const segmentations = this.arrayOfObjects(this.segmentations);
|
|
6635
7086
|
return segmentations && segmentations.map(m => this.segmentations[Object.keys(m)[0]]);
|
|
6636
7087
|
}
|
|
7088
|
+
getActiveSegmentation() {
|
|
7089
|
+
const segmentations = this.getSegmentations();
|
|
7090
|
+
return segmentations.find(segmentation => segmentation.isActive);
|
|
7091
|
+
}
|
|
7092
|
+
getActiveSegment() {
|
|
7093
|
+
const activeSegmentation = this.getActiveSegmentation();
|
|
7094
|
+
const {
|
|
7095
|
+
activeSegmentIndex,
|
|
7096
|
+
segments
|
|
7097
|
+
} = activeSegmentation;
|
|
7098
|
+
if (activeSegmentIndex === null) {
|
|
7099
|
+
return;
|
|
7100
|
+
}
|
|
7101
|
+
return segments[activeSegmentIndex];
|
|
7102
|
+
}
|
|
6637
7103
|
|
|
6638
7104
|
/**
|
|
6639
7105
|
* Get specific segmentation by its id.
|
|
@@ -6677,11 +7143,14 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6677
7143
|
}
|
|
6678
7144
|
}]);
|
|
6679
7145
|
|
|
6680
|
-
//
|
|
6681
|
-
//
|
|
6682
|
-
const
|
|
6683
|
-
|
|
6684
|
-
|
|
7146
|
+
// if first segmentation, we can use the default colorLUT, otherwise
|
|
7147
|
+
// we need to generate a new one and use a new colorLUT
|
|
7148
|
+
const colorLUTIndex = 0;
|
|
7149
|
+
if (Object.keys(this.segmentations).length !== 0) {
|
|
7150
|
+
const newColorLUT = this.generateNewColorLUT();
|
|
7151
|
+
const colorLUTIndex = this.getNextColorLUTIndex();
|
|
7152
|
+
dist_esm.segmentation.config.color.addColorLUT(newColorLUT, colorLUTIndex);
|
|
7153
|
+
}
|
|
6685
7154
|
this.segmentations[segmentationId] = {
|
|
6686
7155
|
...segmentation,
|
|
6687
7156
|
label: segmentation.label || '',
|
|
@@ -6689,8 +7158,8 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6689
7158
|
activeSegmentIndex: segmentation.activeSegmentIndex ?? null,
|
|
6690
7159
|
segmentCount: segmentation.segmentCount ?? 0,
|
|
6691
7160
|
isActive: false,
|
|
6692
|
-
|
|
6693
|
-
|
|
7161
|
+
isVisible: true,
|
|
7162
|
+
colorLUTIndex
|
|
6694
7163
|
};
|
|
6695
7164
|
cachedSegmentation = this.segmentations[segmentationId];
|
|
6696
7165
|
this._updateCornerstoneSegmentations({
|
|
@@ -6715,6 +7184,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6715
7184
|
id: segmentationId,
|
|
6716
7185
|
displaySetInstanceUID: segDisplaySet.displaySetInstanceUID,
|
|
6717
7186
|
type: representationType,
|
|
7187
|
+
label: segDisplaySet.SeriesDescription,
|
|
6718
7188
|
representationData: {
|
|
6719
7189
|
[LABELMAP]: {
|
|
6720
7190
|
volumeId: segmentationId,
|
|
@@ -6731,11 +7201,11 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6731
7201
|
return this.addOrUpdateSegmentation(Object.assign(segmentation, cachedSegmentation), suppressEvents);
|
|
6732
7202
|
}
|
|
6733
7203
|
const {
|
|
6734
|
-
|
|
7204
|
+
labelmapBufferArray,
|
|
6735
7205
|
referencedVolumeId
|
|
6736
7206
|
} = segDisplaySet;
|
|
6737
|
-
if (!
|
|
6738
|
-
throw new Error('
|
|
7207
|
+
if (!labelmapBufferArray || !referencedVolumeId) {
|
|
7208
|
+
throw new Error('No labelmapBufferArray or referencedVolumeId found for the SEG displaySet');
|
|
6739
7209
|
}
|
|
6740
7210
|
|
|
6741
7211
|
// if the labelmap doesn't exist, we need to create it first from the
|
|
@@ -6751,75 +7221,30 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6751
7221
|
volumeId: segmentationId,
|
|
6752
7222
|
targetBuffer: {
|
|
6753
7223
|
type: 'Uint8Array',
|
|
6754
|
-
sharedArrayBuffer:
|
|
7224
|
+
sharedArrayBuffer: window.SharedArrayBuffer
|
|
6755
7225
|
}
|
|
6756
7226
|
});
|
|
6757
|
-
const [rows, columns] = derivedVolume.dimensions;
|
|
6758
7227
|
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) => {
|
|
7228
|
+
const segmentsInfo = segDisplaySet.segMetadata.data;
|
|
7229
|
+
derivedVolumeScalarData.set(new Uint8Array(labelmapBufferArray[0]));
|
|
7230
|
+
segmentation.segments = segmentsInfo.map((segmentInfo, segmentIndex) => {
|
|
7231
|
+
if (segmentIndex === 0) {
|
|
7232
|
+
return;
|
|
7233
|
+
}
|
|
6775
7234
|
const {
|
|
6776
|
-
|
|
7235
|
+
SegmentedPropertyCategoryCodeSequence,
|
|
7236
|
+
SegmentNumber,
|
|
7237
|
+
SegmentLabel,
|
|
7238
|
+
SegmentAlgorithmType,
|
|
7239
|
+
SegmentAlgorithmName,
|
|
7240
|
+
SegmentedPropertyTypeCodeSequence,
|
|
7241
|
+
rgba
|
|
6777
7242
|
} = 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);
|
|
7243
|
+
const {
|
|
7244
|
+
x,
|
|
7245
|
+
y,
|
|
7246
|
+
z
|
|
7247
|
+
} = segDisplaySet.centroids.get(segmentIndex);
|
|
6823
7248
|
const centerWorld = derivedVolume.imageData.indexToWorld([x, y, z]);
|
|
6824
7249
|
segmentation.cachedStats = {
|
|
6825
7250
|
...segmentation.cachedStats,
|
|
@@ -6834,51 +7259,24 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6834
7259
|
}
|
|
6835
7260
|
}
|
|
6836
7261
|
};
|
|
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],
|
|
7262
|
+
return {
|
|
7263
|
+
label: SegmentLabel || `Segment ${SegmentNumber}`,
|
|
7264
|
+
segmentIndex: Number(SegmentNumber),
|
|
7265
|
+
category: SegmentedPropertyCategoryCodeSequence ? SegmentedPropertyCategoryCodeSequence.CodeMeaning : '',
|
|
7266
|
+
type: SegmentedPropertyTypeCodeSequence ? SegmentedPropertyTypeCodeSequence.CodeMeaning : '',
|
|
7267
|
+
algorithmType: SegmentAlgorithmType,
|
|
7268
|
+
algorithmName: SegmentAlgorithmName,
|
|
7269
|
+
color: rgba,
|
|
7270
|
+
opacity: 255,
|
|
6873
7271
|
isVisible: true,
|
|
6874
7272
|
isLocked: false
|
|
6875
7273
|
};
|
|
6876
7274
|
});
|
|
7275
|
+
segmentation.segmentCount = segmentsInfo.length - 1;
|
|
6877
7276
|
segDisplaySet.isLoaded = true;
|
|
6878
7277
|
this._broadcastEvent(SegmentationService_EVENTS.SEGMENTATION_LOADING_COMPLETE, {
|
|
6879
7278
|
segmentationId,
|
|
6880
|
-
segDisplaySet
|
|
6881
|
-
overlappingSegments
|
|
7279
|
+
segDisplaySet
|
|
6882
7280
|
});
|
|
6883
7281
|
return this.addOrUpdateSegmentation(segmentation, suppressEvents);
|
|
6884
7282
|
}
|
|
@@ -6911,6 +7309,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
6911
7309
|
id: segmentationId,
|
|
6912
7310
|
displaySetInstanceUID: rtDisplaySetUID,
|
|
6913
7311
|
type: representationType,
|
|
7312
|
+
label: rtDisplaySet.SeriesDescription,
|
|
6914
7313
|
representationData: {
|
|
6915
7314
|
[CONTOUR]: {
|
|
6916
7315
|
geometryIds
|
|
@@ -7015,6 +7414,9 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
7015
7414
|
toolGroupService
|
|
7016
7415
|
} = this.servicesManager.services;
|
|
7017
7416
|
const center = this._getSegmentCenter(segmentationId, segmentIndex);
|
|
7417
|
+
if (!center?.world) {
|
|
7418
|
+
return;
|
|
7419
|
+
}
|
|
7018
7420
|
const {
|
|
7019
7421
|
world
|
|
7020
7422
|
} = center;
|
|
@@ -7056,7 +7458,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
7056
7458
|
clearInterval(this.highlightIntervalId);
|
|
7057
7459
|
}
|
|
7058
7460
|
const segmentation = this.getSegmentation(segmentationId);
|
|
7059
|
-
toolGroupId = toolGroupId ?? this.
|
|
7461
|
+
toolGroupId = toolGroupId ?? this._getApplicableToolGroupId();
|
|
7060
7462
|
const segmentationRepresentation = this._getSegmentationRepresentation(segmentationId, toolGroupId);
|
|
7061
7463
|
const {
|
|
7062
7464
|
type
|
|
@@ -7068,6 +7470,17 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
7068
7470
|
const adjustedAlpha = type === LABELMAP ? alpha : 1 - alpha;
|
|
7069
7471
|
highlightFn(segmentIndex, adjustedAlpha, hideOthers, segments, toolGroupId, animationLength, segmentationRepresentation);
|
|
7070
7472
|
}
|
|
7473
|
+
_setDisplaySetIsHydrated(displaySetUID, isHydrated) {
|
|
7474
|
+
const {
|
|
7475
|
+
displaySetService
|
|
7476
|
+
} = this.servicesManager.services;
|
|
7477
|
+
const displaySet = displaySetService.getDisplaySetByUID(displaySetUID);
|
|
7478
|
+
if (!displaySet) {
|
|
7479
|
+
return;
|
|
7480
|
+
}
|
|
7481
|
+
displaySet.isHydrated = isHydrated;
|
|
7482
|
+
displaySetService.setDisplaySetMetadataInvalidated(displaySetUID, false);
|
|
7483
|
+
}
|
|
7071
7484
|
_highlightLabelmap(segmentIndex, alpha, hideOthers, segments, toolGroupId, animationLength, segmentationRepresentation) {
|
|
7072
7485
|
const newSegmentSpecificConfig = {
|
|
7073
7486
|
[segmentIndex]: {
|
|
@@ -7170,21 +7583,23 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
7170
7583
|
|
|
7171
7584
|
if (wasActive) {
|
|
7172
7585
|
const remainingSegmentations = this._getSegmentations();
|
|
7173
|
-
|
|
7586
|
+
const remainingHydratedSegmentations = remainingSegmentations.filter(segmentation => segmentation.hydrated);
|
|
7587
|
+
if (remainingHydratedSegmentations.length) {
|
|
7174
7588
|
const {
|
|
7175
7589
|
id
|
|
7176
|
-
} =
|
|
7177
|
-
this._setActiveSegmentationForToolGroup(id, this.
|
|
7590
|
+
} = remainingHydratedSegmentations[0];
|
|
7591
|
+
this._setActiveSegmentationForToolGroup(id, this._getApplicableToolGroupId(), false);
|
|
7178
7592
|
}
|
|
7179
7593
|
}
|
|
7594
|
+
this._setDisplaySetIsHydrated(segmentationId, false);
|
|
7180
7595
|
this._broadcastEvent(this.EVENTS.SEGMENTATION_REMOVED, {
|
|
7181
7596
|
segmentationId
|
|
7182
7597
|
});
|
|
7183
7598
|
}
|
|
7184
|
-
|
|
7185
|
-
this.
|
|
7599
|
+
setSegmentLabel(segmentationId, segmentIndex, label) {
|
|
7600
|
+
this._setSegmentLabel(segmentationId, segmentIndex, label);
|
|
7186
7601
|
}
|
|
7187
|
-
|
|
7602
|
+
_setSegmentLabel(segmentationId, segmentIndex, label) {
|
|
7188
7603
|
let suppressEvents = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
7189
7604
|
const segmentation = this.getSegmentation(segmentationId);
|
|
7190
7605
|
if (segmentation === undefined) {
|
|
@@ -7202,16 +7617,14 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
7202
7617
|
});
|
|
7203
7618
|
}
|
|
7204
7619
|
}
|
|
7205
|
-
shouldRenderSegmentation(viewportDisplaySetInstanceUIDs,
|
|
7206
|
-
if (!viewportDisplaySetInstanceUIDs
|
|
7620
|
+
shouldRenderSegmentation(viewportDisplaySetInstanceUIDs, segmentationFrameOfReferenceUID) {
|
|
7621
|
+
if (!viewportDisplaySetInstanceUIDs?.length) {
|
|
7207
7622
|
return false;
|
|
7208
7623
|
}
|
|
7209
7624
|
const {
|
|
7210
7625
|
displaySetService
|
|
7211
7626
|
} = this.servicesManager.services;
|
|
7212
7627
|
let shouldDisplaySeg = false;
|
|
7213
|
-
const segDisplaySet = displaySetService.getDisplaySetByUID(segDisplaySetInstanceUID);
|
|
7214
|
-
const segFrameOfReferenceUID = this._getFrameOfReferenceUIDForSeg(segDisplaySet);
|
|
7215
7628
|
|
|
7216
7629
|
// check if the displaySet is sharing the same frameOfReferenceUID
|
|
7217
7630
|
// with the new segmentation
|
|
@@ -7220,7 +7633,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
7220
7633
|
|
|
7221
7634
|
// Todo: this might not be ideal for use cases such as 4D, since we
|
|
7222
7635
|
// don't want to show the segmentation for all the frames
|
|
7223
|
-
if (displaySet.isReconstructable && displaySet?.images?.[0]?.FrameOfReferenceUID ===
|
|
7636
|
+
if (displaySet.isReconstructable && displaySet?.images?.[0]?.FrameOfReferenceUID === segmentationFrameOfReferenceUID) {
|
|
7224
7637
|
shouldDisplaySeg = true;
|
|
7225
7638
|
break;
|
|
7226
7639
|
}
|
|
@@ -7330,7 +7743,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
7330
7743
|
}
|
|
7331
7744
|
_setSegmentVisibility(segmentationId, segmentIndex, isVisible, toolGroupId) {
|
|
7332
7745
|
let suppressEvents = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
7333
|
-
toolGroupId = toolGroupId ?? this.
|
|
7746
|
+
toolGroupId = toolGroupId ?? this._getApplicableToolGroupId();
|
|
7334
7747
|
const {
|
|
7335
7748
|
segmentationRepresentationUID,
|
|
7336
7749
|
segmentation
|
|
@@ -7374,7 +7787,7 @@ class SegmentationService extends src/* PubSubService */.hC {
|
|
|
7374
7787
|
}
|
|
7375
7788
|
_getSegmentationRepresentation(segmentationId, toolGroupId) {
|
|
7376
7789
|
const segmentationRepresentations = this.getSegmentationRepresentationsForToolGroup(toolGroupId);
|
|
7377
|
-
if (segmentationRepresentations
|
|
7790
|
+
if (!segmentationRepresentations?.length) {
|
|
7378
7791
|
return;
|
|
7379
7792
|
}
|
|
7380
7793
|
|
|
@@ -7659,7 +8072,8 @@ class CornerstoneCacheService {
|
|
|
7659
8072
|
}
|
|
7660
8073
|
_shouldRenderSegmentation(displaySets) {
|
|
7661
8074
|
const {
|
|
7662
|
-
segmentationService
|
|
8075
|
+
segmentationService,
|
|
8076
|
+
displaySetService
|
|
7663
8077
|
} = this.servicesManager.services;
|
|
7664
8078
|
const viewportDisplaySetInstanceUIDs = displaySets.map(_ref2 => {
|
|
7665
8079
|
let {
|
|
@@ -7673,7 +8087,9 @@ class CornerstoneCacheService {
|
|
|
7673
8087
|
const segmentations = segmentationService.getSegmentations();
|
|
7674
8088
|
for (const segmentation of segmentations) {
|
|
7675
8089
|
const segDisplaySetInstanceUID = segmentation.displaySetInstanceUID;
|
|
7676
|
-
const
|
|
8090
|
+
const segDisplaySet = displaySetService.getDisplaySetByUID(segDisplaySetInstanceUID);
|
|
8091
|
+
const instance = segDisplaySet.instances?.[0] || segDisplaySet.instance;
|
|
8092
|
+
const shouldDisplaySeg = segmentationService.shouldRenderSegmentation(viewportDisplaySetInstanceUIDs, instance.FrameOfReferenceUID);
|
|
7677
8093
|
if (shouldDisplaySeg) {
|
|
7678
8094
|
return true;
|
|
7679
8095
|
}
|
|
@@ -7747,16 +8163,17 @@ const DEFAULT_TOOLGROUP_ID = 'default';
|
|
|
7747
8163
|
// Return true if the data contains the given display set UID OR the imageId
|
|
7748
8164
|
// if it is a composite object.
|
|
7749
8165
|
const dataContains = (data, displaySetUID, imageId) => {
|
|
7750
|
-
if (data.displaySetInstanceUID === displaySetUID)
|
|
8166
|
+
if (data.displaySetInstanceUID === displaySetUID) {
|
|
8167
|
+
return true;
|
|
8168
|
+
}
|
|
7751
8169
|
if (imageId && data.isCompositeStack && data.imageIds) {
|
|
7752
8170
|
return !!data.imageIds.find(dataId => dataId === imageId);
|
|
7753
8171
|
}
|
|
7754
8172
|
return false;
|
|
7755
8173
|
};
|
|
7756
8174
|
class ViewportInfo {
|
|
7757
|
-
constructor(
|
|
8175
|
+
constructor(viewportId) {
|
|
7758
8176
|
this.viewportId = '';
|
|
7759
|
-
this.viewportIndex = void 0;
|
|
7760
8177
|
this.element = void 0;
|
|
7761
8178
|
this.viewportOptions = void 0;
|
|
7762
8179
|
this.displaySetOptions = void 0;
|
|
@@ -7768,7 +8185,6 @@ class ViewportInfo {
|
|
|
7768
8185
|
this.viewportOptions = null;
|
|
7769
8186
|
this.displaySetOptions = null;
|
|
7770
8187
|
};
|
|
7771
|
-
this.viewportIndex = viewportIndex;
|
|
7772
8188
|
this.viewportId = viewportId;
|
|
7773
8189
|
this.setPublicViewportOptions({});
|
|
7774
8190
|
this.setPublicDisplaySetOptions([{}]);
|
|
@@ -7779,7 +8195,9 @@ class ViewportInfo {
|
|
|
7779
8195
|
* OR if it is a composite stack and contains the given imageId
|
|
7780
8196
|
*/
|
|
7781
8197
|
contains(displaySetUID, imageId) {
|
|
7782
|
-
if (!this.viewportData?.data)
|
|
8198
|
+
if (!this.viewportData?.data) {
|
|
8199
|
+
return false;
|
|
8200
|
+
}
|
|
7783
8201
|
if (this.viewportData.data.length) {
|
|
7784
8202
|
return !!this.viewportData.data.find(data => dataContains(data, displaySetUID, imageId));
|
|
7785
8203
|
}
|
|
@@ -7794,9 +8212,6 @@ class ViewportInfo {
|
|
|
7794
8212
|
setViewportId(viewportId) {
|
|
7795
8213
|
this.viewportId = viewportId;
|
|
7796
8214
|
}
|
|
7797
|
-
setViewportIndex(viewportIndex) {
|
|
7798
|
-
this.viewportIndex = viewportIndex;
|
|
7799
|
-
}
|
|
7800
8215
|
setElement(element) {
|
|
7801
8216
|
this.element = element;
|
|
7802
8217
|
}
|
|
@@ -7806,9 +8221,6 @@ class ViewportInfo {
|
|
|
7806
8221
|
getViewportData() {
|
|
7807
8222
|
return this.viewportData;
|
|
7808
8223
|
}
|
|
7809
|
-
getViewportIndex() {
|
|
7810
|
-
return this.viewportIndex;
|
|
7811
|
-
}
|
|
7812
8224
|
getElement() {
|
|
7813
8225
|
return this.element;
|
|
7814
8226
|
}
|
|
@@ -7819,13 +8231,14 @@ class ViewportInfo {
|
|
|
7819
8231
|
// map the displaySetOptions and check if they are undefined then set them to default values
|
|
7820
8232
|
const displaySetOptions = this.mapDisplaySetOptions(publicDisplaySetOptions);
|
|
7821
8233
|
this.setDisplaySetOptions(displaySetOptions);
|
|
8234
|
+
return this.displaySetOptions;
|
|
7822
8235
|
}
|
|
7823
8236
|
hasDisplaySet(displaySetInstanceUID) {
|
|
7824
8237
|
// Todo: currently this does not work for non image & referenceImage displaySets.
|
|
7825
8238
|
// Since SEG and other derived displaySets are loaded in a different way, and not
|
|
7826
8239
|
// via cornerstoneViewportService
|
|
7827
8240
|
let viewportData = this.getViewportData();
|
|
7828
|
-
if (viewportData.viewportType === esm.Enums.ViewportType.ORTHOGRAPHIC) {
|
|
8241
|
+
if (viewportData.viewportType === esm.Enums.ViewportType.ORTHOGRAPHIC || viewportData.viewportType === esm.Enums.ViewportType.VOLUME_3D) {
|
|
7829
8242
|
viewportData = viewportData;
|
|
7830
8243
|
return viewportData.data.some(_ref => {
|
|
7831
8244
|
let {
|
|
@@ -7865,6 +8278,7 @@ class ViewportInfo {
|
|
|
7865
8278
|
toolGroupId,
|
|
7866
8279
|
presentationIds
|
|
7867
8280
|
});
|
|
8281
|
+
return this.viewportOptions;
|
|
7868
8282
|
}
|
|
7869
8283
|
setViewportOptions(viewportOptions) {
|
|
7870
8284
|
this.viewportOptions = viewportOptions;
|
|
@@ -7894,6 +8308,9 @@ class ViewportInfo {
|
|
|
7894
8308
|
getOrientation() {
|
|
7895
8309
|
return this.viewportOptions.orientation;
|
|
7896
8310
|
}
|
|
8311
|
+
getDisplayArea() {
|
|
8312
|
+
return this.viewportOptions.displayArea;
|
|
8313
|
+
}
|
|
7897
8314
|
getInitialImageOptions() {
|
|
7898
8315
|
return this.viewportOptions.initialImageOptions;
|
|
7899
8316
|
}
|
|
@@ -7959,7 +8376,6 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
7959
8376
|
constructor(servicesManager) {
|
|
7960
8377
|
super(CornerstoneViewportService_EVENTS);
|
|
7961
8378
|
this.renderingEngine = void 0;
|
|
7962
|
-
this.viewportsInfo = new Map();
|
|
7963
8379
|
this.viewportsById = new Map();
|
|
7964
8380
|
this.viewportGridResizeObserver = void 0;
|
|
7965
8381
|
this.viewportsDisplaySets = new Map();
|
|
@@ -7975,37 +8391,16 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
7975
8391
|
|
|
7976
8392
|
/**
|
|
7977
8393
|
* Adds the HTML element to the viewportService
|
|
7978
|
-
* @param {*}
|
|
8394
|
+
* @param {*} viewportId
|
|
7979
8395
|
* @param {*} elementRef
|
|
7980
8396
|
*/
|
|
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
|
-
}
|
|
8397
|
+
enableViewport(viewportId, elementRef) {
|
|
8398
|
+
const viewportInfo = new Viewport(viewportId);
|
|
7996
8399
|
viewportInfo.setElement(elementRef);
|
|
7997
|
-
this.viewportsInfo.set(viewportIndex, viewportInfo);
|
|
7998
8400
|
this.viewportsById.set(viewportId, viewportInfo);
|
|
7999
8401
|
}
|
|
8000
8402
|
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;
|
|
8403
|
+
return Array.from(this.viewportsById.keys());
|
|
8009
8404
|
}
|
|
8010
8405
|
|
|
8011
8406
|
/**
|
|
@@ -8059,34 +8454,38 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8059
8454
|
* created for every new viewport, this will be called whenever the set of
|
|
8060
8455
|
* viewports is changed, but NOT when the viewport position changes only.
|
|
8061
8456
|
*
|
|
8062
|
-
* @param
|
|
8457
|
+
* @param viewportId - The viewportId to disable
|
|
8063
8458
|
*/
|
|
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);
|
|
8459
|
+
disableElement(viewportId) {
|
|
8460
|
+
this.renderingEngine?.disableElement(viewportId);
|
|
8461
|
+
|
|
8462
|
+
// clean up
|
|
8073
8463
|
this.viewportsById.delete(viewportId);
|
|
8464
|
+
this.viewportsDisplaySets.delete(viewportId);
|
|
8074
8465
|
}
|
|
8075
8466
|
setPresentations(viewport, presentations) {
|
|
8076
8467
|
const properties = presentations?.lutPresentation?.properties;
|
|
8077
|
-
if (properties)
|
|
8468
|
+
if (properties) {
|
|
8469
|
+
viewport.setProperties(properties);
|
|
8470
|
+
}
|
|
8078
8471
|
const camera = presentations?.positionPresentation?.camera;
|
|
8079
|
-
if (camera)
|
|
8472
|
+
if (camera) {
|
|
8473
|
+
viewport.setCamera(camera);
|
|
8474
|
+
}
|
|
8080
8475
|
}
|
|
8081
|
-
getPresentation(
|
|
8082
|
-
const viewportInfo = this.
|
|
8083
|
-
if (!viewportInfo)
|
|
8476
|
+
getPresentation(viewportId) {
|
|
8477
|
+
const viewportInfo = this.viewportsById.get(viewportId);
|
|
8478
|
+
if (!viewportInfo) {
|
|
8479
|
+
return;
|
|
8480
|
+
}
|
|
8084
8481
|
const {
|
|
8085
8482
|
viewportType,
|
|
8086
8483
|
presentationIds
|
|
8087
8484
|
} = viewportInfo.getViewportOptions();
|
|
8088
|
-
const csViewport = this.
|
|
8089
|
-
if (!csViewport)
|
|
8485
|
+
const csViewport = this.getCornerstoneViewport(viewportId);
|
|
8486
|
+
if (!csViewport) {
|
|
8487
|
+
return;
|
|
8488
|
+
}
|
|
8090
8489
|
const properties = csViewport.getProperties();
|
|
8091
8490
|
if (properties.isComputedVOI) {
|
|
8092
8491
|
delete properties.voiRange;
|
|
@@ -8102,59 +8501,111 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8102
8501
|
camera
|
|
8103
8502
|
};
|
|
8104
8503
|
}
|
|
8504
|
+
storePresentation(_ref) {
|
|
8505
|
+
let {
|
|
8506
|
+
viewportId
|
|
8507
|
+
} = _ref;
|
|
8508
|
+
const stateSyncService = this.servicesManager.services.stateSyncService;
|
|
8509
|
+
let presentation;
|
|
8510
|
+
try {
|
|
8511
|
+
presentation = this.getPresentation(viewportId);
|
|
8512
|
+
} catch (error) {
|
|
8513
|
+
console.warn(error);
|
|
8514
|
+
}
|
|
8515
|
+
if (!presentation || !presentation.presentationIds) {
|
|
8516
|
+
return;
|
|
8517
|
+
}
|
|
8518
|
+
const {
|
|
8519
|
+
lutPresentationStore,
|
|
8520
|
+
positionPresentationStore
|
|
8521
|
+
} = stateSyncService.getState();
|
|
8522
|
+
const {
|
|
8523
|
+
presentationIds
|
|
8524
|
+
} = presentation;
|
|
8525
|
+
const {
|
|
8526
|
+
lutPresentationId,
|
|
8527
|
+
positionPresentationId
|
|
8528
|
+
} = presentationIds || {};
|
|
8529
|
+
const storeState = {};
|
|
8530
|
+
if (lutPresentationId) {
|
|
8531
|
+
storeState.lutPresentationStore = {
|
|
8532
|
+
...lutPresentationStore,
|
|
8533
|
+
[lutPresentationId]: presentation
|
|
8534
|
+
};
|
|
8535
|
+
}
|
|
8536
|
+
if (positionPresentationId) {
|
|
8537
|
+
storeState.positionPresentationStore = {
|
|
8538
|
+
...positionPresentationStore,
|
|
8539
|
+
[positionPresentationId]: presentation
|
|
8540
|
+
};
|
|
8541
|
+
}
|
|
8542
|
+
stateSyncService.store(storeState);
|
|
8543
|
+
}
|
|
8105
8544
|
|
|
8106
8545
|
/**
|
|
8107
|
-
*
|
|
8108
|
-
*
|
|
8109
|
-
* @param
|
|
8110
|
-
* @param
|
|
8111
|
-
* @param
|
|
8112
|
-
* @
|
|
8546
|
+
* Sets the viewport data for a viewport.
|
|
8547
|
+
* @param viewportId - The ID of the viewport to set the data for.
|
|
8548
|
+
* @param viewportData - The viewport data to set.
|
|
8549
|
+
* @param publicViewportOptions - The public viewport options.
|
|
8550
|
+
* @param publicDisplaySetOptions - The public display set options.
|
|
8551
|
+
* @param presentations - The presentations to set.
|
|
8113
8552
|
*/
|
|
8114
|
-
setViewportData(
|
|
8553
|
+
setViewportData(viewportId, viewportData, publicViewportOptions, publicDisplaySetOptions, presentations) {
|
|
8115
8554
|
const renderingEngine = this.getRenderingEngine();
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
}
|
|
8555
|
+
|
|
8556
|
+
// This is the old viewportInfo, which may have old options but we might be
|
|
8557
|
+
// using its viewport (same viewportId as the new viewportInfo)
|
|
8120
8558
|
const viewportInfo = this.viewportsById.get(viewportId);
|
|
8559
|
+
|
|
8560
|
+
// We should store the presentation for the current viewport since we can't only
|
|
8561
|
+
// rely to store it WHEN the viewport is disabled since we might keep around the
|
|
8562
|
+
// same viewport/element and just change the viewportData for it (drag and drop etc.)
|
|
8563
|
+
// the disableElement storePresentation handle would not be called in this case
|
|
8564
|
+
// and we would lose the presentation.
|
|
8565
|
+
this.storePresentation({
|
|
8566
|
+
viewportId: viewportInfo.getViewportId()
|
|
8567
|
+
});
|
|
8121
8568
|
if (!viewportInfo) {
|
|
8122
|
-
throw new Error('
|
|
8569
|
+
throw new Error('element is not enabled for the given viewportId');
|
|
8123
8570
|
}
|
|
8124
8571
|
|
|
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);
|
|
8572
|
+
// override the viewportOptions and displaySetOptions with the public ones
|
|
8573
|
+
// since those are the newly set ones, we set them here so that it handles defaults
|
|
8574
|
+
const displaySetOptions = viewportInfo.setPublicDisplaySetOptions(publicDisplaySetOptions);
|
|
8575
|
+
const viewportOptions = viewportInfo.setPublicViewportOptions(publicViewportOptions);
|
|
8139
8576
|
const element = viewportInfo.getElement();
|
|
8140
8577
|
const type = viewportInfo.getViewportType();
|
|
8141
8578
|
const background = viewportInfo.getBackground();
|
|
8142
8579
|
const orientation = viewportInfo.getOrientation();
|
|
8580
|
+
const displayArea = viewportInfo.getDisplayArea();
|
|
8143
8581
|
const viewportInput = {
|
|
8144
8582
|
viewportId,
|
|
8145
8583
|
element,
|
|
8146
8584
|
type,
|
|
8147
8585
|
defaultOptions: {
|
|
8148
8586
|
background,
|
|
8149
|
-
orientation
|
|
8587
|
+
orientation,
|
|
8588
|
+
displayArea
|
|
8150
8589
|
}
|
|
8151
8590
|
};
|
|
8152
8591
|
|
|
8592
|
+
// Rendering Engine Id set should happen before enabling the element
|
|
8593
|
+
// since there are callbacks that depend on the renderingEngine id
|
|
8594
|
+
// Todo: however, this is a limitation which means that we can't change
|
|
8595
|
+
// the rendering engine id for a given viewport which might be a super edge
|
|
8596
|
+
// case
|
|
8597
|
+
viewportInfo.setRenderingEngineId(renderingEngine.id);
|
|
8598
|
+
|
|
8153
8599
|
// Todo: this is not optimal at all, we are re-enabling the already enabled
|
|
8154
8600
|
// element which is not what we want. But enabledElement as part of the
|
|
8155
8601
|
// renderingEngine is designed to be used like this. This will trigger
|
|
8156
8602
|
// ENABLED_ELEMENT again and again, which will run onEnableElement callbacks
|
|
8157
8603
|
renderingEngine.enableElement(viewportInput);
|
|
8604
|
+
viewportInfo.setViewportOptions(viewportOptions);
|
|
8605
|
+
viewportInfo.setDisplaySetOptions(displaySetOptions);
|
|
8606
|
+
viewportInfo.setViewportData(viewportData);
|
|
8607
|
+
viewportInfo.setViewportId(viewportId);
|
|
8608
|
+
this.viewportsById.set(viewportId, viewportInfo);
|
|
8158
8609
|
const viewport = renderingEngine.getViewport(viewportId);
|
|
8159
8610
|
this._setDisplaySets(viewport, viewportData, viewportInfo, presentations);
|
|
8160
8611
|
|
|
@@ -8163,7 +8614,6 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8163
8614
|
// invalid data.
|
|
8164
8615
|
this._broadcastEvent(this.EVENTS.VIEWPORT_DATA_CHANGED, {
|
|
8165
8616
|
viewportData,
|
|
8166
|
-
viewportIndex,
|
|
8167
8617
|
viewportId
|
|
8168
8618
|
});
|
|
8169
8619
|
}
|
|
@@ -8175,31 +8625,8 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8175
8625
|
const viewport = this.renderingEngine.getViewport(viewportId);
|
|
8176
8626
|
return viewport;
|
|
8177
8627
|
}
|
|
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
8628
|
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;
|
|
8629
|
+
return this.viewportsById.get(viewportId);
|
|
8203
8630
|
}
|
|
8204
8631
|
_setStackViewport(viewport, viewportData, viewportInfo, presentations) {
|
|
8205
8632
|
const displaySetOptions = viewportInfo.getDisplaySetOptions();
|
|
@@ -8236,9 +8663,13 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8236
8663
|
}
|
|
8237
8664
|
}
|
|
8238
8665
|
viewport.setStack(imageIds, initialImageIndexToUse).then(() => {
|
|
8239
|
-
viewport.setProperties(
|
|
8666
|
+
viewport.setProperties({
|
|
8667
|
+
...properties
|
|
8668
|
+
});
|
|
8240
8669
|
const camera = presentations.positionPresentation?.camera;
|
|
8241
|
-
if (camera)
|
|
8670
|
+
if (camera) {
|
|
8671
|
+
viewport.setCamera(camera);
|
|
8672
|
+
}
|
|
8242
8673
|
});
|
|
8243
8674
|
}
|
|
8244
8675
|
_getInitialImageIndexForViewport(viewportInfo, imageIds) {
|
|
@@ -8333,7 +8764,7 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8333
8764
|
});
|
|
8334
8765
|
}
|
|
8335
8766
|
this.viewportsDisplaySets.set(viewport.id, displaySetInstanceUIDs);
|
|
8336
|
-
if (hangingProtocolService.
|
|
8767
|
+
if (hangingProtocolService.getShouldPerformCustomImageLoad()) {
|
|
8337
8768
|
// delegate the volume loading to the hanging protocol service if it has a custom image load strategy
|
|
8338
8769
|
return hangingProtocolService.runImageLoadStrategy({
|
|
8339
8770
|
viewportId: viewport.id,
|
|
@@ -8395,11 +8826,11 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8395
8826
|
};
|
|
8396
8827
|
});
|
|
8397
8828
|
await viewport.setVolumes(volumeInputArray);
|
|
8398
|
-
volumesProperties.forEach(
|
|
8829
|
+
volumesProperties.forEach(_ref2 => {
|
|
8399
8830
|
let {
|
|
8400
8831
|
properties,
|
|
8401
8832
|
volumeId
|
|
8402
|
-
} =
|
|
8833
|
+
} = _ref2;
|
|
8403
8834
|
viewport.setProperties(properties, volumeId);
|
|
8404
8835
|
});
|
|
8405
8836
|
this.setPresentations(viewport, presentations);
|
|
@@ -8448,13 +8879,25 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8448
8879
|
continue;
|
|
8449
8880
|
}
|
|
8450
8881
|
|
|
8451
|
-
// otherwise, check if the hydrated segmentations are in the same
|
|
8882
|
+
// otherwise, check if the hydrated segmentations are in the same FrameOfReferenceUID
|
|
8452
8883
|
// as the primary displaySet, if so add the representation (since it was not there)
|
|
8453
8884
|
const {
|
|
8454
|
-
id: segDisplaySetInstanceUID
|
|
8455
|
-
type
|
|
8885
|
+
id: segDisplaySetInstanceUID
|
|
8456
8886
|
} = segmentation;
|
|
8457
|
-
|
|
8887
|
+
let segFrameOfReferenceUID = this._getFrameOfReferenceUID(segDisplaySetInstanceUID);
|
|
8888
|
+
if (!segFrameOfReferenceUID) {
|
|
8889
|
+
// if the segmentation displaySet does not have a FrameOfReferenceUID, we might check the
|
|
8890
|
+
// segmentation itself maybe it has a FrameOfReferenceUID
|
|
8891
|
+
const {
|
|
8892
|
+
FrameOfReferenceUID
|
|
8893
|
+
} = segmentation;
|
|
8894
|
+
if (FrameOfReferenceUID) {
|
|
8895
|
+
segFrameOfReferenceUID = FrameOfReferenceUID;
|
|
8896
|
+
}
|
|
8897
|
+
}
|
|
8898
|
+
if (!segFrameOfReferenceUID) {
|
|
8899
|
+
return;
|
|
8900
|
+
}
|
|
8458
8901
|
let shouldDisplaySeg = false;
|
|
8459
8902
|
for (const displaySetInstanceUID of displaySetInstanceUIDs) {
|
|
8460
8903
|
const primaryFrameOfReferenceUID = this._getFrameOfReferenceUID(displaySetInstanceUID);
|
|
@@ -8487,13 +8930,12 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8487
8930
|
|
|
8488
8931
|
// Todo: keepCamera is an interim solution until we have a better solution for
|
|
8489
8932
|
// keeping the camera position when the viewport data is changed
|
|
8490
|
-
updateViewport(
|
|
8933
|
+
updateViewport(viewportId, viewportData) {
|
|
8491
8934
|
let keepCamera = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
8492
|
-
const viewportInfo = this.
|
|
8493
|
-
const viewportId = viewportInfo.getViewportId();
|
|
8935
|
+
const viewportInfo = this.getViewportInfo(viewportId);
|
|
8494
8936
|
const viewport = this.getCornerstoneViewport(viewportId);
|
|
8495
8937
|
const viewportCamera = viewport.getCamera();
|
|
8496
|
-
if (viewport instanceof esm.VolumeViewport) {
|
|
8938
|
+
if (viewport instanceof esm.VolumeViewport || viewport instanceof esm.VolumeViewport3D) {
|
|
8497
8939
|
this._setVolumeViewport(viewport, viewportData, viewportInfo).then(() => {
|
|
8498
8940
|
if (keepCamera) {
|
|
8499
8941
|
viewport.setCamera(viewportCamera);
|
|
@@ -8548,23 +8990,6 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8548
8990
|
return slabThickness;
|
|
8549
8991
|
}
|
|
8550
8992
|
}
|
|
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
8993
|
_getFrameOfReferenceUID(displaySetInstanceUID) {
|
|
8569
8994
|
const {
|
|
8570
8995
|
displaySetService
|
|
@@ -8602,28 +9027,28 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
|
|
|
8602
9027
|
*
|
|
8603
9028
|
* @param measurement
|
|
8604
9029
|
* The measurement that is desired to view.
|
|
8605
|
-
* @param
|
|
9030
|
+
* @param activeViewportId - the index that was active at the time the jump
|
|
8606
9031
|
* was initiated.
|
|
8607
|
-
* @return the
|
|
9032
|
+
* @return the viewportId that the measurement should be displayed in.
|
|
8608
9033
|
*/
|
|
8609
|
-
|
|
8610
|
-
const viewportInfo = this.
|
|
9034
|
+
getViewportIdToJump(activeViewportId, displaySetInstanceUID, cameraProps) {
|
|
9035
|
+
const viewportInfo = this.getViewportInfo(activeViewportId);
|
|
8611
9036
|
const {
|
|
8612
9037
|
referencedImageId
|
|
8613
9038
|
} = cameraProps;
|
|
8614
9039
|
if (viewportInfo?.contains(displaySetInstanceUID, referencedImageId)) {
|
|
8615
|
-
return
|
|
9040
|
+
return activeViewportId;
|
|
8616
9041
|
}
|
|
8617
|
-
return [...this.viewportsById.values()].find(viewportInfo => viewportInfo.contains(displaySetInstanceUID, referencedImageId))?.
|
|
9042
|
+
return [...this.viewportsById.values()].find(viewportInfo => viewportInfo.contains(displaySetInstanceUID, referencedImageId))?.viewportId ?? null;
|
|
8618
9043
|
}
|
|
8619
9044
|
}
|
|
8620
9045
|
CornerstoneViewportService.REGISTRATION = {
|
|
8621
9046
|
name: 'cornerstoneViewportService',
|
|
8622
9047
|
altName: 'CornerstoneViewportService',
|
|
8623
|
-
create:
|
|
9048
|
+
create: _ref3 => {
|
|
8624
9049
|
let {
|
|
8625
9050
|
servicesManager
|
|
8626
|
-
} =
|
|
9051
|
+
} = _ref3;
|
|
8627
9052
|
return new CornerstoneViewportService(servicesManager);
|
|
8628
9053
|
}
|
|
8629
9054
|
};
|
|
@@ -8632,7 +9057,7 @@ CornerstoneViewportService.REGISTRATION = {
|
|
|
8632
9057
|
|
|
8633
9058
|
|
|
8634
9059
|
// EXTERNAL MODULE: ../../../node_modules/dicomweb-client/build/dicomweb-client.es.js
|
|
8635
|
-
var dicomweb_client_es = __webpack_require__(
|
|
9060
|
+
var dicomweb_client_es = __webpack_require__(97604);
|
|
8636
9061
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/dicomLoaderService.js
|
|
8637
9062
|
|
|
8638
9063
|
|
|
@@ -8707,7 +9132,7 @@ class DicomLoaderService {
|
|
|
8707
9132
|
// Use referenced imageInstance
|
|
8708
9133
|
const imageInstance = getImageInstance(dataset);
|
|
8709
9134
|
const nonImageInstance = getNonImageInstance(dataset);
|
|
8710
|
-
if (!imageInstance && !nonImageInstance || !nonImageInstance.imageId
|
|
9135
|
+
if (!imageInstance && !nonImageInstance || !nonImageInstance.imageId?.startsWith('dicomfile')) {
|
|
8711
9136
|
return;
|
|
8712
9137
|
}
|
|
8713
9138
|
const instance = imageInstance || nonImageInstance;
|
|
@@ -8801,30 +9226,6 @@ const package_namespaceObject = JSON.parse('{"u2":"@ohif/extension-cornerstone"}
|
|
|
8801
9226
|
|
|
8802
9227
|
const id = package_namespaceObject.u2;
|
|
8803
9228
|
|
|
8804
|
-
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/utils/getHandlesFromPoints.js
|
|
8805
|
-
function getHandlesFromPoints(points) {
|
|
8806
|
-
if (points.longAxis && points.shortAxis) {
|
|
8807
|
-
const handles = {};
|
|
8808
|
-
handles.start = points.longAxis[0];
|
|
8809
|
-
handles.end = points.longAxis[1];
|
|
8810
|
-
handles.perpendicularStart = points.longAxis[0];
|
|
8811
|
-
handles.perpendicularEnd = points.longAxis[1];
|
|
8812
|
-
return handles;
|
|
8813
|
-
}
|
|
8814
|
-
return points.map((p, i) => i % 10 === 0 ? {
|
|
8815
|
-
start: p
|
|
8816
|
-
} : {
|
|
8817
|
-
end: p
|
|
8818
|
-
}).reduce((obj, item) => Object.assign(obj, {
|
|
8819
|
-
...item
|
|
8820
|
-
}), {});
|
|
8821
|
-
}
|
|
8822
|
-
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/utils/index.ts
|
|
8823
|
-
|
|
8824
|
-
|
|
8825
|
-
|
|
8826
|
-
|
|
8827
|
-
|
|
8828
9229
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/index.ts
|
|
8829
9230
|
|
|
8830
9231
|
|
|
@@ -8849,11 +9250,10 @@ function src_extends() { src_extends = Object.assign ? Object.assign.bind() : fu
|
|
|
8849
9250
|
|
|
8850
9251
|
|
|
8851
9252
|
|
|
8852
|
-
|
|
8853
9253
|
|
|
8854
9254
|
|
|
8855
9255
|
const Component = /*#__PURE__*/react.lazy(() => {
|
|
8856
|
-
return Promise.all(/* import() */[__webpack_require__.e(
|
|
9256
|
+
return Promise.all(/* import() */[__webpack_require__.e(23), __webpack_require__.e(181)]).then(__webpack_require__.bind(__webpack_require__, 86181));
|
|
8857
9257
|
});
|
|
8858
9258
|
const OHIFCornerstoneViewport = props => {
|
|
8859
9259
|
return /*#__PURE__*/react.createElement(react.Suspense, {
|
|
@@ -8876,7 +9276,6 @@ const cornerstoneExtension = {
|
|
|
8876
9276
|
esm.imageLoadPoolManager.clearRequestStack(type);
|
|
8877
9277
|
esm.imageRetrievalPoolManager.clearRequestStack(type);
|
|
8878
9278
|
});
|
|
8879
|
-
destroy();
|
|
8880
9279
|
(0,state/* reset */.mc)();
|
|
8881
9280
|
},
|
|
8882
9281
|
/**
|
|
@@ -8956,7 +9355,7 @@ const cornerstoneExtension = {
|
|
|
8956
9355
|
|
|
8957
9356
|
/***/ }),
|
|
8958
9357
|
|
|
8959
|
-
/***/
|
|
9358
|
+
/***/ 73704:
|
|
8960
9359
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
8961
9360
|
|
|
8962
9361
|
"use strict";
|
|
@@ -8976,21 +9375,21 @@ const state = {
|
|
|
8976
9375
|
* @param {HTMLElement} dom Active viewport element.
|
|
8977
9376
|
* @return void
|
|
8978
9377
|
*/
|
|
8979
|
-
const setEnabledElement = (
|
|
9378
|
+
const setEnabledElement = (viewportId, element, context) => {
|
|
8980
9379
|
const targetContext = context || state.DEFAULT_CONTEXT;
|
|
8981
|
-
state.enabledElements[
|
|
9380
|
+
state.enabledElements[viewportId] = {
|
|
8982
9381
|
element,
|
|
8983
9382
|
context: targetContext
|
|
8984
9383
|
};
|
|
8985
9384
|
};
|
|
8986
9385
|
|
|
8987
9386
|
/**
|
|
8988
|
-
* Grabs the enabled element `dom` reference of an
|
|
9387
|
+
* Grabs the enabled element `dom` reference of an active viewport.
|
|
8989
9388
|
*
|
|
8990
9389
|
* @return {HTMLElement} Active viewport element.
|
|
8991
9390
|
*/
|
|
8992
|
-
const getEnabledElement =
|
|
8993
|
-
return state.enabledElements[
|
|
9391
|
+
const getEnabledElement = viewportId => {
|
|
9392
|
+
return state.enabledElements[viewportId];
|
|
8994
9393
|
};
|
|
8995
9394
|
const reset = () => {
|
|
8996
9395
|
state.enabledElements = {};
|
|
@@ -8999,14 +9398,14 @@ const reset = () => {
|
|
|
8999
9398
|
|
|
9000
9399
|
/***/ }),
|
|
9001
9400
|
|
|
9002
|
-
/***/
|
|
9401
|
+
/***/ 87172:
|
|
9003
9402
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
9004
9403
|
|
|
9005
9404
|
"use strict";
|
|
9006
9405
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
9007
9406
|
/* harmony export */ Z: () => (/* binding */ getSOPInstanceAttributes)
|
|
9008
9407
|
/* harmony export */ });
|
|
9009
|
-
/* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(
|
|
9408
|
+
/* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3743);
|
|
9010
9409
|
|
|
9011
9410
|
|
|
9012
9411
|
/**
|